Przybliżone ∫ ((e ^ x) / (x ^ x)) dx


24

Przybliżasz wartość:

wprowadź opis zdjęcia tutaj

Gdzie jest twój wkład I.

Zasady

  • Nie możesz używać żadnych wbudowanych funkcji integralnych.
  • Nie możesz używać żadnych wbudowanych funkcji nieskończonego sumowania.
  • Twój kod musi zostać wykonany w rozsądnym czasie (<20 sekund na moim komputerze)
  • Możesz założyć, że dane wejściowe są większe niż 0, ale niższe niż górna granica twojego języka.
  • Może to być dowolna forma standardowego zwrotu / wyjścia.

Możesz zweryfikować swoje wyniki w Wolfram | Alfa (możesz to sprawdzić, łącząc zamierzone dane wejściowe z połączonym zapytaniem).

Przykłady

(nazwijmy funkcję f)

f(1) -> 2.18273
f(50) -> 6.39981
f(10000) -> 6.39981
f(2.71828) -> 5.58040
f(3.14159) -> 5.92228

Twoja odpowiedź powinna być dokładna ±.0001.


@ThomasKwa Maximum dla twojego języka. Dodam to do pytania.
Addison Crump

Wolfram Alpha mówi, że ostatnia runda do5.92228
Neil

@Neil oo W porządku, więc musiał się pomylić. Dzięki!
Addison Crump

7
Przyznam 200 powtórzeń za najkrótszą prawidłową odpowiedź w TI-BASIC, która działa w <20 sekund na WabbitEmu ze 100% prędkością.
lirtosiast

@lirtosiast Jeśli nadal zamierzasz śledzić tę nagrodę, powinieneś zamieścić ją tutaj .
Addison Crump

Odpowiedzi:


10

Julia, 79 77 38 bajtów

I->sum(x->(e/x)^x,0:1e-5:min(I,9))/1e5

Jest to anonimowa funkcja, która przyjmuje wartość liczbową i zwraca liczbę zmiennoprzecinkową. Aby go wywołać, przypisz go do zmiennej.

Podejście polega na zastosowaniu właściwej sumy Riemanna do przybliżenia całki, która jest podana za pomocą następującego wzoru:

lateks

W naszym przypadku a = 0 ib = I , dane wejściowe. Podzielić ten obszar integracji n = 10 5 oddzielnych części, tak hemibursztynianu x = 1 / n = 10 -5 . Ponieważ jest to stała w stosunku do sumy, możemy wyciągnąć ją poza sumę i po prostu zsumować oceny funkcji w każdym punkcie i podzielić przez n .

Ta funkcja jest zaskakująco dobrze zachowana (fabuła z Mathematica):

mathematicaplot

Ponieważ funkcja ocenia prawie do 0 dla danych wejściowych większych niż około 9, obcinamy dane wejściowe jako I, jeśli mam mniej niż 9, lub w przeciwnym razie 9. Upraszcza to obliczenia, które musimy znacznie wykonać.

Nieskluczony kod:

function g(I)
    # Define the range over which to sum. We truncate the input
    # at 9 and subdivide the region into 1e5 pieces.
    range = 0:1e-5:min(I,9)

    # Evaluate the function at each of the 1e5 points, sum the
    # results, and divide by the number of points.
    return sum(x -> (e / x)^x, range) / 1e5
end

Zaoszczędzono 39 bajtów dzięki Dennisowi!


Czy nie jest to również równoważne z: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Algorytm wydaje się nieco prostszy w użyciu.
Addison Crump,

10^4można zapisać jako 1e4.
Rainer P.

@VoteToClose Skończyło się na innym podejściu
Alex A.

@RainerP. Heh, racja. Dzięki.
Alex A.

Wartość asymptotyczna całki wynosi 6,39981 $ ... $. Wartość 6,39981 $ ... - 10 ^ {- 4} $ jest najpierw osiągana przy I $ = 7,91399 ... $, więc możesz obciąć 8 $ zamiast 9 $, aby zaoszczędzić trochę czasu.
Eric Towers

9

Galaretka, 20 19 17 bajtów

ð«9×R÷øȷ5µØe÷*×ḢS

To pożycza sprytne obcięcie przy 9 lewach z odpowiedzi @ AlexA. i używa właściwej sumy Riemanna do oszacowania odpowiedniej całki.

Skrócone przypadki testowe zajmują trochę czasu, ale są wystarczająco szybkie na Wypróbuj online!

Jak to działa

ð«9×R÷øȷ5µØe÷*×ḢS  Main link. Input: I

      øȷ5          Niladic chain. Yields 1e5 = 100,000.

ð                  Dyadic chain. Left argument: I. Right argument: 1e5.
 «9                Compute min(I, 9).
   ×               Multiply the minimum with 1e5.
    R              Range; yield [1, 2, ..., min(I, 9) * 1e5] or [0] if I < 1e-5.
     ÷             Divide the range's items by 1e5.
                   This yields r := [1e-5, 2e-5, ... min(I, 9)] or [0] if I < 1e-5.

         µ         Monadic chain. Argument: r
          Øe÷      Divide e by each element of r.
             *     Elevate the resulting quotients to the corresponding elements,
                   mapping t -> (e/t) ** t over r.
                   For the special case of r = [0], this yields [1], since
                   (e/0) ** 0 = inf ** 0 = 1 in Jelly.
              ×Ḣ   Multiply each power by the first element of r, i.e., 1e-5 or 0.
                S  Add the resulting products.

Och w porządku. Reguła lewej ręki jest określana w klasach AP Calculus. : P Coolio.
Addison Crump

Nie znam tej nazwy, ale reguła po lewej stronie prawdopodobnie używa lewych punktów końcowych. Mój kod używa właściwych.
Dennis

2
(~ -.-) ~ To jakaś forma przekazanej reguły. xD
Addison Crump

4

ES7, 78 bajtów

i=>[...Array(n=2e3)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i>9?i=9:0,i/=n,j=-i/2)*i

Wykorzystuje to regułę prostokąta z 2000 prostokątami, które (przynajmniej w przykładach) wydają się dawać wystarczająco dokładną odpowiedź, ale dokładność można łatwo zwiększyć w razie potrzeby. Musi zastosować lewę 9, w przeciwnym razie dokładność spada w przypadku dużych wartości.

73-bajtowa wersja wykorzystująca prostokąty o szerokości ~ 0,001, więc nie działa powyżej ~ 700, ponieważ Math.exp uderza w Infinity:

i=>[...Array(n=i*1e3|0)].reduce(r=>r+Math.exp(j+=i)/j**j,0,i/=n,j=-i/2)*i

2

golflua , 83 znaki

Przyznaję: zajęło mi trochę czasu, aby zrozumieć min(I,9)sztuczkę, którą Alex przedstawił, pozwalając na obliczanie dowolnie wysokich liczb, ponieważ do tego czasu całka była zbieżna.

\f(x)~M.e(x)/x^x$b=M.mn(I.r(),9)n=1e6t=b/n g=0.5+f(b/2)~@k=1,n-1g=g+f(k*t)$I.w(t*g)

Byłby nie golfowym odpowiednikiem Lua

function f(x)
   return math.exp(x)/x^x
end

b=math.min(io.read("*n"),9)
n=1e6
t=b/n
g=0.5+f(b/2)

for k=1,n-1 do
   g=g+f(k*t)
end
io.write(t*g)

I przez „chwilę” mam na myśli około 10 minut. A to dlatego, że tak naprawdę nie przeczytałem komentarza Alexa, który to wyjaśnia, po prostu zobaczyłem to w kodzie.
Kyle Kanos,

2

Python 2, 94 76 bajtów

Dzięki @Dennis za uratowanie mnie 18 bajtów!

lambda I,x=1e5:sum((2.71828/i*x)**(i/x)/x for i in range(1,int(min(I,9)*x)))

Wypróbuj online z testcases!

Korzystanie z metody przybliżania w przybliżeniu. Używając prostokąta o szerokości 0,0001, co daje mi wymaganą precyzję. Również obcinanie wejść większych niż 9, aby zapobiec błędom pamięci przy bardzo dużych wejściach.


2

Perl 6, 90 55 bajtów

{my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

stosowanie

my &f = {my \x=1e5;sum ((e/$_*x)**($_/x)/x for 1..min($_,9)*x)}

f(1).say;       # 2.1827350239231
f(50).say;      # 6.39979602775846
f(10000).say;   # 6.39979602775846
f(2.71828).say; # 5.58039854392816
f(3.14159).say; # 5.92227602782184

Jest późno i muszę się przespać, zobaczę, czy jutro mogę dostać to krócej.

EDYCJA: Udało się go nieco skrócić po obejrzeniu metody @DenkerAffe.


1
Podoba mi się, jak tam jest napisane $ h * t. : D
Addison Crump

2

Pyth, 34 29 bajtów

Zapisano 5 bajtów przy pomocy @Dennis!

J^T5smcc^.n1d^ddJmcdJU*hS,Q9J

Wypróbuj online!

Wyjaśnienie

Ten sam algorytm jak w mojej odpowiedzi w języku Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = wejście
J ^ T5 # ustaw J więc szerokość prostokąta * 10 ^ 5
                       hS, Q9 # obcięte wejścia większe 9
                 Zakres mcdJU / J # od zera do Input in J steps
     mcc ^ .n1d ^ ddJ # oblicz obszar dla każdego elementu na liście
    s # Zsumuj wszystkie obszary i wynik


Można zaoszczędzić kilka bajtów przez przypisanie Jdo ^T5i zamiana mnożenia z podziałem wg J. Można również obciąć hS,Q9.
Dennis

@Dennis Dzięki, nie myślałem o tym. Również podstęp sortowania jest fajny, właśnie szukałem min^^
Denker

2

MATL , 26 bajtów

9hX<t1e6XK:K/*ttZebb^/sK/*

To przybliża całkę jako sumę Riemanna. Jak argumentuje Alex, możemy skrócić interwał integracji o około 9, ponieważ wartości funkcji są bardzo małe poza tym.

Maksymalna wartość funkcji jest mniejsza niż 3, więc krok około 1e-5 powinien wystarczyć do uzyskania pożądanej dokładności. Tak więc dla maksymalnego wkładu 9 potrzebujemy około 1e6 punktów.

W przypadku kompilatora online zajmuje to około 1,5 sekundy dla dowolnej wartości wejściowej.

Wypróbuj online !

9hX<         % input number, and limit to 9
t            % duplicate
1e6XK:       % generate vector [1,2,...,1e6]. Copy 1e6 to clipboard K
K/*          % divide by 1e6 and multiply by truncated input. This gives 
             % a vector with 1e6 values of x from 0 to truncated input
ttZe         % duplicate twice. Compute exp(x)
bb^          % rotate top three elements of stack twice. Compute x^x
/            % divide to compute exp(x)/x^x
s            % sum function values
K/*          % multiply by the step, which is the truncated input divided
             % by 1e6

2

Vitsy, 39 bajtów

Pomyślałem, że równie dobrze mogę wnieść własny wkład. ¯ \ _ (ツ) _ / ¯ Wykorzystuje oszacowanie całek Riemanna po lewej stronie Sumy.

D9/([X9]1a5^D{/V}*0v1{\[EvV+DDv{/}^+]V*

D9/([X9]               Truncation trick from Alex A.'s answer.
D                      Duplicate input.
 9/                    Divide it by 9.
   ([  ]               If the result is greater than 0
     X9                Remove the top item of the stack, and push 9.

1a5^D{/V}*0v0{         Setting up for the summation.
1                      Push 1.
 a5^                   Push 100000.
    D                  Duplicate the top item of the stack.
     {                 Push the top item of the stack to the back.
      /                Divide the top two items of the stack. (1/100000)
       V               Save it as a global variable.
                       Our global variable is ∆x.
        }              Push the bottom item of the stack to the top.
         *             Multiply the top two items.
                       input*100000 is now on the stack.
          0v           Save 0 as a temporary variable.
            0          Push 1.
             {         Push the bottom item of the stack to the top.
                       input*100000 is now the top of the stack.

\[EvV+DDv{/}^+]        Summation.
\[            ]        Loop over this top item of the stack times.
                       input*100000 times, to be exact.
  E                    Push Math.E to the stack.
   v                   Push the temporary variable to the stack.
                       This is the current value of x.
    V+                 Add ∆x.
      DD               Duplicate twice.
        v              Save the temporary variable again.
         {             Push the top item of the stack to the back.
          /            Divide the top two items.
                       e/x
           }           Push the top item back to the top of the stack.
            ^          Put the second to top item of the stack to the power of the top item.
                       (e/x)^x
             +         Add that to the current sum.

V*                     Multiply by ∆x

Pozostawia to sumę na górze stosu. Wypróbuj poniższy link online Nna końcu, aby pokazać wynik.

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.