问题描述
这是我问题的延续:
Declaring a functional recursive sequence in Matlab
Is there a more efficient way of nesting logarithms?
Nesting a specific recursion in Pari-GP
但我会保持这个问题独立。我为自己做了一个编码项目;这是为我构建的 tetration function 编写一个简单的计算器。这个 tetration 函数是全纯的,并且声明不是 Kneser 的解决方案(至于所有术语,请忽略);长话短说,我需要计算数字;赢得反对者。
至于这个,我必须使用Pari-GP;因为这是处理大数和代数表达式的奇妙语言。当我们处理 tetration 时(想想 e^e^e^e^e^e 顺序的数字);在现有的少数语言中,这种语言最适合此类事务。它是进行迭代指数计算时的最爱。
现在,我面临的麻烦很奇怪。 不是我的代码不起作用;它是溢出,因为它应该溢出(想想,我们得到像 e^e^e^e^e^e 这样的输入;并且没有计算机可以正确处理它)。在深入研究之前,我会发布第一批代码。
以下代码完美运行;做我想做的一切。问题在于下一批代码。这会产生我想要的所有数字。
\\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,n)={
if(1/real(beta_function(z,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,n)/beta_function(z+1,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,n) = {
beta_function(z,n) + tau(z,n)
}
将其插入,您将得到以下表达式:
Abl(1,log(2),100)
realprecision = 28 significant digits (20 digits displayed)
%109 = 0.15201551563214167060
exp(Abl(0,100))
%110 = 0.15201551563214167060
Abl(1+I,2+0.5*I,100)
%111 = 0.28416643148885326261 + 0.80115283113944703984*I
exp(Abl(0+I,100))
%112 = 0.28416643148885326261 + 0.80115283113944703984*I
等等等等;其中Abl(z,n) = exp(Abl(z-1,n))
。这段代码没有问题。绝对没有;我们可以将其设置为 200 精度,它仍然会产生正确的结果。图表的行为与数学所说的完全一样。问题是,在我的 tetration 构造中(我们真正想要的那个);我们必须将值 Abl(z,n)
的 l
的解决方案拼凑在一起。现在,您完全不必担心任何这些;但是,从数学上讲,这就是我们正在做的事情。
这是第二批代码;它旨在将所有这些 Abl(z,n)
“粘贴在一起”到一个函数中。
//This is the modified asymptotic solution to the Tetration equation.
beta(z,1/sqrt(1+z),n);
}
//This is the Tetration function.
Tet(z,n) ={
if(1/abs(beta_function(z,n)) <= 0.00000001,//Again,we see here this if statement; and we can't have this.
beta_function(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 的四分法,因此它在对数的主分支上本质上是不稳定的。当然,Pari 只是选择主分支。所以当我做 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,n))<=0.00000001,beta_fun
*** ^---------------------
*** _<=_: forbidden comparison t_SER,t_REAL.
我所做的数字比较并没有转化为 t_SER
和 t_REAL
之间的比较。
所以,我的问题终于来了:仅使用真实输入获得 Tet(1+z,100)
的泰勒级数的有效策略是什么。 z=0
附近的复数输入是错误的;真正的价值不是。如果我的数学是对的;我们可以沿实线求导数并得到正确的结果。然后,我们可以构造一个 Tet_taylor(z,n)
,它就是泰勒级数展开式。哪个;尝试绘制图形时绝对不会出错。
任何帮助、问题、评论、建议——任何东西,非常感谢!我真的需要一些外界的关注。
问候,詹姆斯
编辑:
我应该补充一点,某个数字 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 的泰勒级数展开。
问题/建议:
- 您是否应该扩展一个不同的点? (说曲线在哪里 穿过 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,Tet_GRAB_k(A,n)),i-1,z));
return(ser);
}
运行这些数字后,我相信这是有效的。泰勒级数正在收敛;尽管比预期的要慢且准确度稍低;但这是必须的。
感谢所有阅读本文的人。我只是为了完整性而回答这个问题。