P i = = 3. 2

37

Inspirado en este video de la serie Infinite .

Introducción

Pi se define como la relación de la circunferencia al diámetro de un círculo. Pero, ¿cómo se define un círculo? Por lo general, un círculo se define como los puntos con distancia constante al punto central (supongamos que el centro está en (0,0)). La siguiente pregunta sería: ¿Cómo definimos la distancia ? A continuación estamos considerando diferentes nociones de distancias (inducidas por las Lpnormas):

Dada una norma (= algo que mide una longitud ) podemos construir fácilmente una distancia (= distancia entre dos puntos) de la siguiente manera:

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

La norma euclidiana viene dada por:

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

Esto también se llama la norma L2 . Las otras normas Lp se construyen reemplazando el 2en la fórmula anterior por otros valores entre 1 e infinito:

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

Los círculos unitarios para esas diferentes normas tienen formas bastante distintas:

Reto

Dado a p >= 1, calcule la razón de la circunferencia al diámetro de un círculo Lp con respecto a la Lpforma con una precisión de cuatro cifras significativas.

Casos de prueba

Podemos utilizarlo para p,qcon 1 = 1/p + 1/qobtenemos la misma proporción para el Lp, así como la Lqnorma. Además, para p = q = 2la relación es mínima, y ​​para p = 1, q = infinityobtener una relación de 4, las relaciones son siempre entre piy 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
falla
fuente
2
Las formas se conocen como curvas de Lamé o superelipses y existen para 0 < p <1 también, aunque la norma en sí no lo hace (porque viola la desigualdad del triángulo). El artículo de Wikipedia para el superellipse incluye un formulario cerrado para el área.
Neil
@Neil Sin embargo, debemos considerar la circunferencia, no el área, que, que yo sepa, solo se puede calcular a través de una integral de longitud de arco.
flawr
77
Lo siento, cuando terminé de leerlos, había olvidado lo que había preguntado.
Neil
2
Desafío encantador!
Luis Mendo
1
Es interesante observar que la fórmula del área ( A = πr²) no se cumple parap ≠ 2
Mego

Respuestas:

12

Python + scipy, 92 bytes

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

La fórmula es de esta pregunta matemática .

orlp
fuente
Cuando probé una implementación con este enfoque, tuve problemas con la convergencia de ese enfoque, debido a la singularidad en x=1, ¿cómo funciona su presentación?
flawr
Scipy no es parte de la biblioteca estándar de Python. ¿Quizás cambiar a Sage?
busukxuan
2
@busukxuan No hay ningún requisito en PPCG que le permita usar solo bibliotecas estándar. Pero lo mencionaré en el título de todos modos.
orlp
1
@ChristianSievers Hice mi propia integración para evitar sentirme mal por usar la fórmula cerrada de otra persona :-P
Luis Mendo
1
@ChristianSievers De hecho, también incluí otra fórmula en el sandbox, en caso de que estés interesado =)
error
10

MATL , 31 bytes

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

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Esto genera las coordenadas x , y de un cuarto del círculo unitario muestreado en 1001 puntos con el paso 0.001 en x . La longitud del cuarto de círculo se aproxima por la de la línea poligonal que pasa por esos puntos; es decir, la suma de las longitudes de los 1000 segmentos. La longitud, por supuesto, se calcula de acuerdo con p-norm. Multiplicar el resultado por 2 da la longitud aproximada de medio círculo, es decir, 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
fuente
8

Mathematica, 49 46 bytes

3 bytes guardados debido a alephalpha .

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

Función anónima. Toma un número como entrada y devuelve un número como salida.

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

PARI / GP, 48 43 bytes

Es fácil después de que @orlp haya encontrado la fórmula, y la versión de @ alephalpha ahorra 5 bytes:

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

Para agregar algo ligeramente útil, calculemos ppara qué obtenemos 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

Uso Correcto

Si bien el código proporciona resultados que son mucho más exactos de lo que exige el desafío, puede mejorarse mucho fácilmente: si reemplazamos el límite superior de integración 1 con [1,1/p-1](dando lo que el manual llama el exponente de singularidad), todos los dígitos mostrados f(2)están de acuerdo Pi. Esto sigue siendo cierto si aumentamos la precisión a 100 (tipo \p100).

Sin embargo, después de ese cambio, el solvecálculo ya no funcionó. Cambié el término interno para manejar explícitamente el casou=0 y también cambié a una computadora diferente con una versión PARI más nueva y 64 bits (lo que implica una mayor precisión predeterminada).

Aquí está el cálculo mejorado del pvalor de Pi=3.2, y también echemos un vistazo al Pi real:

? 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
Christian Sievers
fuente
p->2*intnum(u=0,1,(1+(u^-p-1)^(1-p))^(1/p))
alephalpha
0

JavaScript (ES7), 80 bytes

Basado en la respuesta de orlp . Esta implementación de JS es bastante lenta. Es posible que desee probar i=1e-7(o incluso más) para una aproximación más rápida.

Nota : Esto está destinado básicamente para Chrome y Edge solamente. Una versión ES6 equivalente que se usa Math.pow()en Firefox 50.1 parece ser mucho más lenta.

Editar : según Neil, esto también debería funcionar bien en 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
fuente
La versión ES7 parecía bastante viva cuando lo probé usando Firefox 52 (no lo medí científicamente, pero me pareció la misma velocidad que Chrome; Edge se congeló en mí).
Neil
@Neil Gracias por sus comentarios. Actualizado en consecuencia.
Arnauld