Ters Pi işlevi


17

Pi fonksiyonu faktöriyelerin gerçekler (ya da karmaşık sayılar) üzerindeki bir uzantısıdır. N tamsayıları için , Π (n) = n! ancak gerçekler üzerinde bir tanım elde etmek için onu bir integral kullanarak tanımlarız:

Pi (z) = 0'dan sonsuzluğa integral e ^ -tt ^ z dt

Bu meydan okumada Π fonksiyonunu tersine çevireceğiz .

Gerçek sayısı göz önüne alındığında z ≥ 1 , pozitif bulmak x öyle ki Π (x) = Z . Cevabınız en az 5 ondalık basamak için doğru olmalıdır.


Örnekler:

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

4
İnsanların daha çok Gamma (Γ) işlevini kullandığını unutmayın. Π (x) = Γ (x + 1) . Ancak IMO Γ kaymış bir iğrençliktir ve Π faktöriyelin gerçek uzantısıdır.
orlp

1
Eh, bu dizi genişlemesi beni korkutmak için yeterli ... i.imgur.com/ttgzDSJ.gif
Sihirli Ahtapot Urn

1
Örneğin verdiğiniz tüm örneklerin başka çözümleri de var 120 -> -0.991706. Bunun nedeni, x sağdan -1'e giderken Π (x) sonsuza gider. Belki de x> 0'da ısrar etmek istersiniz.
Greg Martin

@GregMartin de eklendi.
orlp

1
Doğal görünmese de, kaydırılmış versiyonu tercih etmek için bazı nedenler var. Örneğin MathOverflow'daki bu yanıta ve o sayfadaki diğer yanıtlara bakın.
Ruslan

Yanıtlar:


8

Mathematica, 17 15 27 bayt

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

Çıktı , çözüm {{x -> n}}nerede n, izin verilmeyecek gibi görünüyor .


7

Pyth, 4 bayt

.I.!

Bir sayı girdisi alan ve sonucu basan bir program.

Test odası

Nasıl çalışır

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

1`1e-5+tQYgG<

Bu, 1e-5başlangıç adımında doğrusal arama kullanır 1. Bu yüzden çok yavaş ve çevrimiçi derleyicide zaman aşımına uğradı.

Bunu test etmek için aşağıdaki bağlantı, 1e-5doğruluk gereksiniminin yerine geçer 1e-2. Çevrimiçi deneyin!

açıklama

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 bayt

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

CAS girişine girilir ve elektronik tablo hücresine bir sayı girilmesini bekler A1. Formun tek öğeli bir dizisini döndürür {x = <result>}.

İşte infaz bir gif:

Programın yürütülmesi

Nasıl çalışır

Numerically Solveaşağıdaki eşitlik: Gamma(x+1)=A1başlangıç ​​değeri ile x=1.


Pozitif bir sayı döndürmesi garanti ediliyor mu ve birkaç cevap kırmış olan 1.5 için mi çalışıyor?
Pavel

@Pavel Çalıştığını doğrulayabilirim 1.5. GeoGebra'nın sayısal çözümleme için hangi algoritmayı kullandığını bulamadım, ancak ilk değeri x=1denediğim her değer için tamamen olumlu cevaplar verdi.
TheBikingViking

2

MATLAB, 59 bayt

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

Bu, Pi işlevi ve girdisi arasındaki kare farkının en aza indirgeyicisini , istenen hassasiyeti elde etmek için 1çok küçük bir toleransla (tarafından verilen eps) başlayarak bulan anonim bir işlevdir .

Test senaryoları (Matlab R2015b'de çalışır):

>> @(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

Sen olabilir çevrimiçi denemek Octave, ama ne yazık ki bazı sonuç gerekli hassasiyet yoksundur.


2

J, 86 33 bayt

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

Taşmayı önlemek için Newton'un log Pi ile yöntemini kullanır.

Bu, Stirling yaklaşımını kullanarak günlük Gama'yı hesaplayan önceki sürümdür. Log Gamma'daki (3) adım boyutu (1e3) ve terim sayısı, performans maliyetinde muhtemelen daha yüksek doğruluk için arttırılabilir.

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

Anında katsayı terimlerini hesaplayan başka bir sürüm

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

Çevrimiçi deneyin! ve terimlerin yakınlaştığını görmek için .

açıklama

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

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

FindRoot bir başlangıç ​​değeri olduğunda Newton yöntemini dahili olarak uygular.

Aşağıdaki iki yöntem doğrudan Newton'un yöntemini uygular.

FixedPoint 45 bayt kullanma alternatifi

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

Mathematica, türevi yaklaşık olarak tahmin etmek yerine doğrudan hesaplayabildiğinden Newton'un bunu çözme yönteminin daha kesin bir uygulaması.

Tekrar tekrar değiştirmek için kuralların kullanılması daha kısa olacaktır, ancak kaç tane yineleme yapabileceği, vurulabilecek bir sınır vardır (65536) FixedPoint.

Alternatif kullanma kuralları, 38 bayt

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

görüntü


1

Jöle , 34 bayt

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

Çevrimiçi deneyin! veya Ara değerleri birleştikçe görüntüleyin .

Newton yöntem ve türev uyumu (sekant yöntem) J'nin kombinasyonunun bir uygulama tersini hesaplamak için Π ( n ).

Taşmayı önlemek için kütüğün tersini ( Π ( n )) çözer .

İlk tahminle başlar x 0 = y +1, burada y = log ( Π ( n )). Daha sonra x n +1 = x n - (log ( Π ( x n )) - y ) / (log (( Π (1.001 * x n )) - log ( Π ( x n ))) / kullanarak yakınsama gerçekleşir (0.001 x x n )).



@ LouisMendo Vay be bu iyi bir yakalama! Ara değerlerden biri gama uygulandıktan sonra büyük bir değer olan ~ 65807 olduğundan ve Python taşar. Aynı hesaplama J için de geçerlidir, çünkü aynı hesaplamaya dayanır.
mil

1

PARI / GP, 30 bayt

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

Arasındaki çözümü bulur 1ve x+1. Ne yazık ki, xgiriş için üst sınır kadar büyük değil 1.5.


1

Mathematica, 26 Bayt

Yine başka bir Mathematica çözümü!

Denklem çözme her zaman bir minimizasyon problemine dönüştürülebilir.

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

Denklemin sol ve sağ tarafları arasındaki farkı en aza indiren argümanı bulur.

NMinimize değil NArgMin kullanmak, çıktıyı olağan ayrıntılı kural tabanlı çıktıdan ziyade istenen sonuç olmaya zorlar (ve bir bayt kurtarır!)


0

Libm ile C, 111

Güncelleme - giriş 1.5 için sabit.

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)söz konusu aralıkta monoton olarak artan bir işlevdir, shis, ardışık değerler arasındaki fark küçük olana kadar sadece ikili bir aramadır. Başlangıç ​​alt sınırı 0ve başlangıç ​​üst sınırı 2*x.

Giriş ve çıkış, fonksiyona iletilen bir çifte bir işaretçi üzerinden yapılır.

Bu daha derin golf olabilir eminim - özellikle 4 yerel çiftler gerekir sanmıyorum, ama şimdiye kadar bunu azaltmak için kolay bir yol görmüyorum.

Çevrimiçi deneyin - Oluşturur (libm ile bağlantı kurar) ve bir bash betiğinde çalışır.

Hafifçe soluksuz:

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;
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.