Hàm nghịch đảo Pi


17

Hàm Pi là một phần mở rộng của giai thừa trên các số thực (hoặc thậm chí là số phức). Với số nguyên n , (n) = n! , nhưng để có được một định nghĩa trên thực tế, chúng tôi xác định nó bằng cách sử dụng một tích phân:

Pi (z) = tích phân t từ 0 đến vô cùng e ^ -tt ^ z dt

Trong thử thách này, chúng ta sẽ đảo ngược Π chức năng.

Cho số thực z 1 , tìm dương x sao cho Π (x) = z . Câu trả lời của bạn phải chính xác cho ít nhất 5 chữ số thập phân.


Ví dụ:

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

4
Lưu ý rằng mọi người thường sử dụng chức năng Gamma (Γ). Π (x) = Γ (x + 1) . Nhưng IMO là một sự ghê tởm thay đổi và là phần mở rộng thực sự của giai thừa.
orlp

1
Chà, việc mở rộng chuỗi đó đủ để làm tôi sợ ... i.imgur.com/ttgzDSJ.gif
Bạch tuộc ma thuật Urn

1
Tất cả các ví dụ bạn đưa ra cũng có các giải pháp khác 120 -> -0.991706. Điều này là do (x) đi đến vô cùng khi x đi đến -1 từ bên phải. Có lẽ bạn muốn nhấn mạnh rằng x> 0 là tốt.
Greg Martin

@GregMartin Đã thêm.
orlp

1
Có một số lý do để thích phiên bản thay đổi, mặc dù nó có vẻ không tự nhiên. Xem ví dụ câu trả lời này trên MathOverflow cũng như những người khác trên trang đó.
Ruslan

Câu trả lời:


8

Toán học, 17 15 27 byte

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

Đầu ra trông giống như {{x -> n}}, đâu nlà giải pháp, có thể không được phép.


7

Bình thường, 4 byte

.I.!

Một chương trình lấy đầu vào của một số và in kết quả.

Bộ kiểm tra

Làm thế nào nó hoạt động

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

Điều này sử dụng seach tuyến tính trong các bước 1e-5bắt đầu tại 1. Vì vậy, nó rất chậm và hết thời gian trong trình biên dịch trực tuyến.

Để kiểm tra nó, liên kết sau thay thế 1e-5yêu cầu độ chính xác bằng1e-2 . Hãy thử trực tuyến!

Giải trình

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]

Đã nhập vào đầu vào CAS và mong đợi đầu vào của một số trong ô bảng tính A1 . Trả về một mảng một phần tử của biểu mẫu {x = <result>}.

Đây là một gif của việc thực hiện:

Thi hành chương trình

Làm thế nào nó hoạt động

Numerically Solvephương trình sau: Gamma(x+1)=A1với bắt đầu từ giá trị x=1.


Được đảm bảo để trả về một số dương, và nó có hoạt động cho 1,5, đã phá vỡ một số câu trả lời không?
Pavel

@Pavel Tôi có thể xác nhận rằng nó hoạt động cho 1.5. Tôi chưa thể tìm ra thuật toán GeoGebra nào sử dụng để giải toán số, nhưng giá trị ban đầu x=1đã đưa ra câu trả lời hoàn toàn tích cực cho mọi giá trị tôi đã thử.
TheBikingViking

2

MATLAB, 59 byte

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

Đây là một hàm ẩn danh tìm thấy bộ giảm thiểu chênh lệch bình phương tạo ra hàm Pi và đầu vào của nó, bắt đầu từ 1, với dung sai rất nhỏ (được cho bởi eps) để đạt được độ chính xác mong muốn.

Các trường hợp thử nghiệm (chạy trên 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

Bạn có thể thử trực tuyến trên Octave, nhưng thật không may, một số kết quả thiếu độ chính xác cần thiết.


2

J, 86 33 byte

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

Sử dụng phương pháp của Newton với log Pi để tránh tràn.

Đây là phiên bản trước đó tính toán đăng nhập Gamma bằng cách sử dụng xấp xỉ của Stirling. Kích thước bước (1e3) và số lượng thuật ngữ trong nhật ký Gamma (3) có thể được tăng lên để có độ chính xác cao hơn với chi phí hiệu suất.

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

Một phiên bản khác tính toán các điều khoản hệ số khi đang bay

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

Hãy thử trực tuyến! và để xem các điều khoản hội tụ .

Giải trình

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

Toán học, 21 byte

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

FindRoot áp dụng phương pháp của Newton trong nội bộ khi có giá trị ban đầu.

Hai phương pháp dưới đây áp dụng phương pháp của Newton trực tiếp.

Thay thế bằng cách sử dụng FixedPoint 45 byte

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

Việc triển khai chính xác hơn phương pháp của Newton để giải quyết điều này vì Mathicala có thể tính đạo hàm trực tiếp thay vì xấp xỉ nó.

Sử dụng các quy tắc để thay thế nhiều lần sẽ ngắn hơn, nhưng có giới hạn (65536) đối với số lần lặp mà nó có thể thực hiện có thể bị tấn công trong khi FixedPointkhông có giới hạn.

Sử dụng quy tắc thay thế, 38 byte

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

Hình ảnh


1

Thạch , 34 byte

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

Hãy thử trực tuyến! hoặc Xem các giá trị trung gian khi chúng hội tụ .

An thực hiện sự kết hợp của phương pháp Newton và xấp xỉ hàm (phương pháp cát tuyến) J để tính nghịch đảo của Π ( n ).

Nó giải quyết cho nghịch đảo của log ( Π ( n )) để tránh tràn.

Nó bắt đầu với một đoán ban đầu x 0 = y 1 nơi y = log ( Π ( n )). Sau đó, nó lặp đi lặp lại cho đến khi hội tụ bằng x n +1 = x n - (log ( Π ( x n )) - y ) / (log (( Π (1.001 * x n )) - log ( Π ( x n ))) / (0,001 * x n )).


3
Tôi gặp lỗi với đầu vào1.5
Luis Mendo

@LuisMendo Wow đó là một bắt tốt! Nó xảy ra do một trong các giá trị trung gian là ~ 65807, đây là một giá trị rất lớn sau khi gamma được áp dụng và Python tràn ra. Điều tương tự xảy ra trong J vì nó dựa trên cùng một tính toán.
dặm

1

PARI / GP, 30 byte

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

Tìm giải pháp giữa 1x+1. Thật không may, xkhông đủ lớn vì giới hạn trên cho đầu vào như thế nào 1.5.


1

Toán học, 26 byte

Một giải pháp Mathicala khác!

Giải phương trình luôn có thể được biến thành một vấn đề tối thiểu hóa.

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

Tìm đối số giảm thiểu sự khác biệt giữa bên trái và bên phải của phương trình.

Sử dụng NArgMin thay vì NMinizing buộc đầu ra chỉ là kết quả mong muốn thay vì đầu ra dựa trên quy tắc dài dòng thông thường (và nó tiết kiệm một byte!)


0

C với libm, 111

Cập nhật - cố định cho đầu vào 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)là một hàm tăng đơn điệu trong phạm vi được đề cập, shis chỉ là một tìm kiếm nhị phân cho đến khi sự khác biệt giữa các giá trị liên tiếp là nhỏ. Giới hạn dưới bắt đầu là 0và giới hạn trên bắt đầu là2*x .

Đầu vào và đầu ra là thông qua một con trỏ đến một đôi được truyền cho hàm.

Tôi khá chắc chắn rằng điều này có thể được chơi golf sâu hơn - đặc biệt tôi không nghĩ rằng tôi cần 4 cú đúp địa phương, nhưng cho đến nay tôi không thấy một cách dễ dàng để giảm điều này.

Dùng thử trực tuyến - Bản dựng (liên kết với libm) và chạy trong tập lệnh bash.

Nhẹ nhàng vô duyên:

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;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.