P i = = 3, 2

37

Вдохновлен этим видео из серии Infinite .

Введение

Пи определяется как отношение длины окружности к диаметру круга. Но как определяется круг? Обычно круг определяется как точки с постоянным расстоянием до центральной точки (предположим, что центр находится в (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-нормы с точностью до четырех значащих цифр.

Testcases

Мы можем использовать это для 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
flawr
источник
2
Формы известны как кривые Ламе или суперэллипсы и существуют также для 0 < p <1, хотя сама норма этого не делает (потому что это нарушает неравенство треугольника). Статья Wikipedia для суперэллипса включает закрытую форму для области.
Нил
@Neil Однако нам нужно учитывать окружность, а не площадь, которую, насколько я знаю, можно рассчитать только через интеграл длины дуги.
flawr
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]

Формула из этого математического вопроса .

orlp
источник
При тестировании реализации с этим appraoch у меня были проблемы с конвергенцией этого подхода, из-за особенностей в x=1том, как ваша заявка делает?
flawr
Scipy не является частью стандартной библиотеки Python. Может быть, переключиться на Sage?
Busukxuan
2
@busukxuan Для PPCG не существует требований, позволяющих использовать только стандартные библиотеки. Но я все равно упомяну это в названии.
orlp
1
@ChristianSievers Я сделал свою собственную интеграцию, чтобы не чувствовать себя плохо из-за использования чужой закрытой формулы :-P
Луис Мендо
1
@ChristianSievers Я на самом деле также включил еще одну форму в песочнице, на случай, если вам интересно =)
flawr
10

MATL , 31 байт

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

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

Это создает координаты x , y одной четверти единичного круга, отобранного в 1001 точке с шагом 0,001 в x . Длина четверти круга аппроксимируется длиной многоугольной линии, проходящей через эти точки; то есть сумма длин 1000 сегментов. Длина, конечно, рассчитывается в соответствии с p-norm. Умножение результата на 2 дает приблизительную длину полукруга, то есть пи.

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 байта сохранены благодаря алефалии .

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

Анонимная функция. Принимает число в качестве ввода и возвращает число в качестве вывода.

LegionMammal978
источник
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))
алефальфа
0

JavaScript (ES7), 80 байт

Основано на ответе orlp . Эта реализация JS довольно медленная. Вы можете попробовать 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))

Arnauld
источник
Версия ES7 выглядела довольно бодро, когда я попробовал ее с помощью Firefox 52 (я не измерял ее с научной точки зрения, но он чувствовал себя примерно с той же скоростью, что и Chrome; Edge застыл на мне).
Нил
@Neil Спасибо за ваш отзыв. Обновлен соответственно.
Arnauld