P i = = 3. 2

37

Terinspirasi oleh video Seri Infinite ini .

pengantar

Pi didefinisikan sebagai rasio keliling dengan diameter lingkaran. Tetapi bagaimana sebuah lingkaran didefinisikan? Biasanya sebuah lingkaran didefinisikan sebagai titik-titik dengan jarak konstan ke titik tengah (mari kita asumsikan bahwa pusat berada pada (0,0)). Pertanyaan selanjutnya adalah: Bagaimana kita menentukan jarak ? Berikut ini kami sedang mempertimbangkan gagasan jarak yang berbeda (diinduksi oleh Lp-norms):

Diberi norma (= sesuatu yang mengukur panjang ) kita dapat dengan mudah membuat jarak (= jarak antara dua titik) sebagai berikut:

dist(A,B) := norm (A-B)

Norma euclidean diberikan oleh:

norm((x,y)) = (x^2 + y^2)^(1/2)

Ini juga disebut norma-L2 . Norma Lp lainnya dibangun dengan mengganti 2rumus di atas dengan nilai lain antara 1 dan tak hingga:

norm_p((x,y)) = (|x|^p + |y|^p)^(1/p)

Lingkaran unit untuk norma-norma yang berbeda memiliki bentuk yang sangat berbeda:

Tantangan

Diberikan a p >= 1, hitung rasio keliling terhadap diameter lingkaran-Lp sehubungan dengan Lp-norm dengan akurasi empat angka signifikan.

Testcases

Kita bisa menggunakannya untuk p,qdengan 1 = 1/p + 1/qkita mendapatkan rasio yang sama untuk Lpserta Lqnorma. Selanjutnya untuk p = q = 2rasionya minimal, dan untuk p = 1, q = infinitykita dapatkan rasio 4, sehingga rasio selalu antara pidan 4.

p   or  q            ratio
1       infinity     4
2       2            3.141592
1.623   2.60513      3.200
1.5     3            3.25976
4       1.33333      3.39693
cacat
sumber
2
Bentuknya dikenal sebagai kurva Lamé atau superellipses dan ada untuk 0 < p <1 juga, meskipun norma itu sendiri tidak (karena melanggar ketimpangan segitiga). Artikel Wikipedia untuk superellipse menyertakan formulir tertutup untuk area tersebut.
Neil
@Neil Namun kita perlu mempertimbangkan keliling, bukan area, yang - sejauh yang saya tahu - hanya dapat dihitung melalui integral panjang busur.
flawr
7
Maaf, pada saat saya selesai membaca tentang mereka, saya sudah lupa apa pertanyaannya.
Neil
2
Tantangan yang indah!
Luis Mendo
1
Sangat menarik untuk dicatat bahwa rumus area ( A = πr²) tidak berlaku untukp ≠ 2
Mego

Jawaban:

12

Python + scipy, 92 byte

from scipy.integrate import*
lambda p:2/p*quad(lambda x:(x/x**p+(1-x)**(1-p))**(1/p),0,1)[0]

Formula berasal dari pertanyaan math.SE ini .

orlp
sumber
Ketika menguji implementasi dengan appraoch ini saya mengalami masalah dengan konvergensi pendekatan itu, karena singularitas di x=1, bagaimana kiriman Anda lakukan?
flawr
Scipy bukan bagian dari pustaka standar Python. Mungkin beralih ke Sage?
busukxuan
2
@busukxuan Tidak ada persyaratan pada PPCG yang memungkinkan Anda untuk hanya menggunakan perpustakaan standar. Tapi saya akan menyebutkannya dalam judul.
orlp
1
@ChristianSievers Saya melakukan integrasi saya sendiri untuk menghindari perasaan tidak enak karena menggunakan formula tertutup orang lain :-P
Luis Mendo
1
@ChristianSievers Saya sebenarnya juga menyertakan formla lain di kotak pasir, jika Anda tertarik =)
flawr
10

MATL , 31 byte

0:1e-3:1lyG^-lG/^v!d|G^!slG/^sE

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

Ini menghasilkan koordinat x , y dari seperempat lingkaran unit yang diambil sampelnya pada 1001 poin dengan langkah 0,001 dalam x . Panjang seperempat lingkaran didekati oleh garis poligon yang melewati titik-titik tersebut; yaitu jumlah dari panjang 1000 segmen. Panjangnya tentu saja dihitung menurut p-norm. Mengalikan hasilnya dengan 2 memberikan perkiraan panjang setengah lingkaran, yaitu, pi.

0:1e-3:1   % Push [0 0.001 0.002 ... 0.999 1]. These are the x coordinates of
           % the vertices of the polygonal line that will approximate a quarter
           % of the unit circle
l          % Push 1
y          % Duplicate [0 0.001 0.002 ... 0.999 1] onto the top of the stack.
G          % Push input, p
^          % Element-wise power: gives [0^p 0.001^p ... 1^p]
-          % Element-wise subtract from 1: gives [1-0^p 1-0.001^p ... 1-1^p]
lG/        % Push 1, push p, divide: gives 1/p
^          % Element-wise power: gives [(1-0^p)^(1/p) (1-0.001^p)^(1/p) ...
           % ... (1-1^p)^(1/p)]. These are the y coordinates of the vertices
           % of the polygonal line
v          % Concatenate vertically into a 2×1001 matrix. The first row contains
           % the x coordinates and the second row contains the y coordinates
!          % Transpose
d|         % Compute consecutive differences down each column. This gives a
           % 1000×2 matrix with the x and y increments of each segment. These
           % increments will be referred to as Δx, Δy
G          % Push p
^          % Element-wise power
!          % Transpose
s          % Sum of each column. This gives a 1×1000 vector containing
           % (Δx)^p+(Δy)^p for each segment
lG/        % Push 1/p
^          % Element-wise power. This gives a 1×1000 vector containing 
           % ((Δx)^p+(Δy)^p)^(1/p) for each segment, that is, the length of 
           % each segment according to p-norm
s          % Sum the lenghts of all segments. This approximates the length of
           % a quarter of the unit circle
E          % Multiply by 2. This gives the length of half unit circle, that is,
           % pi. Implicitly display
Luis Mendo
sumber
8

Mathematica, 49 46 byte

3 byte disimpan karena alephalpha .

2NIntegrate[(1+(a^-#-1)^(1-#))^(1/#),{a,0,1}]&

Fungsi anonim. Mengambil nomor sebagai input dan mengembalikan nomor sebagai output.

LegionMammal978
sumber
1
2NIntegrate[(1+(a^-#-1)^(1-#))^(1/#),{a,0,1}]&
alephalpha
5

PARI / GP, 48 43 byte

Mudah setelah @orlp menemukan formula, dan versi @ alephalpha menghemat 5 byte:

p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p))

Untuk menambahkan sesuatu yang sedikit berguna, mari kita hitung pyang kita dapat 3.2:

? f=p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p));
? solve(p=1,2,f(p)-3.2)
%2 = 1.623002382384469009676324702

Penggunaan yang benar

Sementara kode memberikan hasil yang jauh lebih tepat daripada permintaan tantangan, kode dapat dengan mudah ditingkatkan banyak: jika kita mengganti batas integrasi atas 1dengan [1,1/p-1](memberikan apa yang manual sebut sebagai eksponen singularitas) maka semua angka yang ditampilkan f(2)setuju dengan Pi. Ini masih benar jika kita meningkatkan presisi hingga 100 (tipe \p100).

Namun, setelah perubahan bahwa solveperhitungan tidak lagi bekerja. Saya mengubah istilah dalam untuk secara eksplisit menangani kasus ini u=0dan juga mengubah ke komputer yang berbeda dengan versi PARI yang lebih baru dan 64 bit (yang menyiratkan presisi standar yang lebih tinggi).

Ini adalah perhitungan peningkatan pnilai untuk Pi=3.2, dan mari kita lihat Pi nyata:

? f=p->2*intnum(u=0,[1,1/p-1],if(u,(1+(u^-p-1)^(1-p))^(1/p),0));
? f(2)
%2 = 3.1415926535897932384626433832795028842
? Pi
%3 = 3.1415926535897932384626433832795028842
? solve(p=1,2,f(p)-3.2)
%4 = 1.6230023823844690096763253745604419761
Sievers Kristen
sumber
p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p))
alephalpha
0

JavaScript (ES7), 80 byte

Berdasarkan jawaban orlp . Implementasi JS ini cukup lambat. Anda mungkin ingin mencoba i=1e-7(atau bahkan lebih tinggi) untuk perkiraan yang lebih cepat.

Catatan : Ini pada dasarnya hanya ditujukan untuk Chrome dan Edge. Versi ES6 yang setara menggunakan Math.pow()Firefox 50.1 tampaknya jauh lebih lambat.

Sunting : Menurut Neil, ini juga akan berfungsi dengan baik di Firefox 52.

f=
p=>{for(i=5e-8,s=x=0;(x+=i)<1;)s+=i*(x**(1-p)+(1-x)**(1-p))**(1/p);return 2/p*s}

console.log(f(1).toFixed(3))
console.log(f(2).toFixed(3))
console.log(f(1.623).toFixed(3))

Arnauld
sumber
Versi ES7 tampak cukup sigap ketika saya mencobanya menggunakan Firefox 52 (saya tidak mengukurnya secara ilmiah, tetapi rasanya dengan kecepatan yang sama dengan Chrome; Edge membeku pada saya).
Neil
@Neil Terima kasih atas tanggapan Anda. Diperbarui sesuai.
Arnauld