Integrais definidas aproximadas usando somas de Riemann


19

As somas de Riemann esquerda e direita são aproximações para integrais definidas . Obviamente, em matemática, precisamos ser muito precisos; portanto, pretendemos calculá-las com várias subdivisões que se aproximam do infinito, mas isso não é necessário para os propósitos deste desafio. Em vez disso, você deve tentar escrever o programa mais curto, obtendo entrada e fornecendo saída através de qualquer um dos métodos padrão , em qualquer linguagem de programação , que faz o seguinte:

Tarefa

Dados dois números racionais a e b (os limites da integral definido), um número inteiro positivo n , um booleano k representando esquerda / para a direita e uma função de caixa preta f , calcular a soma de Riemann esquerda ou para a direita (dependendo k ) de ∫abf(x)dx , usando n subdivisões iguais .

Especificações de E / S

  • a eb podem ser números / de ponto flutuante racional ou fracções.

  • k pode ser representado por dois valores distintos e consistentes, mas lembre-se de quevocê não tem permissãopara assumir funções completas ou parciais como entrada.

  • f é uma função de caixa preta. Citando a resposta da meta acima,o conteúdo (ou seja, o código) das funções da caixa preta pode não ser acessado, você pode chamá-las apenas (passar argumentos, se aplicável) e observar sua saída. Se necessário, inclua as informações necessárias sobre a sintaxe usada pelo seu idioma para que possamos testar seu envio.

Como saída, você deve fornecer uma fração / ponto flutuante / racional que representa a soma de Riemann solicitada. Como discutido no passado , a imprecisão de ponto flutuante pode ser ignorada, desde que sua saída seja precisa com pelo menos três casas decimais quando arredondada para o múltiplo mais próximo de 1/1000 (por exemplo, 1.4529999é bom em vez de 1.453).

Especificações matemáticas

  • f é a garantia de ser contínua entrea eb (sem saltos, sem furos, não há asymptotes verticais).

  • Há três casos possíveis com os quais você deve lidar: a=b (O resultado deve ser 0 ou equivalente), a<b ou a>b .

  • Se b<a , a integral altera seu sinal. Além disso, o sentido correto da integral, neste caso, é no sentido de a .

  • As áreas abaixo do gráfico são negativas e as acima do gráfico são positivas.

Exemplos / Casos de Teste

A resolução não é ótima, porque eu tive que reduzi-los um pouco, mas eles ainda são legíveis.

  • f(x)=2x+1,a=5,b=13,n=4 , k = direita:

    2x + 1

    O resultado deve ser 15⋅2+19⋅2+23⋅2+27⋅2=168 , porque a largura de cada retângulo é |b−a|n=2e as alturas correspondentes sãof(7)=15,f(9)=19,f(11)=23,f(13)=27 .

  • f(x)=x,a=1,b=2.5,n=3 , k = esquerda:

    Raiz quadrada

    A saída deve ser 1.8194792169 .

  • f(x)=−3x+4+x25,a=12.5,b=2.5,n=10 , k = direita:

    -3x + 4 + 1 / 5x ^ 2

    −(−4.05−5.45−6.45−7.05−7.25−7.05−6.45−5.45−4.05−2.25)=55.5b<a

  • f(x)=9−4x+2x27,a=0,b=15,n=3

    9-4x + 2 / 7x ^ 2

    13.5714285715

  • f(x)=6,a=1,b=4,n=218

  • f(x)=x7+165x+1,a=7,b=7,n=40

  • f(x)=x⋅sin⁡(x−1),a=0,b=1,n=500.385723952885505


3
Agradecimentos especiais: Esse desafio foi publicado na Sandbox , onde recebeu feedback valioso do usuário202729 , AdmBorkBork e Leaky Nun .
— Xcoder

Espero que as soluções aqui ajudar a pena de estudantes Calc I muitos anos ...
— Giuseppe

f(x) = x * sin(1 / x); a = 0; b = 1; n = 50; k = right — Output: 0.385723952885505. Note that sine uses radians here, but feel free to use degrees instead.Agora que f (x) é uma caixa preta, por que isso importa?
— L4m2

@ l4m2 Não importa muito, só queria que as pessoas soubessem que não deveriam se preocupar com essas coisas.
— Sr. Xcoder

@ Giuseppe Não. Os métodos dos programas aqui são ainda piores que os métodos das calculadoras portáteis. [apenas dizendo]
— user202729

Respostas:


8

R , 69 65 63 57 bytes

function(a,b,n,k,f,w=(b-a)/n)sum(sapply(a+w*(1:n-k),f))*w

Experimente online!

Aceita k=FALSEsomas à direita, embora o link TIO agora inclua aliases para "esquerda" e "direita" para facilitar o uso.

a+w*(1:n-k) gera pontos adequados à esquerda ou à direita.

Em seguida, sapplyaplica f- se a cada elemento do resultado, que sumaumentamos e multiplicamos pela largura do intervalo (b-a)/npara produzir o resultado. Este último também cuida de qualquer problema de sinal que possamos ter.


4

SNOBOL4 (CSNOBOL4) , 127 bytes

	DEFINE('R(a,b,n,k,p)')
R	l =(b - a) / n
	i =1
l	R =R + eval(p '(a + l * (i - k))')
	i =lt(i,n) i + 1	:s(l)
	R =R * l :(return)

Experimente online!

Supondo que a função pesteja definida em algum lugar, isso leva a,b,n,k,(name of p), com k=0para a direita e l=1para a esquerda.

O catspaw's SNOBOL4+suporta REALs, mas não possui funções trigonométricas embutidas. No entanto, suponho que alguém possa ter uma sinfunção razoável usando uma série de taylor.

Não tenho 100% de certeza de que essa é a maneira "correta" de passar uma função de caixa preta no SNOBOL (que, a meu conhecimento, não possui funções de primeira classe), mas me parece razoável.

Suponho que assumindo que a função seja definida como fmenor, pois a linha lpode ser

l	R =R + f(a + l * (i - k))

mas não é passado como argumento, que parece um pouco como "trapaça".

Observe que o link TIO possui uma instrução :(e)after DEFINE, que é para que o código realmente seja executado corretamente.


4

Julia 0,6 , 50 bytes

R(f,a,b,n,k)=(c=(b-a)/n;sum(f.(a+[k:n+k-1...]c))c)

Experimente online!

Um intervalo normalizado é construído, coletado em um vetor e depois escalado. A coleta do intervalo em um vetor usando [X...]é necessária para evitar a inexact errormultiplicação do intervalo diretamente por 0 quando a=b. Da mesma forma, construir um intervalo diretamente com :ou range()não é possível quando a=b.

O uso de k é muito semelhante à solução de Guiseppe , com k=1for righte k=0for left.


f.vetoriza fseus argumentos?
— Giuseppe

@ Giuseppe: Exatamente. f.é a aplicação elemento a elemento de f.
— LukeS

2

Haskell , 73 67 bytes

Obrigado a H.PWiz e Bruce Forte pelas dicas!

(f&a)b n k|d<-(b-a)/realToFrac n=d*sum(f<$>take n(drop k[a,a+d..]))

Experimente online!

Solução bastante simples.

ké 0para a esquerda e 1para a direita.


11
Se você está tomando n, você não precisa ir atéb
— H.PWiz



1

Geléia , 21 bytes

ƓḶ+Ɠ÷
IḢ×¢A+ṂɠvЀÆm×I

Experimente online!

Retire a,bdos argumentos e

n
right
f

de stdin.


Se você não conhece o Jelly, pode usar o Python para escrever a função de caixa preta f:

f (x) = 2x + 1 ; a = 5; b = 13; n = 4; k = direita

f (x) = √x ; a = 1; b = 2,5; n = 3; k = esquerda

f (x) = -3x + 4 + 1/5 * x 2 ; a = 12,5; b = 2,5; n = 10; k = direita

f (x) = 9 - 4x + 2/7 * x 2 ; a = 0; b = 15; n = 3; k = esquerda

f (x) = 6 ; a = 1; b = 4; n = 2; k = direita

f (x) = x * sen (1 / x) ; a = 0; b = 1; n = 50; k = direita


Explicação:


ƓḶ+Ɠ÷     Helper niladic link.
Ɠ         First line from stdin. (n). Assume n = 4.
 Ḷ        Lowered range (unlength). Get [0, 1, 2, 3].
  +Ɠ      Add second line from stdin (k). Assume k = 1 (right).
            Get [1, 2, 3, 4].
    ÷     Divide by (n). Get [0.25,0.5,0.75,1].

IḢ×¢A+ṂɠvЀÆm×I   Main monadic link. Take input `[a, b]`, assume `a=2,b=6`.
IḢ                `a-b`. Get `-4`.
  ×¢              Multiply by value of niladic link above. Get `[-1,-2,-3,-4]`.
    A             Absolute value. Get `[1,2,3,4]`.
     +Ṃ           Add min(a, b) = 2. Get `[3,4,5,6]`.
        vЀ       For each number, evaluate with...
       ɠ            input line from stdin.
           Æm     Arithmetic mean.
             ×I   Multiply by `a-b`.


1

Perl 6 , 65 bytes

{my \d=($^b-$^a)/$^n;sum ($a,*+d...*)[($^k+^0>d)+ ^$n]».&^f X*d}

Experimente online!

Relativamente simples. A única complicação está a tratar do a > bcaso, o que eu faço por xor-ing a bandeira de entrada $^kcom 0 > d, o que inverte quando a > b.


0

APL (Dyalog Classic) , 37 bytes

{(a b n k)←⍵⋄l←n÷⍨b-a⋄l×+/⍺⍺a+l×k+⍳n}

Experimente online!

APL NARS, 37 caracteres

A função tem o argumento à esquerda da função, no argumento numérico à direita abn k. Na questão k = deixada aqui, significa k = ¯1; k = aqui significa k = 0. Teste:

  f←{(a b n k)←⍵⋄l←n÷⍨b-a⋄l×+/⍺⍺a+l×k+⍳n}
  {1+2×⍵} f 5 13 4 0
168
  {√⍵} f 1 2.5 3 ¯1
1.819479217
  {4+(¯3×⍵)+0.2×⍵×⍵} f 12.5 2.5 10 0
55.5
  {9+(¯4×⍵)+7÷⍨2×⍵×⍵} f 0 15 3 ¯1
13.57142857
  {6-0×⍵} f 1 4 2 0
18
  {1+(165×⍵)+⍵*7} f 7 7 4 ¯1
0
  {⍵×1○÷⍵} f 0 1 50 0
0.3857239529

Os envios são contados em bytes, não em caracteres. Não me lembro se o NARS tem uma página de código personalizada (portanto, seria também 37 bytes) ou usa UTF16.
— Uriel

@ Uriel São 37 bytes no Dyalog APL classic, siga o link; possivelmente 35x2 bytes para o Nars Apl ...
— RosLuP

Então, por que você escreve como NARS? O NARS ainda tem dfnss? Pela maneira que você pode deixar cair os primeiros pais por 35 bytes
— Uriel

APL NARS, 37 caracteres significa que ele deve ser executado em NARS APL também
— RosLuP
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.