P i = = 3. 2


37

Натхненний цим відео з нескінченної серії .

Вступ

Pi визначається як відношення окружності до діаметру кола. Але як визначається коло? Зазвичай коло визначають як точки, що мають постійну відстань до центральної точки (припустимо, що центр знаходиться у (0,0)). Наступне питання буде: Як ми визначаємо відстань ? Далі ми розглядаємо різні поняття відстаней (індуковані Lp-нормами):

Враховуючи норму (= щось, що вимірює довжину ), ми можемо легко побудувати відстань (= відстань між двома точками) наступним чином:

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

Евклідова норма задається:

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

Це також називається L2-нормою . Інші Lp-норми будуються шляхом заміни 2наведеної вище формули іншими значеннями від 1 до нескінченності:

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

Одиничні кола для цих різних норм мають досить чіткі форми:

Виклик

З огляду на a p >= 1, обчисліть відношення окружності до діаметру Lp-кола відносно Lp-norm з точністю до чотирьох значущих цифр.

Тестові шафи

Ми можемо скористатися тим, що за p,qдопомогою 1 = 1/p + 1/qми отримаємо однакове співвідношення Lpяк Lqнорма, так і норма. Крім того, для p = q = 2цього співвідношення мінімально, і для p = 1, q = infinityнас виходить співвідношення 4, тому співвідношення завжди між piі 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

2
Форми відомі як криві Ламе або суперреліпси і існують для 0 < p <1, навіть якщо сама норма цього не робить (оскільки це порушує нерівність трикутника). Стаття у Вікіпедії про суперреліпс включає закриту форму для цієї області.
Ніл

@Neil Нам все ж потрібно враховувати окружність, а не площу, яку - наскільки я знаю - можна обчислити лише через інтеграл довжини дуги.
недолік

7
Вибачте, до того часу, коли я закінчив їх читати, я забув, про що ставив запитання.
Ніл

2
Прекрасний виклик!
Луїс Мендо

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]

Формула - це питання з математики .


Під час тестування реалізації цього додатка у мене виникли проблеми з конвергенцією такого підходу через особливості x=1, як відбувається ваше подання?
недолік

Scipy не входить до стандартної бібліотеки Python. Може, перейти на Sage?
busukxuan

2
@busukxuan Не існує вимог щодо PPCG, яка дозволяє використовувати лише стандартні бібліотеки. Але я все одно згадаю його у назві.
orlp

1
@ChristianSievers Я зробив власну інтеграцію, щоб уникнути поганого використання чужої закритої формули :-P
Луїс Мендо

1
@ChristianSievers Я фактично також включив ще одну формулу в пісочницю, якщо вам це цікаво =)
недолік

10

MATL , 31 байт

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

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

Це генерує координати x , y однієї чверті одиничного кола, відібраного в 1001 балах, з кроком 0,001 в x . Довжина чверті кола апроксимується довжиною багатокутної лінії, яка проходить через ці точки; тобто сума довжин 1000 відрізків. Довжина, звичайно, обчислюється відповідно до p-norm. Помноження результату на 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

Математика, 49 46 байт

3 байти збережено завдяки алефальфі .

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

Анонімна функція. Бере число як вхід і повертає число як вихід.


1
2NIntegrate[(1+(a^-#-1)^(1-#))^(1/#),{a,0,1}]&
алефальфа

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))
алефальфа

0

JavaScript (ES7), 80 байт

На основі відповіді orlp . Це впровадження СВ досить повільне. Ви можете спробувати i=1e-7(або навіть вище) для швидшого наближення.

Примітка . В основному це призначено лише для Chrome і Edge. Еквівалентна версія ES6, що використовується Math.pow()в Firefox 50.1, здається, набагато повільніше.

Редагувати : За словами Ніла, це також має чудово працювати на 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 Дякую за відгук. Оновлено відповідно.
Арнольд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.