Оценить дзета-функцию Римана по комплексному числу

11

Вступление

Я нашел этот вопрос закрытым, потому что он был неясен, но это была хорошая идея. Я сделаю все возможное, чтобы превратить это в явный вызов.

Функция Римана Зета является специальной функцией , которая определяется как аналитическое продолжение

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

в сложную плоскость. Есть много эквивалентных формул для этого, что делает его интересным для игры в гольф.

Вызов

Напишите программу, которая принимает в качестве входных данных 2 числа с плавающей запятой (действительную и мнимую часть комплексного числа) и оценивает дзета-функцию Римана в этой точке.

правила

  • Ввод и вывод через консоль ИЛИ функция ввода и возврата значения
  • Встроенные комплексные числа не допускаются, используйте числа с плавающей точкой (число, двойные, ...)
  • Никаких математических функций, кроме функций с + - * / pow logреальными значениями триггеров (если вы хотите интегрировать, используйте гамма-функцию, ... вы должны включить это определение функций в код)
  • Ввод: 2 поплавка
  • Выход: 2 поплавка
  • Ваш код должен содержать значение, которое дает теоретически произвольную точность, когда сделано произвольно большим / маленьким
  • Поведение на входе 1 не важно (это единственный полюс этой функции)

Самый короткий код в байтах побеждает!

Пример ввода и вывода

Входные данные:

2, 0

Выход:

1.6449340668482266, 0

Входные данные:

1, 1

Выход:

0,5821580597520037, -0,9268485643308071

Входные данные:

-1, 0

Выход:

-0.08333333333333559, 0

Йенс Рендерс
источник
1
Какова требуемая точность вывода? Я не уверен, что понимаю, что Ваш код должен содержать значение, которое дает теоретически произвольную точность, когда сделано произвольно большим / маленьким . Вы имеете в виду, как максимальное значение цикла, чем когда увеличение без ограничения дает повышенную точность? Может ли это значение быть жестко закодировано?
Луис Мендо
@DonMuesli Это означает, что точность зависит от параметра, скажем, N, который вы можете присвоить любому значению, которое вам нравится, но для любой заданной точности вы можете сделать N маленьким или большим, чтобы достичь этой точности. Слово теоретически есть, потому что вы не должны беспокоиться об ограниченной точности машины или языка.
Дженс Рендерс
Для дальнейшего уточнения N: достаточно ли того, что для любой привязки epsи ввода xсуществует Nвычисление zeta(x)с точностью до eps; или должен существовать тот, Nкоторый зависит только от epsи гарантирует, что для любого x(или, возможно, для любой, xболее определенной функции epsот полюса) он достигает границы; или может Nзависеть x, но ответы должны объяснить, как рассчитать Nданные xи eps? (Моя аналитическая теория чисел не так уж много, но я подозреваю, что варианты 2 и 3 будут выходить за рамки всех, кроме одного или двух обычных плакатов).
Питер Тейлор
@PeterTaylor N достаточно большой: для любого xи для любого epsдолжно существовать Pтакое, что для всех N>Pвыходных данных ближе, чем epsк точному значению. Это понятно? Нужно ли уточнить это для случая, когда N достаточно мало?
Йенс Рендерс
Нет, это достаточно ясно.
Питер Тейлор

Ответы:

8

Python - 385

Это простая реализация уравнения 21 от http://mathworld.wolfram.com/RiemannZetaFunction.html. Это использует соглашение Python для необязательных аргументов; если вы хотите указать точность, вы можете передать третий аргумент функции, в противном случае она использует 1e-24 по умолчанию.

import numpy as N
def z(r,i,E=1e-24):
 R=0;I=0;n=0;
 while(True):
  a=0;b=0;m=2**(-n-1)
  for k in range(0,n+1):
   M=(-1)**k*N.product([x/(x-(n-k))for x in range(n-k+1,n+1)]);A=(k+1)**-r;t=-i*N.log(k+1);a+=M*A*N.cos(t);b+=M*A*N.sin(t)
  a*=m;b*=m;R+=a;I+=b;n+=1
  if a*a+b*b<E:break
 A=2**(1-r);t=-i*N.log(2);a=1-A*N.cos(t);b=-A*N.sin(t);d=a*a+b*b;a=a/d;b=-b/d
 print(R*a-I*b,R*b+I*a)
RT
источник
z(2,0)дает неверное значение, должно быть пи ^ 2/6.
GuillaumeDufay
4

Python 3 , 303 297 байт

Этот ответ основан на ответе Python RT с несколькими модификациями:

  • Во- первых, Binomial(n, k)определяется как , p = p * (n-k) / (k+1)который изменяется , Binomial(n,k)чтобы Binomial(n,k+1)при каждом проходе для цикла.
  • Во-вторых, (-1)**k * Binomial(n,k)стал p = p * (k-n) / (k+1)щелчок знака на каждом шагу цикла.
  • В-третьих, whileцикл был изменен, чтобы немедленно проверить, если a*a + b*b < E.
  • В- четвертых, побитовое не оператор ~используется в нескольких местах , где они будут помогать в гольф, используя тождества , такие как -n-1 == ~n, n+1 == -~n, и n-1 == ~-n.

Для улучшения игры в гольф было сделано несколько других небольших модификаций, таких как размещение forцикла в одной строке и вызов в printодной строке с кодом перед ним.

Предложения по игре в гольф приветствуются. Попробуйте онлайн!

Редактировать: -6 байт из числа небольших изменений.

import math as N
def z(r,i,E=1e-40):
 R=I=n=0;a=b=1
 while a*a+b*b>E:
  a=b=0;p=1;m=2**~n
  for k in range(1,n+2):M=p/k**r;p*=(k-1-n)/k;t=-i*N.log(k);a+=M*N.cos(t);b+=M*N.sin(t)
  a*=m;b*=m;R+=a;I+=b;n+=1
 A=2**-~-r;t=-i*N.log(2);x=1-A*N.cos(t);y=A*N.sin(t);d=x*x+y*y;return(R*x-I*y)/d,(R*y+I*x)/d
Sherlock9
источник
1

Аксиома, 413 315 292 байта

p(n,a,b)==(x:=log(n^b);y:=n^a;[y*cos(x),y*sin(x)]);z(a,b)==(r:=[0.,0.];e:=10^-digits();t:=p(2,1-a,-b);y:=(1-t.1)^2+t.2^2;y=0=>[];m:=(1-t.1)/y;q:=t.2/y;n:=0;repeat(w:=2^(-n-1);abs(w)<e=>break;r:=r+w*reduce(+,[(-1)^k*binomial(n,k)*p(k+1,-a,-b) for k in 0..n]);n:=n+1);[r.1*m-q*r.2,m*r.2+r.1*q])

Это также реализовало бы уравнение 21 из http://mathworld.wolfram.com/RiemannZetaFunction.html Выше приведенная здесь должна быть одна аксиомная функция z (a, b), которая в 16 раз медленнее, чем эта функция Zeta (a, b) ниже [ это должен быть тот, который был скомпилирован] все безголосие и прокомментировано [1 секунда для Zeta () против 16 секунд для z () для одного значения из 20 цифр после точки плавания]. Для вопроса о цифре можно выбрать точность, вызвав digits (); функция, например, цифры (10); z (1,1) должен печатать 10 цифр после точки, но цифры (50); z (1,1) должен печатать 50 цифр после точки.

-- elevImm(n,a,b)=n^(a+i*b)=r+i*v=[r,v]
elevImm(n:INT,a:Float,b:Float):Vector Float==(x:=log(n^b);y:=n^a;[y*cos(x),y*sin(x)]::Vector Float);

--                      +oo               n
--                      ---              ---
--             1        \       1        \            n 
--zeta(s)= ---------- * /     ------  *  /    (-1)^k(   )(k+1)^(-s)
--          1-2^(1-s)   ---n  2^(n+1)    ---k         k  
--                       0                0


Zeta(a:Float,b:Float):List Float==
  r:Vector Float:=[0.,0.]; e:=10^-digits()

  -- 1/(1-2^(1-s))=1/(1-x-i*y)=(1-x+iy)/((1-x)^2+y^2)=(1-x)/((1-x)^2+y^2)+i*y/((1-x)^2+y^2)    

  t:=elevImm(2,1-a,-b);
  y:=(1-t.1)^2+t.2^2;
  y=0=>[] 
  m:=(1-t.1)/y; 
  q:=t.2/y
  n:=0
  repeat
     w:=2^(-n-1)
     abs(w)<e=>break  --- this always terminate because n increase
     r:=r+w*reduce(+,[(-1)^k*binomial(n,k)*elevImm(k+1,-a,-b) for k in 0..n])
     n:=n+1
  -- (m+iq)(r1+ir2)=(m*r1-q*r2)+i(m*r2+q*r1)
  [r.1*m-q*r.2,m*r.2+r.1*q]

this is one test for the z(a,b) function above:

(10) -> z(2,0)
   (10)  [1.6449340668 482264365,0.0]
                                              Type: List Expression Float
(11) -> z(1,1)
   (11)  [0.5821580597 520036482,- 0.9268485643 3080707654]
                                              Type: List Expression Float
(12) -> z(-1,0)
   (12)  [- 0.0833333333 3333333333 3,0.0]
                                              Type: List Expression Float
(13) -> z(1,0)
   (13)  []
RosLuP
источник