从 Pari-GP 中的递归函数构建泰勒级数

Constructing Taylor Series from a Recursive function in Pari-GP

这是我的问题的延续:

Is there a more efficient way of nesting logarithms?

但我会保留这个问题。我为自己做了一个编码项目;这是为我构建的 tetration function 编写一个工作简单的计算器。这个四聚函数是全纯的,并且声明不是 Kneser 的解决方案(至于所有行话,请忽略);长话短说,我需要 运行 个数字;争取反对者。

关于这个,我不得不使用Pari-GP;因为这是处理大量数字和代数表达式的绝佳语言。当我们处理四舍五入时(想想 e^e^e^e^e^e 顺序的数字);在现有的少数语言中,这种语言是处理此类事务的最佳语言。它是进行迭代指数计算时的最爱。

现在,我面临的麻烦很奇怪。 不是以至于我的代码没有工作;它正在溢出,因为它应该溢出(想想,我们得到像 e^e^e^e^e^e 这样的输入;没有计算机可以正确处理它)。在我深入研究之前,我将 post 第一批代码。

以下代码完美运行;做我想做的一切。问题出在下一批代码上。这会产生我想要的所有数字。

\This is the asymptotic solution to tetration. z is the variable, l is the multiplier, and n is the depth of recursion
\Warning: z with large real part looks like tetration; and therefore overflows very fast. Additionally there are singularities which occur where l*(z-j) = (2k+1)*Pi*I.
\j,k are integers

beta_function(z,l,n) =
{
    my(out = 0);
    for(i=0,n-1,
        out = exp(out)/(exp(l*(n-i-z)) +1));
    out;
}

\This is the error between the asymptotic tetration and the tetration. This is pretty much good for 200 digit accuracy if you need.
\modify the 0.000000001 to a bigger number to make this go faster and receive less precision. When graphing 0.0001 is enough
\Warning: This will blow up at some points. This is part of the math; these functions have singularities/branch cuts.

tau(z,l,n)={
    if(1/real(beta_function(z,l,n)) <= 0.000000001, //this is where we'll have problems; if I try to grab a taylor series with this condition we error out
        -log(1+exp(-l*z)),
        log(1 + tau(z+1,l,n)/beta_function(z+1,l,n)) - log(1+exp(-l*z))
    )
}

\This is the sum function. I occasionally modify it; to make better graphs, but the basis is this.

Abl(z,l,n) = {
    beta_function(z,l,n) + tau(z,l,n)
}

插入这个,你会得到以下表达式:

Abl(1,log(2),100)
   realprecision = 28 significant digits (20 digits displayed)
%109 = 0.15201551563214167060
exp(Abl(0,log(2),100))
%110 = 0.15201551563214167060
Abl(1+I,2+0.5*I,100)
%111 = 0.28416643148885326261 + 0.80115283113944703984*I
exp(Abl(0+I,2+0.5*I,100))
%112 = 0.28416643148885326261 + 0.80115283113944703984*I

依此类推;其中 Abl(z,l,n) = exp(Abl(z-1,l,n))。这段代码没有问题。绝对none;我们可以将其设置为 200 精度,它仍然会产生正确的结果。这些图表的行为与数学所说的完全一样。问题是,在我的四舍五入结构中(我们真正想要的那个);我们必须将值 lAbl(z,l,n) 的解决方案粘贴在一起。现在,您根本不必担心这些;但是,从数学上讲,这就是我们正在做的事情。

这是第二批代码;旨在将所有这些Abl(z,l,n)“粘贴”到一个函数中。

//This is the modified asymptotic solution to the Tetration equation.
beta(z,n) = {
    beta_function(z,1/sqrt(1+z),n);
}

//This is the Tetration function.
Tet(z,n) ={
    if(1/abs(beta_function(z,1/sqrt(1+z),n)) <= 0.00000001,//Again, we see here this if statement; and we can't have this.
        beta_function(z,1/sqrt(1+z),n),
        log(Tet(z+1,n))
    )
}

此代码非常适合实数值;和复杂的价值。一些示例值,

Tet(1+I,100)
%113 = 0.12572857262453957030 - 0.96147559586703141524*I
exp(Tet(0+I,100))
%114 = 0.12572857262453957030 - 0.96147559586703141524*I
Tet(0.5,100)
%115 = -0.64593666417664607364
exp(Tet(0.5,100))
%116 = 0.52417133958039107545
Tet(1.5,100)
%117 = 0.52417133958039107545

我们也可以在实线上有效地绘制这个对象。看起来像下面这样,

ploth(X=0,4,Tet(X,100))

现在,您可能会问; 那有什么问题吗?

如果你试图在复平面上绘制这个函数,它注定会失败。嵌套对数在实线附近产生了太多的奇点。对于远离实线的虚构参数,没有问题。我制作了一些漂亮的图表;但是你越接近真实的线;它越是行为不端,只是短路。你可能在想;那么,数学是错误的!但是,不,发生这种情况的原因是因为 Kneser 的四分法是唯一关于对数主分支稳定的四分法。因为这个四分法不是 Kneser 的四分法,所以它在对数的主分支上本质上是不稳定的。当然,帕丽只是选择了总支。所以当我做 log(log(log(log(log(beta(z+5,100))))));数学已经表明这会发生分歧。但在实线上;这完全足够了。对于虚数远离零的 z 的值,我们也很好。

所以,我想解决这个问题的方法是在Tet(1+z,100)处获取泰勒级数; Pari-GP 非常适合。麻烦了?

Tet(1+z,100)
  ***   at top-level: Tet(1+z,100)
  ***                 ^------------
  ***   in function Tet: ...unction(z,1/sqrt(1+z),n))<=0.00000001,beta_fun
  ***                                                ^---------------------
  *** _<=_: forbidden comparison t_SER , t_REAL.

我所做的数字比较并没有转化为 t_SERt_REAL 之间的比较。

所以,我的问题终于来了:什么是仅使用真实输入获得 Tet(1+z,100) 的泰勒级数的有效策略。 z=0 附近的复数输入有误;真正的价值不是。如果我的数学是正确的;我们可以沿实线求导得到正确的结果。然后,我们可以构造一个 Tet_taylor(z,n) 这就是泰勒级数展开。哪个;尝试绘制图表时绝对不会出错。

任何帮助、问题、评论、建议 - 任何东西,我们都将不胜感激!我真的需要一些外界的关注。

如果你能弄清楚这个问题,非常感谢post。这个让我很烦。

问候,詹姆斯

编辑:

我应该补充一点,Tet(z+c,100) 对于某些数字 c 是我们想要的实际四舍五入函数。有一个变化常数我还没有谈到。尽管如此;这对问题来说是虚假的,更像是一个数学点。

这绝对不是答案 - 我完全不知道你想做什么。但是,我认为提供建议没有坏处。 PARI 有一个内置的幂级数类型(本质上是泰勒级数)——并且非常擅长使用它们(支持许多操作)。我原本打算就如何使用您的函数作为示例从递归定义中获得泰勒级数提供一些建议 - 但在这种情况下,我认为您正在尝试围绕可能注定要扩展的奇点进行扩展失败。 (在你的情节上它似乎是 x->0,结果是 -infinity???)

特别是如果我计算:

log(beta(z+1, 100))
log(log(beta(z+2, 100)))
log(log(log(beta(z+3, 100))))
log(log(log(log(beta(z+4, 100)))))
...

不同的系列没有收敛到任何东西。甚至系列的常数项也随着每次迭代而变小,所以我不完全确定是否存在关于 x = 0 的泰勒级数展开。

Questions/suggestions:

  • 您是否应该扩展不同的点? (说曲线在哪里 穿过 x 轴)。
  • 泰勒级数是否满足某种递归关系?例如:A(z) = log(A(z+1))。 [这行不通,但也许还有另一种写法]。

我怀疑我的回答不太可能令人满意 - 但话说回来,你的问题比实际的编程问题更数学化。

所以我已经成功回答了我的问题。我好久没编程了;我有点简陋。但我在喝够咖啡后想通了。我创建了 3 个新函数,这让我可以获取泰勒级数。

\This function attempts to find the number of iterations we need.

Tet_GRAB_k(A,n) ={
    my(k=0);
    while( 1/real(beta(A+k,n)) >= 0.0001, k++);
    return(k);
}


\This function will run and produce the same results as Tet; but it's slower; but it let's us estimate Taylor coefficients. 
\You have to guess which k to use for whatever accuracy before overflowing; which is what the last function is good for.

Tet_taylor(z,n,k) = {
    my(val = beta(z+k,n));
    for(i=1,k,val = log(val));
    return(val);
}

\This function produces an array of all the coefficients about a value A.

TAYLOR_SERIES(A,n) = {
    my(ser = vector(40,i,0));
    for(i=1,40, ser[i] = polcoeff(Tet_taylor(A+z,n,Tet_GRAB_k(A,n)),i-1,z));
    return(ser);
}

在 运行 数字之后,我相信这行得通。泰勒级数收敛;尽管比预期的要慢且准确度略低;但这是必须的。

感谢所有阅读本文的人。我只是为了完整性回答这个问题。