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


24

Debe aproximar el valor de:

ingrese la descripción de la imagen aquí

Donde está tu opinión I.

Reglas

  • No puede utilizar ninguna función integral incorporada.
  • No puede usar ninguna función de suma infinita incorporada.
  • Su código debe ejecutarse en un período de tiempo razonable (<20 segundos en mi máquina)
  • Puede suponer que la entrada es mayor que 0 pero menor que el límite superior de su idioma.
  • Puede ser cualquier forma de retorno / salida estándar.

Puede verificar sus resultados en Wolfram | Alfa (puede verificar concatenando su entrada prevista para la consulta vinculada).

Ejemplos

(llamemos a la función f)

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

Su respuesta debe ser precisa para ±.0001.


@ThomasKwa Maximum para tu idioma. Lo agregaré a la pregunta.
Addison Crump

Wolfram Alpha dice que la última ronda5.92228
Neil

@Neil oo Alrighty entonces, debe haber escrito mal. ¡Gracias!
Addison Crump

77
Otorgaré 200 repeticiones a la respuesta válida más corta en TI-BASIC que se ejecute en <20 segundos en WabbitEmu al 100% de velocidad.
lirtosiast

@lirtosiast Si todavía tiene la intención de seguir esta recompensa, debe publicarla aquí .
Addison Crump

Respuestas:


10

Julia, 79 77 38 bytes

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

Esta es una función anónima que acepta un valor numérico y devuelve un flotante. Para llamarlo, asígnelo a una variable.

El enfoque aquí es usar una suma de Riemann correcta para aproximar la integral, que viene dada por la siguiente fórmula:

látex

En nuestro caso, a = 0 yb = I , la entrada. Dividimos la región de integración en n = 10 5 porciones discretas, entonces ∆ x = 1 / n = 10 -5 . Como se trata de una constante en relación con la suma, podemos extraerla de la suma y simplemente sumar las evaluaciones de funciones en cada punto y dividirlas por n .

La función es sorprendentemente buena (trama de Mathematica):

trama matemática

Como la función evalúa casi a 0 para entradas mayores que aproximadamente 9, truncamos la entrada para que sea I si I es menor que 9, o 9 en caso contrario. Esto simplifica los cálculos que tenemos que hacer significativamente.

Código sin golf:

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

¡Ahorró 39 bytes gracias a Dennis!


¿No es esto también equivalente a: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Parece un algoritmo un poco más simple de usar.
Addison Crump

10^4se puede escribir como 1e4.
Rainer P.

@VoteToClose Terminé tomando un enfoque diferente
Alex A.

@RainerP. Je, cierto. Gracias.
Alex A.

El valor asintótico de la integral es $ 6.39981 ... $. El valor $ 6.39981 ... - 10 ^ {- 4} $ se alcanza primero en $ I = 7.91399 ... $, por lo que puede truncar en $ 8 $ en lugar de $ 9 $ para ahorrar un poco de tiempo.
Eric Towers

9

Jalea, 20 19 17 bytes

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

Esto toma prestado el truncado inteligente en el truco 9 de la respuesta de @ AlexA. , y usa una suma de Riemann correcta para estimar la integral correspondiente.

Los casos de prueba truncados tardan un poco, pero son lo suficientemente rápidos en ¡ Pruébelo en línea!

Cómo funciona

ð«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 esta bien. La regla de la mano izquierda es cómo se conoce en las clases de Cálculo AP. : P Coolio.
Addison Crump

No estoy familiarizado con ese nombre, pero la regla de la izquierda probablemente usa los puntos finales izquierdos. Mi código usa los correctos.
Dennis

2
(~ -.-) ~ Es una forma de regla de la mano. xD
Addison Crump

4

ES7, 78 bytes

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

Esto usa la regla del rectángulo con 2000 rectángulos, que (al menos para los ejemplos) parecen producir una respuesta suficientemente precisa, pero la precisión podría aumentarse fácilmente si fuera necesario. Tiene que usar el truco 9; de lo contrario, la precisión disminuye para valores grandes.

Versión de 73 bytes que utiliza rectángulos de ancho ~ 0.001 para que no funcione por encima de ~ 700 porque Math.exp llega a Infinito:

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 caracteres

Lo admito: me tomó un tiempo descubrir el min(I,9)truco que Alex presentó permitió calcular números arbitrariamente altos porque la integral convergía para entonces.

\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 de Lua sin golf sería

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)

Y por "un rato" me refiero a unos 10 minutos. Y eso fue completamente porque en realidad no leí el comentario de Alex que lo explica, solo lo vi en el código.
Kyle Kanos

2

Python 2, 94 76 bytes

¡Gracias a @Dennis por salvarme 18 bytes!

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

¡Pruébelo en línea con cajas de prueba!

Usando el método de rectángulo para la aproximación. Usando un ancho de rectángulo de 0.0001 que me da la precisión exigida. También trunca las entradas mayores de 9 para evitar errores de memoria con entradas muy grandes.


2

Perl 6, 90 55 bytes

{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

Es tarde y necesito dormir, veré si puedo conseguir esto más corto mañana.

EDITAR: Logré hacerlo un poco más corto después de ver el método de @DenkerAffe.


1
Me gusta cómo dice $ h * t allí. : D
Addison Crump

2

Pyth, 34 29 bytes

¡Ahorré 5 bytes con algo de ayuda de @Dennis!

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

Pruébalo en línea!

Explicación

Mismo algoritmo que en mi respuesta de Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = input
J ^ T5 # establece J por lo ancho del rectángulo * 10 ^ 5
                       hS, Q9 # entradas truncadas mayor 9
                 mcdJU / J # rango de cero a entrada en J pasos
     mcc ^ .n1d ^ ddJ # calcular el área para cada elemento en la lista
    s # Suma todas las áreas y el resultado de salida


Usted puede ahorrar unos pocos bytes asignando Ja ^T5e intercambiando la multiplicación con la división por J. Además, el truncamiento se puede hacer con hS,Q9.
Dennis

@ Dennis Gracias, no pensé en eso. También el truco de clasificación es bueno, solo estaba buscando min^^
Denker

2

MATL , 26 bytes

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

Esto aproxima la integral como una suma de Riemann. Como argumentó Alex, podemos truncar el intervalo de integración en aproximadamente 9 porque los valores de la función son muy pequeños más allá de eso.

El valor máximo de la función es inferior a 3, por lo que un paso de aproximadamente 1e-5 debería ser suficiente para obtener la precisión deseada. Entonces, para la entrada máxima 9 necesitamos alrededor de 1e6 puntos.

Esto toma aproximadamente 1.5 segundos en el compilador en línea, para cualquier valor de entrada.

Pruébalo en línea !

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 bytes

Pensé que bien podría dar mi propia contribución. ¯ \ _ (ツ) _ / ¯ Esto utiliza la estimación de integrales de la suma de Riemann izquierda.

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

Esto deja la suma en la parte superior de la pila. El siguiente enlace para probarlo en línea se encuentra Nal final para mostrarle el resultado.

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.