Approssimativo ∫ ((e ^ x) / (x ^ x)) dx


24

Devi approssimare il valore di:

inserisci qui la descrizione dell'immagine

Dov'è il tuo contributo I.

Regole

  • Non è possibile utilizzare alcuna funzione integrale integrata.
  • Non è possibile utilizzare alcuna funzione di somma infinita integrata.
  • Il codice deve essere eseguito in un periodo di tempo ragionevole (<20 secondi sulla mia macchina)
  • Puoi presumere che l'input sia maggiore di 0 ma inferiore al limite superiore della tua lingua.
  • Può essere qualsiasi forma di ritorno / output standard.

Puoi verificare i tuoi risultati su Wolfram | Alpha (è possibile verificare concatenando l'input previsto alla query collegata).

Esempi

(chiamiamo la funzione f)

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

La tua risposta dovrebbe essere accurata ±.0001.


@ThomasKwa Massimo per la tua lingua. Lo aggiungerò alla domanda.
Addison Crump,

Wolfram Alpha dice che l'ultimo round a5.92228
Neil

@Neil oo Va bene allora, devo aver sbagliato a scrivere. Grazie!
Addison Crump,

7
Assegnerò 200 rappresentanti alla risposta valida più breve in TI-BASIC che viene eseguita in <20 secondi su WabbitEmu alla velocità del 100%.
Lirtosiast

@lirtosiast Se hai ancora intenzione di dare seguito a questa taglia, dovresti invece pubblicarla qui .
Addison Crump,

Risposte:


10

Julia, 79 77 38 byte

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

Questa è una funzione anonima che accetta un valore numerico e restituisce un float. Per chiamarlo, assegnarlo a una variabile.

L'approccio qui è di usare una giusta somma di Riemann per approssimare l'integrale, che è dato dalla seguente formula:

latice

Nel nostro caso, a = 0 eb = I , l'input. Dividiamo la regione di integrazione in n = 10 5 porzioni discrete, quindi ∆ x = 1 / n = 10 -5 . Poiché si tratta di una costante relativa alla somma, possiamo estrarla dalla somma e sommare semplicemente le valutazioni delle funzioni in ciascun punto e dividerle per n .

La funzione è sorprendentemente ben educata (trama di Mathematica):

mathematicaplot

Poiché la funzione viene valutata quasi a 0 per input maggiori di circa 9, tronciamo l'input su I se I è inferiore a 9 o altrimenti 9. Questo semplifica i calcoli che dobbiamo fare in modo significativo.

Codice non golfato:

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

39 byte salvati grazie a Dennis!


Questo non equivale anche a: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Sembra un algoritmo leggermente più semplice da usare.
Addison Crump,

10^4può essere scritto come 1e4.
Rainer P.

@VoteToClose Alla fine ha adottato un approccio diverso
Alex A.

@RainerP. Heh, giusto. Grazie.
Alex A.

Il valore asintotico dell'integrale è $ 6,39981 ... $. Il valore $ 6,39981 ... - 10 ^ {- 4} $ viene prima ottenuto a $ I = 7,91399 ... $, quindi puoi troncare a $ 8 $ anziché $ 9 $ per risparmiare un po 'di tempo.
Eric Towers

9

Gelatina, 20 19 17 byte

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

Questa prende in prestito l'intelligente troncato a 9 trucco da @ Alexa risposta di. , E utilizza una giusta somma di Riemann per stimare l'integrale corrispondente.

I casi di test troncati richiedono un po 'di tempo, ma sono abbastanza veloci su Provalo online!

Come funziona

ð«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.

Oh va bene. La regola della mano sinistra indica come viene definita nelle classi di calcolo AP. : P Coolio.
Addison Crump,

Non ho familiarità con quel nome, ma la regola della mano sinistra probabilmente utilizza gli endpoint di sinistra. Il mio codice usa quelli giusti.
Dennis,

2
(~ -.-) ~ È una forma di regola consegnato. xD
Addison Crump

4

ES7, 78 byte

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

Questo utilizza la regola del rettangolo con 2000 rettangoli, che (almeno per gli esempi) sembrano produrre una risposta sufficientemente accurata, ma l'accuratezza potrebbe essere facilmente aumentata se necessario. Deve usare il trucco 9 altrimenti l'accuratezza diminuisce per valori elevati.

Versione a 73 byte che utilizza rettangoli di larghezza ~ 0,001 quindi non funziona sopra ~ 700 perché Math.exp colpisce 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 caratteri

Lo ammetto: mi ci è voluto un po 'per capire il min(I,9)trucco presentato da Alex che permetteva di calcolare numeri arbitrariamente alti perché l'integrale convergeva da allora.

\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)

Un equivalente Lua non golfato sarebbe

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)

E per "un po '" intendo circa 10 minuti. E questo perché non ho letto il commento di Alex che lo spiega, l'ho visto nel codice.
Kyle Kanos

2

Python 2, 94 76 byte

Grazie a @Dennis per avermi salvato 18 byte!

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

Provalo online con le prove!

Utilizzando il metodo rettangolo per l'approssimazione. Utilizzando una larghezza rettangolare di 0,0001 che mi dà la precisione richiesta. Troncando anche input maggiori 9 per prevenire errori di memoria con input molto grandi.


2

Perl 6, 90 55 byte

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

uso

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

È tardi e ho bisogno di dormire, vedrò se riesco a farlo più breve domani.

EDIT: gestito per renderlo un po 'più breve dopo aver visto il metodo di @DenkerAffe.


1
Mi piace come dice $ h * t lì dentro. : D
Addison Crump

2

Pyth, 34 29 byte

Hai salvato 5 byte con l'aiuto di @Dennis!

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

Provalo online!

Spiegazione

Stesso algoritmo della mia risposta Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = input
J ^ T5 # imposta J in modo che la larghezza del rettangolo * 10 ^ 5
                       hS, Q9 # tronca gli ingressi maggiori 9
                 Intervallo mcdJU / J # da zero a Input in passi J
     mcc ^ .n1d ^ ddJ # calcola l'area per ciascun elemento nell'elenco
    s # Somma tutte le aree e il risultato di output


È possibile salvare pochi byte assegnando Jad ^T5e scambiando la moltiplicazione con la divisione per J. Inoltre, il troncamento può essere eseguito con hS,Q9.
Dennis,

@Dennis Grazie, non ci ho pensato. Anche il trucco di smistamento è carino, stavo solo cercando min^^
Denker

2

MATL , 26 byte

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

Questo si avvicina all'integrale come somma di Riemann. Come sostenuto da Alex, possiamo troncare l'intervallo di integrazione a circa 9 perché i valori della funzione sono molto piccoli oltre a ciò.

Il valore massimo della funzione è inferiore a 3, quindi un passaggio di circa 1e-5 dovrebbe essere sufficiente per ottenere l'accuratezza desiderata. Quindi per il massimo input 9 abbiamo bisogno di circa 1e6 punti.

Questo richiede circa 1,5 secondi nel compilatore online, per qualsiasi valore di input.

Provalo 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 byte

Ho pensato di poter dare il mio contributo. ¯ \ _ (ツ) _ / ¯ Questo utilizza la stima della somma di Riemann per la mano sinistra degli integrali.

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

Questo lascia la somma in cima alla pila. Il link prova online qui sotto ha Nalla fine per mostrarti il ​​risultato.

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.