Приблизительный ∫ ((e ^ x) / (x ^ x)) дх


24

Вы должны приблизить значение:

введите описание изображения здесь

Если ваш вход I.

правила

  • Вы не можете использовать какие-либо встроенные интегральные функции.
  • Вы не можете использовать какие-либо встроенные функции бесконечного суммирования.
  • Ваш код должен выполняться за разумное время (<20 секунд на моем компьютере)
  • Вы можете предположить, что ввод больше 0, но меньше верхнего предела вашего языка.
  • Это может быть любая форма стандартного возврата / вывода.

Вы можете проверить свои результаты на Wolfram | Альфа (вы можете проверить, объединив ваш предполагаемый вход в связанный запрос).

Примеры

(давайте назовем функцию f)

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

Ваш ответ должен быть точным ±.0001.


@ThomasKwa Максимум для вашего языка. Я добавлю это к вопросу.
Эддисон Крамп

Вольфрам Альфа говорит, что последний раунд5.92228
Нил

@ Нейл oO Хорошо, тогда, наверное, опечатка. Благодарность!
Эддисон Крамп

7
Я присуждаю 200 повторений за самый короткий действительный ответ в TI-BASIC, который выполняется в <20 секунд на WabbitEmu со скоростью 100%.
lirtosiast

@lirtosiast Если вы по-прежнему намерены продолжить эту награду, вы должны опубликовать ее здесь .
Эддисон Крамп

Ответы:


10

Юлия, 79 77 38 байт

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

Это анонимная функция, которая принимает числовое значение и возвращает число с плавающей запятой. Чтобы вызвать его, присвойте его переменной.

Подход здесь заключается в использовании правильной суммы Римана для аппроксимации интеграла, который задается следующей формулой:

латекс

В нашем случае a = 0 и b = I , вход. Разобьем область интегрирования на n = 10 5 дискретных частей, поэтому ∆ x = 1 / n = 10 -5 . Поскольку это константа относительно суммы, мы можем вывести ее за пределы суммы и просто сложить оценки функций в каждой точке и разделить на n .

Функция на удивление хорошо себя ведет (сюжет от Mathematica):

mathematicaplot

Так как функция оценивает почти 0 для входов больше 9, мы усекаем входные данные до I, если I меньше 9, или 9 в противном случае. Это упрощает вычисления, которые мы должны сделать значительно.

Ungolfed код:

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 байт!


Разве это также не эквивалентно: $ \ frac {t \ sum_ {k = 0} ^ {n} (f (a + kt) + f (a + (k + 1) t))} {2} $? Это кажется немного проще в использовании алгоритма.
Эддисон Крамп

10^4можно записать как 1e4.
Райнер П.

@VoteToClose Закончилось тем, что выбрал другой подход
Алекс А.

@RainerP. Хех, верно. Спасибо.
Алекс А.

Асимптотическое значение интеграла составляет $ 6,39981 ... $. Значение $ 6,39981 ... - 10 ^ {- 4} $ впервые достигается при $ I = 7,91399 ... $, поэтому вы можете сократить его до 8 $ вместо 9 $, чтобы сэкономить немного времени.
Эрик Тауэрс

9

Желе, 20 19 17 байт

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

Это заимствует умное усечение в 9 трюк из ответа @ AlexA. И использует правильную сумму Римана для оценки соответствующего интеграла.

Усеченные тестовые примеры занимают некоторое время, но достаточно быстрые на Попробуйте онлайн!

Как это работает

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

О хорошо Правило левой руки - это то, как оно упоминается в классах AP Calculus. : P Кулио.
Эддисон Крамп

Я не знаком с этим именем, но в левом правиле, вероятно, используются левые конечные точки. Мой код использует правильные.
Деннис

2
(~ -.-) ~ Это какая-то форма ручного правила. xD
Эддисон Крамп

4

ES7, 78 байт

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

При этом используется правило прямоугольника с 2000 прямоугольниками, которое (по крайней мере для примеров), по-видимому, дает достаточно точный ответ, но точность может быть легко увеличена при необходимости. Он должен использовать 9 трюк, иначе точность падает для больших значений.

73-байтовая версия, которая использует прямоугольники шириной ~ 0,001, поэтому она не работает выше ~ 700, потому что Math.exp достигает 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 символа

Я признаю это: мне потребовалось некоторое время, чтобы выяснить, какой min(I,9)трюк, представленный Алекс, позволил вычислить произвольно большие числа, потому что к тому времени интеграл сходился.

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

Эквивалент 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)

И под «временем» я подразумеваю около 10 минут. И это было полностью, потому что я на самом деле не читал комментарий Алекса, который объясняет это, просто видел его в коде.
Кайл Канос

2

Python 2, 94 76 байт

Спасибо @Dennis за то, что сэкономили мне 18 байт!

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

Попробуйте онлайн с тестовыми примерами!

Использование метода прямоугольника для приближения. Используя ширину прямоугольника 0,0001, что дает мне требуемую точность. Также усечение входов больше 9, чтобы предотвратить ошибки памяти с очень большими входами.


2

Perl 6, 90 55 байтов

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

использование

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

Уже поздно, и мне нужно поспать, я посмотрю, смогу ли я получить это немного короче завтра.

РЕДАКТИРОВАТЬ: удалось получить его немного короче, увидев метод @DenkerAffe.


1
Мне нравится, как там написано $ h * t. : D
Эддисон Крамп

2

Pyth, 34 29 байт

Сохранено 5 байт с помощью @Dennis!

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

Попробуйте онлайн!

объяснение

Тот же алгоритм, что и в моем ответе на Python .

J ^ T5smcc ^ .n1d ^ ddJmcdJU * hS, Q9J # Q = ввод
J ^ T5 # установить J так, чтобы ширина прямоугольника * 10 ^ 5
                       hS, Q9 # усеченные входы больше 9
                 mcdJU / J # диапазон от нуля до ввода в шагах J
     mcc ^ .n1d ^ ddJ # вычислить площадь для каждого элемента в списке
    s # Суммирование всех областей и выходной результат


Вы можете сохранить несколько байт, назначая Jдля ^T5и замены умножения с делением J. Кроме того, усечение может быть сделано с hS,Q9.
Деннис

@ Денис Спасибо, не думал об этом. Кроме того, уловка сортировки хороша, я просто искал min^^
Денкер

2

MATL , 26 байт

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

Это приближает интеграл как сумму Римана. Как утверждал Алекс, мы можем сократить интервал интегрирования примерно до 9, потому что значения функций очень малы.

Максимальное значение функции меньше 3, поэтому шага в 1e-5 должно быть достаточно для достижения желаемой точности. Таким образом, для максимального ввода 9 нам нужно около 1e6 баллов.

Это займет около 1,5 секунд в онлайн-компиляторе для любого входного значения.

Попробуйте онлайн !

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

Витси, 39 байт

Думаю, я мог бы также внести свой вклад. ¯ \ _ (ツ) _ / ¯ Используется левая оценка римановой суммы интегралов.

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

Это оставляет сумму на вершине стека. Ссылка «Попробуй онлайн» ниже Nпоказывает результат.

Попробуйте онлайн!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.