Лотарингія Кіче [закрито]


52

Так як це було Pi день в останній час , я помітив на ряд з проблем , які просять вас обчислити пі.

Звичайно, лоррайн з кішею - це не зовсім пиріг (ви можете претендувати на бонусний бал ¹ +1, якщо ви здогадалися на виклику поза заголовком). Таким чином, ваше завдання полягає в тому, щоб написати алгоритм або метод , схожий на те, що він наближається до Pi на перший погляд, але гарантовано не зближується з Pi.

Це непродумане завдання, тому переконайтеся, що він виведе 3.14 ... для простого тестового випадку, наприклад, з 10 ітерацій вашого алгоритму. Це також є проблемою для популярності, тому не варто шукати очевидних echo(pi)і кажіть, що плаваюча точка IEEE 754 округляє деякі цифри вгору або вниз.

Переможець отримує лоррайн quiche².

¹ Попередження: насправді не бонусний бал. Стверджуючи рахунок, ви погоджуєтесь спекти мені пиріг до Пі Дня 2016 року

² Попередження: лотарингія кіче використовується як метафора для того, щоб ваша відповідь була позначена як "прийнята"



2
Я голосую за те, щоб закрити це питання поза темою, оскільки обґрунтовані виклики вже не є темою. meta.codegolf.stackexchange.com/a/8326/20469
кіт

Відповіді:


77

Алгоритм

Використовуючи відомий результат:

введіть тут опис зображення

ми визначаємо в Python 3:

from math import sin
from functools import reduce
from operator import mul

def integrate(f, a, b, n):
   h = (b-a)/n
   i = h * sum(f(a+i*h+h/2) for i in range(n))
   return i

def sinc(x):
   return sin(x)/x

def borwein(n):
   def f(x):
     g = lambda i: sinc(x/(2*i+1))
     return reduce(mul, map(g, range(n)), 1)
   return f

Тестування

>>> for i in range(1,10):
...   pi = 2 * integrate(borwein(i), 0, 1000, 1000)
...   print("x[{}] = {}".format(i, pi))
x[1] = 3.140418050361841
x[2] = 3.141593078648859
x[3] = 3.1415926534611547
x[4] = 3.1415926535957164
x[5] = 3.1415926535895786
x[6] = 3.1415926535897953
x[7] = 3.1415926535897936
x[8] = 3.1415926535435896 # ???
x[9] = 3.141592616140805  # ?!!

Спойлер

Інтеграл Borwein є ідеєю Матх практичної жарти. Хоча особистість, наведена вище, має значення sinc (x / 13), наступне значення насправді:

введіть тут опис зображення


12
Напевно, одна з найкращих відповідей на непродумане питання останнім часом.
Оптимізатор

14
"математична ідея практичного жарту". +1
нечисте м'ясо

16
Це добре! IIRC, один з найвідоміших жартів з цим інтегралом, коли хтось записував результати до дивних на Wolfram Alpha, і надсилав звіт про помилку ... На який
бійці

3
Ця довідка дає хороше пояснення того, що відбувається.
TonioElGringo

59

Щоб знайти pi, ми інтегруємо це добре відоме диференціальне рівняння:

> dy / dt = sin (y) * exp (t)

З початковою умовою

> 0 <y0 <2 * пі

Добре відомо, що ця задача початкового значення сходиться до π, оскільки t зростає без обмежень. Отже, все, що нам потрібно, - це почати з розумної здогадки щодо чогось між 0 і 2π, і ми можемо виконати числову інтеграцію. 3 близький до π, тому для початку виберемо y = 3.

class PiEstimator {

    static final int numSteps = 100;
    static final double dt = 0.1, tMax = numSteps * dt;

    static double f(double y, double t){ return Math.sin(y) * Math.exp(t); }

    public static void main(String[] args){
        double y = 3;
        int n = 0;

        for(double t = 0; t < tMax; t+=dt){
            if(n%5 == 0) System.out.println(n + ": " + y);
            n++;
            y += f(y,t)*dt;
        }
    }
}

Ось декілька результатів на кожному етапі:

0: 3.0
5: 3.0682513992369205
10: 3.11812938865782
15: 3.1385875952782825
20: 3.141543061526081
25: 3.141592653650948
30: 3.1415926535886047
35: 3.1415926535970526
40: 3.1415926517316737  // getting pretty close!
45: 3.1416034165087647  // uh oh
50: 2.0754887983317625  
55: 49.866227663669584
60: 64.66835482328707
65: 57.249212987256286
70: 9.980977494635624
75: 35.43035516640032
80: 51.984982646834
85: 503.8854575676292
90: 1901.3240821223753
95: 334.1514462091029
100: -1872.5333656701248

Як це працює:

Це диференціальне рівняння добре відомо, тому що його вкрай складно правильно інтегрувати. Хоча для малих значень t наївна інтеграція дасть прийнятні результати, більшість методів інтеграції виявляють надзвичайну нестабільність, оскільки t стає дуже великою.


4
@UriZarfaty Ця стаття у Вікіпедії досить добре пояснює це: en.wikipedia.org/wiki/Stiff_equation
AJMansfield

1
Що таке n? ...
Коул Джонсон

1
@AJMansfield Я мав на увазі: це ніде не оголошено. Ваша forуповільнення використовує t, але використовує ваш цикл n.
Коул Джонсон

1
@ColeJohnson я щойно це виправив.
AJMansfield

2
Я думаю, що ваше диференціальне рівняння повинне читати dy / dt = sin (y) * exp (t).
Девід Чжан

6

Код:

var pi = function(m) {
  var s2 = 1, s1 = 1, s = 1;
  for (var i = 0; s >= 0; ++i) {
    s = s1 * 2 - s2 * (1 + m*m);
    s2 = s1;
    s1 = s;
  }
  return i*m*2;
};

Я в основному виявив цю послідовність випадково. Він починається так, як 1, 1і кожен термін після цього s(n)задається s(n) = 2*s(n - 1) - s(n - 2) * (1 + m*m). Кінцевий результат - найменший nтакий, що s(n) < 0множиться на 2m. Оскільки mстає менше, воно повинно ставати все більш точним.

pi(1/100) --> 3.14
pi(1/1000) --> 3.14
pi(1/10000) --> 3.1414
pi(1/100000) --> 3.14158
pi(1/1000000) --> 3.141452 // what?
pi(1/10000000) --> 3.1426524 // .. further away from pi

Я впевнений, що це помилки з плаваючою комою, оскільки (1 + m*m)наближається до однієї, але я не впевнений. Як я вже сказав, я натрапив на це випадково. Я не впевнений у його офіційній назві. Не намагайтеся зробити це з mдуже маленьким або він буде працювати вічно (якщо 1 + m*m == 1з - за mте , що так мало).

Якщо хтось знає назву цієї послідовності або чому вона поводиться так, я би вдячний.


Я думаю, це пов’язано з скасуванням, що є втратою цифр при відніманні двох майже рівних чисел. S1 і s2 майже однакові після ітерації.
Санчіз

1
Я ще не з'ясував, як це працює, але це нагадує мені про те, що я колись робив: я неодноразово брав сукупну суму галасливого сигналу і нормалізував його до значення 0, максимальне значення 1. Це призведе до синусоїди, оскільки це єдиний сигнал, який є власною антивиробничою (зі зміщенням фази).
Санчіз

Я запитав це на math.SE, і отримав цю відповідь.
Санчіз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.