Przybliżone całki określone przy użyciu sum Riemanna

19

Sumy Riemanna po lewej i prawej stronie są przybliżeniami do całek oznaczonych . Oczywiście w matematyce musimy być bardzo dokładni, więc staramy się je obliczać za pomocą szeregu podziałów zbliżających się do nieskończoności, ale nie jest to potrzebne do celów tego wyzwania. Zamiast tego powinieneś spróbować napisać najkrótszy program, przyjmując dane wejściowe i dostarczając dane wyjściowe za pomocą dowolnej domyślnej metody , w dowolnym języku programowania , który wykonuje następujące czynności:

Zadanie

Biorąc pod uwagę dwie liczby wymierne i (granice całkowitej całki), dodatnią liczbę całkowitą , wartość logiczną reprezentującą funkcję lewo / prawo i czarną skrzynkę , oblicz lewą lub prawą sumę Riemanna (w zależności od ) z , używając równych poddziałów.abnk fkabf(x)dxn

Specyfikacja I / O

  • ai mogą być liczbami racjonalne / zmiennoprzecinkowe lub frakcje. b

  • k może być reprezentowane przez dowolne dwie odrębne i spójne wartości, ale należy pamiętać, że nie wolno przyjmować pełnych lub częściowych funkcji jako danych wejściowych.

  • f jest funkcją czarnej skrzynki. Powołując się na powyższą meta odpowiedź, zawartość (tj. Kod) funkcji czarnej skrzynki może nie być dostępna, możesz tylko wywoływać je (przekazując argumenty, jeśli dotyczy) i obserwować ich wyniki . W razie potrzeby podaj niezbędne informacje o składni używanej przez Twój język, abyśmy mogli przetestować Twoje zgłoszenie.

Jako wynik musisz podać ułamek wymierny / zmiennoprzecinkowy / reprezentujący sumę Riemanna, o którą jesteś proszony. Jak omówiono w przeszłości , niedokładność zmiennoprzecinkowa może być ignorowana, o ile wynik jest dokładny do co najmniej trzech miejsc po przecinku, gdy jest zaokrąglany do najbliższej wielokrotności 1/1000 (np. 1.4529999Jest w porządku zamiast 1.453).

Dane matematyczne

  • f jest zagwarantowana w sposób ciągły pomiędzy i (bez skoków, otwory, nie ma pionowych asymptoty).ab

  • Istnieją trzy możliwe przypadki, z którymi musisz sobie poradzić: (Wynik powinien wynosić lub jej odpowiedniki), lub .a=b0a<ba>b

  • Jeślib<a , całka zmienia swój znak. Również prawo poczucie całki jest w tym przypadku w kierunku.a

  • Obszary pod wykresem są ujemne, a te nad wykresem są dodatnie.

Przykłady / przypadki testowe

Rozdzielczość nie jest optymalna, ponieważ musiałem je nieco zmniejszyć, ale nadal są czytelne.

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

    2x + 1

    Wynik powinien wynosić 152+192+232+272=168 , ponieważ szerokość każdego prostokąta wynosi a odpowiednie wysokości to .|ba|n=2f(7)=15,f(9)=19,f(11)=23,f(13)=27

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

    Pierwiastek kwadratowy

    Dane wyjściowe powinny wynosić .1.8194792169

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

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

    Oczekiwana wartość wyjściowa wynosi , ponieważ całka zmienia znaki podczas przesuwania granic ( b < a ) .(4.055.456.457.057.257.056.455.454.052.25)=55.5b<a

  • f(x)=94x+2x27,a=0,b=15,n=3 , k = w lewo:

    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)=xsin(x1),a=0,b=1,n=500.385723952885505

Pan Xcoder
źródło
3
Specjalne podziękowania: To wyzwanie zostało opublikowane w piaskownicy , gdzie otrzymano cenne opinie od user202729 , AdmBorkBork i Leaky Nun .
Pan Xcoder,
Mam nadzieję, że zastosowane tutaj rozwiązania pomogą wielu studentom programu Calc I na wiele lat ...
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.Teraz, gdy f (x) jest czarną skrzynką, dlaczego to ma znaczenie?
l4m2
@ l4m2 Nie ma to większego znaczenia, chciałem tylko poinformować ludzi, że nie powinni się martwić o takie rzeczy.
Pan Xcoder,
@Giuseppe Nie. Metody programów tutaj są jeszcze gorsze niż metody kalkulatorów ręcznych. [tylko mówię]
user202729,

Odpowiedzi:

8

R , 69 65 63 57 bajtów

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

Wypróbuj online!

Pobiera k=FALSEsumy po prawej stronie, chociaż łącze TIO zawiera teraz aliasy dla „lewej” i „prawej” dla łatwości użycia.

a+w*(1:n-k) generuje odpowiednie lewe lub prawe punkty.

Następnie sapplystosuje się fdo każdego elementu wyniku, który następnie sumzwiększamy i mnożymy przez szerokość interwału, (b-a)/naby uzyskać wynik. Ta ostatnia również starannie rozwiązuje wszelkie problemy ze znakiem, jakie możemy mieć.

Giuseppe
źródło
4

SNOBOL4 (CSNOBOL4) , 127 bajtów

	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)

Wypróbuj online!

Zakładając, że funkcja pjest gdzieś zdefiniowana, bierze to a,b,n,k,(name of p), z k=0prawej i l=1lewej.

catspaw SNOBOL4+obsługuje REALs, ale nie ma wbudowanych funkcji trig. Jednak przypuszczam, że można wymyślić rozsądną sinfunkcję za pomocą serii Taylor.

Nie jestem w 100% pewien, że jest to „właściwy” sposób przekazania funkcji czarnej skrzynki w SNOBOL (która, o ile mi wiadomo, nie ma funkcji pierwszej klasy), ale wydaje mi się to rozsądne.

Przypuszczam, że zakładając, że funkcja jest zdefiniowana jako fkrótsza, jak lmogłaby być linia

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

ale nie jest to traktowane jako argument, który przypomina trochę „oszukiwanie”.

Zauważ, że link TIO zawiera instrukcję :(e)after DEFINE, która zapewnia prawidłowe działanie kodu.

Giuseppe
źródło
4

Julia 0.6 , 50 bajtów

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

Wypróbuj online!

Znormalizowany zakres jest konstruowany, gromadzony w wektorze, a następnie skalowany. Zebranie zakresu do wektora za pomocą [X...]jest konieczne, aby uniknąć inexact errorpomnożenia zakresu bezpośrednio przez 0 kiedy a=b. Podobnie, konstruowanie zakresu bezpośrednio za pomocą :lub range()nie jest możliwe, kiedy a=b.

Użycie k jest bardzo podobne do rozwiązania Guiseppe , k=1dla for righti k=0for left.

Łukasza
źródło
f.wektoryzuje fswoje argumenty?
Giuseppe,
@Giuseppe: Dokładnie. f.jest elementarną aplikacją f.
Łukasza
2

Haskell , 73 67 bajtów

Dzięki H.PWiz i Bruce Forte za wskazówki!

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

Wypróbuj online!

Całkiem proste rozwiązanie.

kjest 0na lewo i 1na prawo.

Cristian Lupascu
źródło
1
Jeśli bierzesz n, nie musisz iść dob
H.PWiz
2

Python 2 , 99 94 bajtów

Trochę naiwne rozwiązanie.

def R(f,a,b,n,k):s=cmp(b,a);d=s*(b-a)/n;return s*sum(d*f([0,a,b][s]+i*d)for i in range(k,n+k))

Wypróbuj online!

mbomb007
źródło
94 bajty w Pythonie 2
Mr. Xcoder,
Z jakiegoś powodu myślałem, że musimy poradzić sobie z wprowadzaniem liczb całkowitych. Dzięki.
mbomb007
1

Galaretka , 21 bajtów

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

Wypróbuj online!

Weź a,bz argumentów i

n
right
f

od standardowego.


Jeśli nie znasz Jelly, możesz użyć Pythona do napisania funkcji czarnej skrzynki f:

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

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

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

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

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

f (x) = x * sin (1 / x) ; a = 0; b = 1; n = 50; k = racja


Wyjaśnienie:


ƓḶ+Ɠ÷     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`.

użytkownik202729
źródło
1

Perl 6 , 65 bajtów

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

Wypróbuj online!

Stosunkowo proste. Jedyną komplikacją jest obsługa a > bsprawy, co robię, ustawiając flagę wejściową za $^kpomocą 0 > d, która odwraca ją, kiedy a > b.

Sean
źródło
0

APL (Dyalog Classic) , 37 bajtów

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

Wypróbuj online!

APL NARS, 37 znaków

Funkcja ma argument po lewej stronie funkcji, w prawym argumencie liczbowym abn k. W pozostawionym tutaj pytaniu k = oznacza to k = ¯1; k = tutaj oznacza to k = 0. Test:

  f←{(a b n k)←⍵⋄ln÷⍨b-al×+/⍺⍺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
RosLuP
źródło
Zgłoszenia są liczone w bajtach, a nie w znakach. Nie pamiętam, czy NARS ma niestandardową stronę kodową (więc byłoby to również 37 bajtów) czy używa UTF16.
Uriel
@Uriel Jest 37 bajtów w klasycznej aplikacji APL Dyalog po linku; prawdopodobnie 35x2 bajtów dla Nars Apl ...
RosLuP,
Dlaczego więc piszesz to jako NARS? Czy NARS ma nawet dfnss? Nawiasem mówiąc, możesz upuścić pierwszych rodziców za 35 bajtów
Uriel
APL NARS, 37 znaków oznacza, że ​​powinien również działać w NARS APL
RosLuP