Обратная функция Пи


17

Функция Пи является расширением факториала по реалам (или даже комплексным числам). Для целых чисел п , Π (п) = п! , но чтобы получить определение по реалам, мы определяем его с помощью интеграла:

Pi (z) = целое t от 0 до бесконечности e ^ -tt ^ z dt

В этих проблемах мы будем инвертировать П функцию.

Для вещественного числа z ≥ 1 найдите положительное x такое, что Π (x) = z . Ваш ответ должен быть точным не менее 5 десятичных цифр.


Примеры:

120 -> 5.0000
10 -> 3.39008
3.14 -> 2.44815
2017 -> 6.53847
1.5 -> 1.66277

4
Обратите внимание, что чаще люди используют функцию Gamma (Γ). Π (x) = Γ (x + 1) . Но IMO Γ - это сдвинутая мерзость, а Π - истинное продолжение факториала.
orlp

1
Wellp, этого расширения серии достаточно, чтобы напугать меня ... i.imgur.com/ttgzDSJ.gif
Волшебная Урна Осьминога

1
Например, все приведенные вами примеры имеют и другие решения 120 -> -0.991706. Это связано с тем, что) (x) стремится к бесконечности, а x - к -1 справа. Возможно, вы хотите настаивать на том, что x> 0 также.
Грег Мартин

@GregMartin Добавлено также.
orlp

1
Есть несколько причин предпочесть сдвинутую версию, несмотря на то, что она кажется неестественной. Посмотрите, например, этот ответ на MathOverflow, а также другие на этой странице.
Руслан

Ответы:


8

Mathematica, 17 15 27 байт

FindInstance[#==x!&&x>0,x]&

Вывод выглядит так {{x -> n}}, где nнаходится решение, которое не может быть разрешено.


7

Pyth, 4 байта

.I.!

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

Тестирование

Как это устроено

.I.!    Program. Input: Q
.I.!GQ  Implicit variable fill
.I      Find x such that:
  .!G    gamma(x+1)
     Q   == Q
        Implicitly print

5

MATL , 13 байт

1`1e-5+tQYgG<

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

Чтобы проверить это, следующая ссылка заменяет 1e-5требование точности на 1e-2. Попробуйте онлайн!

объяснение

1        % Push 1 (initial value)
`        % Do...while
  1e-5   %   Push 1e-5
  +      %   Add
  t      %   Duplicate
  QYg    %   Pi function (increase by 1, apply gamma function)
  G<     %   Is it less than the input? If so: next iteration
         % End (implicit)
         % Display (implicit)

3

GeoGebra , 25 байт

NSolve[Gamma(x+1)=A1,x=1]

Введен во вход CAS и ожидает ввода числа в ячейку электронной таблицы A1. Возвращает одноэлементный массив формы {x = <result>}.

Вот рисунок исполнения:

Исполнение прогрмы

Как это устроено

Nв уме Solveследующее уравнение: Gamma(x+1)=A1с начальным значением x=1.


Гарантируется ли возвращение положительного числа, и работает ли оно на 1,5, что сломало несколько ответов?
Павел

@Pavel Я могу подтвердить, что это работает 1.5. Я не смог выяснить, какой алгоритм использует GeoGebra для численного решения, но первоначальное значение x=1дало чисто положительные ответы для каждого значения, которое я пробовал.
TheBikingViking

2

MATLAB, 59 байт

@(x)fminsearch(@(t)(gamma(t+1)-x)^2,1,optimset('TolF',eps))

Это анонимная функция, которая находит минимизатор квадрата разности между функцией Pi и его входом, начиная 1с очень малого допуска (заданного eps) для достижения желаемой точности.

Тестовые случаи (запуск на Matlab R2015b):

>> @(x)fminsearch(@(t)(gamma(t+1)-x)^2,1,optimset('TolF',eps))
ans = 
    @(x)fminsearch(@(t)(gamma(t+1)-x)^2,1,optimset('TolF',eps))
>> f = ans; format long; f(120), f(10), f(3.14), f(2017)
ans =
   5.000000000000008
ans =
   3.390077650547032
ans =
   2.448151165246967
ans =
   6.538472664321318

Вы можете попробовать это онлайн в Octave, но, к сожалению, некоторым результатам не хватает необходимой точности.


2

J, 86 33 байта

((]-(-~^.@!)%[:^.@!D.1])^:_>:)@^.

Использует метод Ньютона с log Pi, чтобы избежать переполнения.

Это предыдущая версия, которая вычисляет log Gamma, используя приближение Стирлинга. Размер шага (1e3) и количество членов в журнале Gamma (3) могут быть увеличены для возможно более высокой точности за счет производительности.

3 :'(-(k-~g)%%&1e3(g=:((%~12 _360 1260 p.&:%*:)+-+^~-&^.%:@%&2p1)@>:)D:1])^:_>:k=:^.y'

Еще одна версия, которая вычисляет коэффициент коэффициентов на лету

3 :'(-((-^.y)+g)%%&1e3(g=:((%~(((%1-^@-)t:%]*<:)+:>:i.3)p.%@*:)+(*^.)-]+-:@^.@%&2p1)@>:)D:1])^:_>:^.y'

Попробуйте онлайн! и увидеть термины сходятся .

объяснение

((]-(-~^.@!)%[:^.@!D.1])^:_>:)@^.  Input: float y
(                            )@^.  Operate on log(y)
                           >:        Increment, the initial guess is log(y)+1
 (                     )^:_          Repeat until convergence starting with x = log(y)+1
                      ]                Get x
               ^.@!                    The log Pi verb
             [:    D.1                 Approximate its first derivative at x
       ^.@!                            Apply log Pi to x
     -~                                Subtract log(y) from it
            %                          Divide it by the derivative
  ]-                                   Subtract it from x and use as next value of x

2

Mathematica, 21 байт

FindRoot[#-x!,{x,1}]&

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

Два метода ниже применяют метод Ньютона напрямую.

Альтернатива с использованием FixedPoint 45 байт

FixedPoint[#-(#!-y)/Gamma'[#+1]&,Log[y=#]+1]&

Более точная реализация метода Ньютона для решения этой проблемы, поскольку Mathematica может вычислять производную напрямую, а не аппроксимировать ее.

Использование правил для многократной замены будет короче, но существует ограничение (65536) на количество итераций, которые он может выполнить, FixedPointи при этом не имеет ограничения.

Альтернативное использование правил, 38 байт

Log[y=#]+1//.x_->x-(x!-y)/Gamma'[x+1]&

Образ


1

Желе , 34 байта

Ḋ!Æl_®
ȷİ‘×;µ!ÆlI÷I÷@Ç_@ḊḢ
Æl©‘ÇÐĿ

Попробуйте онлайн! или просмотреть промежуточные значения по мере их сходства .

Реализация комбинации J метода Ньютона и аппроксимации производной (секущий метод) для вычисления обратного значения Π ( n ).

Вместо этого он решает обратный лог ( Π ( n )), чтобы избежать переполнения.

Начинается с начальной догадки х 0 = y +1, где y = log ( Π ( n )). Затем выполняется итерация до сходимости с использованием x n +1 = x n - (log ( Π ( x n )) - y ) / (log (( Π (1.001 * x) n )) - log ( Π ( x n ))) / (0,001 * x n )).


3
Я получаю сообщение об ошибке1.5
Луис Мендо

@ LuisMendo Ого, это хороший улов! Это происходит, поскольку одно из промежуточных значений составляет ~ 65807, что является огромным значением после применения гаммы и переполнения Python. То же самое происходит в J, поскольку он опирается на те же вычисления.
миль

1

PARI / GP, 30 байтов

x->solve(t=1,x+1,gamma(t+1)-x)

Находит решение между 1 и x+1. К сожалению, xон недостаточно велик в качестве верхней границы для ввода 1.5.


1

Mathematica, 26 байт

Еще одно решение Mathematica!

Решение уравнений всегда можно превратить в задачу минимизации.

NArgMin[{(#-x!)^2,x>0},x]&

Находит аргумент, который минимизирует разницу между левой и правой сторонами уравнения.

Использование NArgMin вместо NMinimize заставляет вывод быть желаемым результатом, а не обычным подробным выводом на основе правил (и это сохраняет байт!)


0

C с libm, 111

Обновление - исправлено для входа 1.5.

f(double *z){double u=2**z,l=0,g=u,p=0;for(;log(fabs(g-p))>-14;)p=g,g=(u+l)/2,u=tgamma(g+1)>*z?g:(l=g,u);*z=g;}

gamma(x+1)является монотонно возрастающей функцией в рассматриваемом диапазоне, shis - это просто двоичный поиск, пока разница между последовательными значениями не станет небольшой. Начальная нижняя граница 0и начальная верхняя граница 2*x.

Ввод и вывод через указатель на двойник передается в функцию.

Я почти уверен, что это можно сделать глубже - в частности, я не думаю, что мне нужно 4 местных пары, но пока я не вижу простого способа уменьшить это.

Попробуйте онлайн - собирает (связывает с libm) и запускает в bash-скрипте.

Слегка разряженный

f(double *z){
    double u=2**z,l=0,g=u,p=0;
    for(;log(fabs(g-p))>-14;){
        p=g;
        g=(u+l)/2;
        u=tgamma(g+1)>*z?g:(l=g,u);*z=g;
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.