Spigot алгоритм

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску

Spigot Алгоритм (упоминается также как "алгоритм крана", или, что более точно, "алгоритм затвора", так как его работа похожа на движение затвора автомата, выбрасывающего очередной патрон) — алгоритм вычисления значения математических констант, например или e, который позволяет определить цифры в некоторой заранее выбранной системе счисления (обычно двоичной или с основанием в виде степени двойки) слева направо. Название происходит от английского слова "spigot", означающего кран или вентиль для управления потоком жидкости.

Интерес к Spigot алгоритму усилился в период раннего развития вычислительной математики из-за жестких ограничений на объемы памяти. Первый подобный алгоритм вычисления знаков числа e встречается в работе Артура Сейла (Arthur Harry John Sale) 1986 года[1]. Название "Spigot алгоритм" скорее всего придумали Стенли Рабинович и Стен Вагон[2].

Алгоритм предложенный Рабиновичем и Вагоном ограниченный в том смысле, что количество вычисляемых знаков должно быть определено заранее. Джереми Гиббонс (Jeremy Gibbons) в 2004г вводит обобщение под названием "потоковый алгоритм"[3], в котором вычисления можно проводить бесконечно долго, тем самым убрав ограниченность исходного алгоритма. Ещё одним улучшением Spigot алгоритма стал алгоритм, позволяющий вычислить конкретный знак без необходимости определения предыдущих знаков числа. Например, Формула Бэйли-Боруэйна-Плаффа для вычисления произвольных знаков в 16-ричной записи числа .

Пример[править | править код]

Продемонстрируем работу Spigot алгоритма на примере вычисления двоичных знаков натурального логарифма 2 на основе формулы:

Чтобы найти двоичные знаки начиная с 8-го, умножим число на 27 (так как 7=8-1):

Затем разделим бесконечный ряд на "голову", в которой степень двойки больше или равна нулю, и "хвост" с отрицательными степенями:

Нас интересует только дробная часть этого значения, поэтому мы заменяем каждое слагаемое в первой сумме ("голове") на:

Вычислим каждое слагаемое отдельно, отбрасывая целую часть:

k A = 27−k B = A (mod k) C = B / k C (mod 1)
1 64 0 0 0
2 32 0 0 0
3 16 1 1/3 1/3
4 8 0 0 1/3
5 4 4 4/5 2/15
6 2 2 1/3 7/15
7 1 1 1/7 64/105

Вычислим несколько первых элементов из "хвоста". Выбираем такую часть этой суммы, чтобы ошибка вычисления была меньше искомого 7-го знака числа.

k D = 1/k2k−7 D Макс. ошибка
8 1/16 1/16 1/16
9 1/36 13/144 1/36
10 1/80 37/360 1/80

Суммируя "голову" и несколько первых элементов "хвоста" мы получим:

таким образом цифры с 8-й по 11-ю в двоичной записи числа являются 1, 0, 1, 1. Заметьте, что мы не вычисляли значения предыдущих семи цифр. Информация об этих цифрах была умышленно отброшена при использовании модульной арифметики при вычислении "головы".

Данный подход можно использовать для вычисления произвольного n-го знака в двоичной записи числа ln(2). Количество слагаемых в "голове" линейно растёт с увеличением n, но сложность вычисления элементов растёт логарифмически при использовании методов возведения в степень по модулю. Точность вычисления, промежуточные вычисления и количество нужных слагаемых из "хвоста" не зависят от n, а зависят только от количества двоичных знаков, которые нужно вычислить. Используя дробные числа одинарной точности можно найти около 12 двоичных знаков, независимо от начальной позиции.

Примечания[править | править код]

  1. Sale, AHJ. The calculation of e to many significant digits (англ.) // The Computer Journal (англ.) : journal. — 1968. — Vol. 11, no. 2. — P. 229—230. — doi:10.1093/comjnl/11.2.229.
  2. Rabinowitz, Stanley; Wagon, Stan. A Spigot Algorithm for the Digits of Pi (англ.) // American Mathematical Monthly : journal. — 1995. — Vol. 102, no. 3. — P. 195—203. — doi:10.2307/2975006.
  3. Gibbons, Jeremy Unbounded Spigot Algorithms for the Digits of Pi (24 мая 2004).

Ссылки[править | править код]