P i = = 3. 2


37

แรงบันดาลใจจากวิดีโอชุด Infiniteนี้

บทนำ

Pi หมายถึงอัตราส่วนของเส้นรอบวงกับเส้นผ่านศูนย์กลางของวงกลม แต่วงกลมถูกกำหนดอย่างไร? โดยปกติวงกลมจะถูกกำหนดให้เป็นจุดที่มีระยะทางคงที่ถึงจุดกึ่งกลาง (ให้เราสมมติว่าจุดศูนย์กลางอยู่ที่(0,0)) คำถามต่อไปคือ: เราจะกำหนดระยะทางได้อย่างไร ในเรื่องต่อไปนี้เรากำลังพิจารณาแนวคิดเกี่ยวกับระยะทางที่แตกต่างกัน (เกิดจากLp-norms):

รับค่าปกติ (= บางอย่างที่วัดความยาว ) เราสามารถสร้างระยะทางได้อย่างง่ายดาย(= ระยะห่างระหว่างจุดสองจุด) ดังนี้:

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

บรรทัดฐานยูคลิดให้โดย:

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

นี้เรียกว่ายังL2 บรรทัดฐาน Lp-normsอื่น ๆถูกสร้างขึ้นโดยแทนที่2ในสูตรข้างต้นด้วยค่าอื่น ๆ ระหว่าง 1 ถึงอนันต์:

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

วงกลมหน่วยสำหรับบรรทัดฐานที่ต่างกันเหล่านั้นมีรูปร่างที่ค่อนข้างแตกต่างกัน

ท้าทาย

รับp >= 1, คำนวณอัตราส่วนของเส้นรอบวงกับเส้นผ่านศูนย์กลางของLp-circleเทียบกับLp-norm ด้วยความแม่นยำของตัวเลขสี่ตัวที่สำคัญ

Testcases

เราสามารถใช้สิ่งนั้นp,qด้วยเมื่อ1 = 1/p + 1/qเราได้อัตราส่วนLpเท่ากันกับค่าLqปกติ นอกจากนี้สำหรับp = q = 2อัตราส่วนที่น้อยที่สุดและp = 1, q = infinityเราได้รับอัตราส่วน 4 ดังนั้นอัตราส่วนอยู่เสมอระหว่างและpi4

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

2
รูปร่างเป็นที่รู้จักกันในชื่อLamé curves หรือ superellipses และมีค่าเป็น 0 < p <1 เหมือนกันถึงแม้ว่าบรรทัดฐานนั้นจะไม่ได้ (เพราะมันละเมิดความไม่เท่าเทียมกันของสามเหลี่ยม) บทความ Wikipedia สำหรับ superellipse รวมถึงแบบฟอร์มปิดสำหรับพื้นที่
Neil

@ Neil เราต้องพิจารณาถึงเส้นรอบวงไม่ใช่พื้นที่ซึ่งเท่าที่ฉันรู้สามารถคำนวณได้จากอินทิกรัลความยาวส่วนโค้ง
ข้อบกพร่อง

7
ขออภัยตามเวลาที่ฉันได้อ่านพวกเขาฉันลืมไปแล้วว่าคำถามที่ถามมา
Neil

2
ความท้าทายที่น่ารัก!
Luis Mendo

1
เป็นที่น่าสนใจที่จะทราบว่าสูตรพื้นที่ ( A = πr²) ไม่ถือp ≠ 2
Mego

คำตอบ:


12

Python + scipy, 92 ไบต์

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

สูตรมาจากคำถาม math.SEนี้


เมื่อทดสอบการใช้งานกับการประเมินผลนี้ฉันมีปัญหากับการบรรจบกันของวิธีการดังกล่าวเนื่องจากภาวะเอกฐานที่x=1การส่งของคุณจะทำอย่างไร
ข้อบกพร่อง

Scipy ไม่ได้เป็นส่วนหนึ่งของ Python standard library อาจเปลี่ยนเป็น Sage หรือ
busukxuan

2
@busukxuan ไม่มีข้อกำหนดบน PPCG ที่อนุญาตให้คุณใช้ไลบรารีมาตรฐานเท่านั้น แต่ฉันจะพูดถึงมันในชื่อเรื่องต่อไป
orlp

1
@ChristianSievers ฉันได้รวมของตัวเองเพื่อหลีกเลี่ยงความรู้สึกไม่ดีสำหรับการใช้สูตรปิดของคนอื่น :-P
Luis Mendo

1
@ChristianSievers ที่จริงผมยังรวมถึงformla อื่นใน sandbox ในกรณีที่คุณกำลังสนใจ =)
flawr

10

MATL , 31 ไบต์

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

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

นี้สร้างx , y ที่พิกัดของหนึ่งในสี่ของวงกลมหน่วยตัวอย่างที่ 1,001 จุดที่มีขั้นตอนใน 0.001 x ความยาวของไตรมาสของวงกลมนั้นประมาณด้วยเส้นรูปหลายเหลี่ยมที่ผ่านจุดเหล่านั้น นั่นคือผลรวมของความยาวของ 1,000 ส่วน ความยาวคำนวณจากหลักสูตรตามpปกติ การคูณผลลัพธ์ด้วย 2 จะให้ความยาวประมาณครึ่งวงกลมนั่นคือ 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

8

Mathematica, 49 46 ไบต์

3 ไบต์บันทึกไว้เนื่องจากalephalpha

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

ฟังก์ชั่นไม่ระบุชื่อ รับตัวเลขเป็นอินพุตและส่งคืนตัวเลขเป็นเอาต์พุต


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

5

PARI / GP, 48 43 ไบต์

เป็นเรื่องง่ายหลังจาก @orlp พบสูตรแล้วและเวอร์ชัน @ alephalpha บันทึกได้ 5 ไบต์:

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

หากต้องการเพิ่มสิ่งที่มีประโยชน์เล็กน้อยให้ลองคำนวณสิ่งpที่เราได้รับ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

การใช้งานที่ถูกต้อง

ในขณะที่รหัสให้ผลที่มีมากขึ้นแน่นอนกว่าความต้องการความท้าทายก็สามารถจะดีขึ้นมากถ้าเราเปลี่ยนวงเงินบูรณาการบน1ด้วย[1,1/p-1](ให้สิ่งที่เรียกคู่มือสัญลักษณ์เอกพจน์) ตัวเลขแล้วแสดงให้เห็นทั้งหมดเห็นด้วยกับf(2) Piสิ่งนี้ยังคงเป็นจริงถ้าเราเพิ่มความแม่นยำเป็น 100 (ประเภท\p100)

อย่างไรก็ตามหลังจากนั้นเปลี่ยนการsolveคำนวณไม่ทำงานอีกต่อไป ฉันเปลี่ยนคำศัพท์ภายในเพื่อจัดการกับเคสอย่างชัดเจนu=0และเปลี่ยนเป็นคอมพิวเตอร์เครื่องอื่นด้วยรุ่น PARI ที่ใหม่กว่าและ 64 บิต (ซึ่งหมายถึงความแม่นยำเริ่มต้นที่สูงขึ้น)

นี่คือการคำนวณที่ได้รับการปรับปรุงให้ดีขึ้นpสำหรับค่าPi=3.2และลองดูที่ Pi จริง:

? 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

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

0

JavaScript (ES7), 80 ไบต์

ขึ้นอยู่กับคำตอบของ orlp การใช้งาน JS นี้ค่อนข้างช้า คุณอาจต้องการลองi=1e-7(หรือสูงกว่า) เพื่อให้การประมาณเร็วขึ้น

หมายเหตุ : นี้มีวัตถุประสงค์โดยทั่วไปสำหรับ Chrome และขอบเท่านั้น รุ่น ES6 เทียบเท่าใช้Math.pow()บน Firefox 50.1 น่าจะเป็นมากช้าลง

แก้ไข : ตาม Neil สิ่งนี้ควรทำงานได้ดีบน 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))


รุ่น ES7 ดูค่อนข้างสนุกสนานเมื่อฉันลองใช้ Firefox 52 (ฉันไม่ได้วัดทางวิทยาศาสตร์ แต่รู้สึกได้ถึงความเร็วเดียวกับ Chrome; Edge แข็งสำหรับฉัน)
Neil

@ Neil ขอบคุณสำหรับความคิดเห็นของคุณ อัปเดตตาม
Arnauld
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.