Funzione Pi inversa


17

La funzione Pi è un'estensione del fattoriale sui reali (o anche sui numeri complessi). Per numeri interi n , Π (n) = n! , ma per ottenere una definizione sui reali la definiamo usando un integrale:

Pi (z) = t integrale da 0 a infinito e ^ -tt ^ z dt

In questa sfida invertiremo la funzione Π .

Dato un numero reale z ≥ 1 , trova positivo x tale che Π (x) = z . La tua risposta deve essere accurata per almeno 5 cifre decimali.


Esempi:

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

4
Si noti che più spesso le persone usano la funzione Gamma (Γ). Π (x) = Γ (x + 1) . Ma l'IMO Γ è un abominio mutato, e Π è la vera estensione del fattoriale.
orlp,

1
Bene, l'espansione di quella serie è sufficiente per spaventarmi ... i.imgur.com/ttgzDSJ.gif
Magic Octopus Urn

1
Tutti gli esempi forniti offrono anche altre soluzioni, ad esempio 120 -> -0.991706. Questo perché Π (x) va all'infinito mentre x va a -1 da destra. Forse intendi insistere anche su x> 0.
Greg Martin,

@GregMartin Anche aggiunto.
orlp,

1
Ci sono alcuni motivi per preferire la versione spostata, nonostante sembri innaturale. Vedi ad esempio questa risposta su MathOverflow e altre su quella pagina.
Ruslan,

Risposte:


8

Mathematica, 17 15 27 byte

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

L'output appare {{x -> n}}, dov'è nla soluzione, che potrebbe non essere consentita.


7

Pyth, 4 byte

.I.!

Un programma che accetta l'input di un numero e stampa il risultato.

Suite di test

Come funziona

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

1`1e-5+tQYgG<

Questo utilizza la ricerca lineare nelle fasi di 1e-5inizio a 1. Quindi è terribilmente lento e scade nel compilatore online.

Per testarlo, il seguente link sostituisce il 1e-5requisito di precisione con 1e-2. Provalo online!

Spiegazione

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 byte

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

Inserito nell'input CAS e si aspetta l'immissione di un numero nella cella del foglio di calcolo A1. Restituisce una matrice a un elemento del modulo {x = <result>}.

Ecco una gif dell'esecuzione:

Esecuzione del programma

Come funziona

Numericamente Solvela seguente equazione :, Gamma(x+1)=A1con valore iniziale x=1.


Garantisce la restituzione di un numero positivo e funziona con 1.5, che ha infranto diverse risposte?
Pavel,

@Pavel Posso confermare che funziona 1.5. Non sono stato in grado di scoprire quale algoritmo GeoGebra utilizza per la risoluzione numerica, ma il valore iniziale di x=1ha dato risposte puramente positive per ogni valore che ho provato.
TheBikingViking

2

MATLAB, 59 byte

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

Questa è una funzione anonima che trova il minimizzatore della differenza quadrata tra la funzione Pi e il suo input, a partire da 1, con una tolleranza molto piccola (data da eps) per ottenere la precisione desiderata.

Casi di test (eseguiti su 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

Potresti provarlo online in Octave, ma sfortunatamente alcuni dei risultati mancano della precisione richiesta.


2

J, 86 33 byte

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

Utilizza il metodo di Newton con log Pi per evitare traboccamenti.

Questa è la versione precedente che calcola il registro Gamma usando l'approssimazione di Stirling. La dimensione del gradino (1e3) e il numero di termini nel log Gamma (3) possono essere aumentati per un'accuratezza forse più elevata a costo della prestazione.

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

Un'altra versione che calcola i termini dei coefficienti al volo

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

Provalo online! e vedere i termini convergere .

Spiegazione

((]-(-~^.@!)%[:^.@!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 byte

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

FindRoot applica il metodo di Newton internamente quando esiste un valore iniziale.

I due metodi seguenti applicano direttamente il metodo di Newton.

Alternativa usando FixedPoint 45 byte

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

Un'implementazione più precisa del metodo di Newton per risolvere questo dato che Mathematica può calcolare direttamente la derivata invece di approssimarla.

L'uso delle regole per la sostituzione ripetuta sarebbe più breve, ma esiste un limite (65536) al numero di iterazioni che può eseguire che potrebbero essere colpite mentre FixedPointnon ha un limite.

Alternativa usando regole, 38 byte

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

Immagine


1

Gelatina , 34 byte

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

Provalo online! oppure Visualizza i valori intermedi mentre convergono .

Un'implementazione della combinazione di J del metodo di Newton e approssimazione derivata (metodo secante) per calcolare l'inverso di Π ( n ).

Risolve invece l'inverso del log ( Π ( n )) per evitare il trabocco.

Inizia con un'ipotesi iniziale x 0 = y +1 dove y = log ( Π ( n )). Quindi scorre fino alla convergenza usando x n +1 = x n - (log ( Π ( x n )) - y ) / (log (( Π (1.001 * x n )) - log ( Π ( x n ))) / (0,001 * x n )).


3
Viene visualizzato un errore con l'input1.5
Luis Mendo,

@LuisMendo Wow, è una buona cattura! Si verifica poiché uno dei valori intermedi è ~ 65807, valore enorme dopo l'applicazione della gamma e overflow di Python. Lo stesso si verifica in J poiché si basa sullo stesso calcolo.
miglia

1

PARI / GP, 30 byte

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

Trova la soluzione tra 1e x+1. Sfortunatamente, xnon è abbastanza grande come limite superiore per input simili 1.5.


1

Mathematica, 26 byte

Ancora un'altra soluzione Mathematica!

La risoluzione delle equazioni può sempre essere trasformata in un problema di minimizzazione.

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

Trova l'argomento che minimizza la differenza tra i lati sinistro e destro dell'equazione.

L'uso di NArgMin anziché NMinimize impone che l'output sia solo il risultato desiderato anziché il solito output dettagliato basato su regole (e salva un byte!)


0

C con libm, 111

Aggiornamento - risolto per input 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)è una funzione monotonicamente crescente nell'intervallo in questione, shis è solo una ricerca binaria fino a quando la differenza tra i valori successivi è piccola. Il limite inferiore iniziale è 0e il limite superiore iniziale è 2*x.

L'input e l'output avviene tramite un puntatore a un doppio passato alla funzione.

Sono abbastanza sicuro che questo possa essere più profondo, in particolare non credo di aver bisogno di 4 doppie locali, ma finora non vedo un modo semplice per ridurlo.

Provalo online - Build (collegamento con libm) ed eseguito in uno script bash.

Leggermente ungolfed:

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;
    }
}
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.