Fungsi Pi terbalik


17

Fungsi Pi adalah perpanjangan dari faktorial di atas real (atau bahkan bilangan kompleks). Untuk bilangan bulat n , Π (n) = n! , tetapi untuk mendapatkan definisi atas real kami mendefinisikannya menggunakan integral:

Pi (z) = integral t dari 0 hingga tak terbatas e ^ -tt ^ z dt

Dalam tantangan ini kita akan membalikkan fungsi Π .

Dengan bilangan real z ≥ 1 , cari positif x sedemikian rupa sehingga that (x) = z . Jawaban Anda harus akurat untuk setidaknya 5 digit desimal.


Contoh:

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

4
Perhatikan bahwa semakin sering orang menggunakan fungsi Gamma (Γ). Π (x) = Γ (x + 1) . Tetapi IMO Γ adalah kekejian yang bergeser, dan Π adalah perpanjangan sebenarnya dari faktorial.
orlp

1
Wellp, ekspansi seri itu cukup untuk menakuti saya ... i.imgur.com/ttgzDSJ.gif
Magic Octopus Guci

1
Semua contoh yang Anda berikan memiliki solusi lain juga, misalnya 120 -> -0.991706. Ini karena Π (x) pergi hingga tak terhingga ketika x pergi ke -1 dari kanan. Mungkin Anda bermaksud menekankan bahwa x> 0 juga.
Greg Martin

@GregMartin Ditambahkan juga.
orlp

1
Ada beberapa alasan untuk lebih memilih versi bergeser, meskipun tampaknya tidak wajar. Lihat misalnya jawaban ini di MathOverflow dan juga yang lain di halaman itu.
Ruslan

Jawaban:


8

Mathematica, 17 15 27 byte

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

Output terlihat seperti {{x -> n}}, di mana nsolusinya, yang mungkin tidak diizinkan.


7

Pyth, 4 byte

.I.!

Program yang mengambil input nomor dan mencetak hasilnya.

Suite uji

Bagaimana itu bekerja

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

Ini menggunakan pencarian linear dalam langkah-langkah 1e-5mulai dari 1. Jadi itu sangat lambat, dan waktu habis dalam kompiler online.

Untuk mengujinya, tautan berikut ini menggantikan 1e-5persyaratan akurasi oleh 1e-2. Cobalah online!

Penjelasan

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]

Dimasukkan dalam input CAS, dan mengharapkan input nomor dalam sel spreadsheet A1. Mengembalikan array satu elemen dari formulir {x = <result>}.

Berikut adalah gif dari eksekusi:

Eksekusi program

Bagaimana itu bekerja

Nsecara Solvepersamaan berikut:: Gamma(x+1)=A1dengan nilai awal x=1.


Apakah dijamin akan mengembalikan angka positif, dan apakah itu berfungsi untuk 1,5, yang telah melanggar beberapa jawaban?
Pavel

@Pavel Saya dapat mengkonfirmasi bahwa itu berfungsi untuk 1.5. Saya belum dapat menemukan algoritma yang digunakan GeoGebra untuk penyelesaian numerik, tetapi nilai awal dari x=1telah memberikan jawaban murni positif untuk setiap nilai yang saya coba.
TheBikingViking

2

MATLAB, 59 byte

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

Ini adalah fungsi anonim yang menemukan minimizer dari perbedaan kuadrat antara fungsi Pi dan inputnya, mulai dari 1 , dengan toleransi yang sangat kecil (diberikan oleh eps) untuk mencapai presisi yang diinginkan.

Test case (dijalankan di 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

Anda dapat mencobanya secara online di Octave, tetapi sayangnya beberapa hasil tidak memiliki ketelitian yang diperlukan.


2

J, 86 33 byte

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

Menggunakan metode Newton dengan log Pi untuk menghindari luapan.

Ini adalah versi sebelumnya yang menghitung log Gamma menggunakan perkiraan Stirling. Ukuran langkah (1e3) dan jumlah istilah dalam log Gamma (3) dapat ditingkatkan untuk akurasi yang mungkin lebih tinggi dengan biaya kinerja.

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

Versi lain yang menghitung ketentuan koefisien dengan cepat

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

Cobalah online! dan untuk melihat istilah-istilah tersebut bertemu .

Penjelasan

((]-(-~^.@!)%[:^.@!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 menerapkan metode Newton secara internal ketika ada nilai awal.

Dua metode di bawah ini menerapkan metode Newton secara langsung.

Alternatif menggunakan FixedPoint 45 byte

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

Implementasi metode Newton yang lebih tepat untuk menyelesaikan ini karena Mathematica dapat menghitung turunan secara langsung alih-alih memperkirakannya.

Menggunakan aturan untuk mengganti berulang kali akan lebih pendek, tetapi ada batas (65536) untuk berapa banyak iterasi yang dapat dilakukan yang mungkin terkena sedangkan FixedPoint tidak memiliki batas.

Alternatif menggunakan aturan, 38 byte

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

Gambar


1

Jelly , 34 byte

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

Cobalah online! atau Lihat nilai-nilai antara saat mereka bertemu .

Implementasi kombinasi J dari metode Newton dan perkiraan turunan (metode garis potong) untuk menghitung kebalikan dari Π ( n ).

Ini memecahkan untuk kebalikan dari log ( Π ( n )) sebagai gantinya untuk menghindari overflow.

Dimulai dengan tebakan awal x 0 = y +1 di mana y = log ( Π ( n )). Kemudian beralih hingga konvergensi menggunakan x n +1 = x n - (log ( Π ( x n )) - y ) / (log (( Π (1,001 * x n )) - log ( Π ( x n ))) / (0,001 * x n )).


3
Saya mendapatkan pesan kesalahan dengan input1.5
Luis Mendo

@LuisMendo Wow itu tangkapan yang bagus! Ini terjadi karena salah satu nilai antara adalah ~ 65807 yang merupakan nilai besar setelah gamma diterapkan, dan Python meluap. Hal yang sama terjadi pada J karena bergantung pada perhitungan yang sama.
mil

1

PARI / GP, 30 byte

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

Menemukan solusi antara 1dan x+1. Sayangnya, xtidak cukup besar sebagai batas atas untuk input suka 1.5.


1

Mathematica, 26 Bytes

Namun solusi lain Mathematica!

Penyelesaian persamaan selalu dapat diubah menjadi masalah minimisasi.

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

Menemukan argumen yang meminimalkan perbedaan antara sisi kiri dan kanan persamaan.

Menggunakan NArgMin daripada NMinimize memaksa output hanya menjadi hasil yang diinginkan daripada output berbasis aturan verbose biasa (dan menghemat satu byte!)


0

C dengan libm, 111

Pembaruan - diperbaiki untuk 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)adalah fungsi yang meningkat secara monoton pada rentang yang dimaksud, shis hanyalah pencarian biner sampai perbedaan antara nilai-nilai berturut-turut kecil. Batas bawah awal adalah 0dan batas atas awal adalah2*x .

Input dan output adalah melalui pointer ke ganda yang dilewatkan ke fungsi.

Saya cukup yakin ini bisa bermain golf lebih dalam - khususnya saya tidak berpikir saya membutuhkan 4 ganda lokal, tapi sejauh ini saya tidak melihat cara mudah untuk mengurangi ini.

Cobalah secara online - Membangun (menautkan dengan libm) dan berjalan dalam skrip bash.

Tanpa 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;
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.