在 Pari-GP 中嵌套特定的递归
Nesting a specific recursion in Pari-GP
各位!
我已经 post 解决了一个类似的问题,最初是在 Stackexchange 上;它被移到这里,可以在 link 找到: 我正在尝试在这个 post 中做类似的事情,但我认为 Matlab 不是做吧。我将不得不使用 Pari-GP;在这一点上没有两种解决方法。
这本质上是我为自己制作的一个编码项目;这是为了有效地数值评估 Tetration 函数的某种构造。我已经能够在 MatLab 中很好地编写代码;问题是,因为我们正在处理像 e^e^e^e^e^e^e 这样的大数字;这些短路在 MatLab 中。 Pari-GP 对通常会导致溢出的数字有更好的理解;我现在完全明白为什么 Tetration 社区一直使用它。
尽管如此,Matlab 代码适用于小数字和对它们有好处的数字(放置虚构的参数)。为了这个问题的完整性; matlab 代码的 github 存储库是 https://github.com/JmsNxn92/Recursive_Tetration 这不是我们想要的代码;我进一步优化了它;这完全不是最新的。但是对于这个问题的目的来说,已经足够了。
现在,我不是最好的程序员。我从 09 年开始就没编程了,也许吧;但我仍然知道我的出路。但更多的是我有编码的框架;而更少的实际语法。想象一下熟悉法国哲学和法国写作;但是在点咖啡厅时结结巴巴
至于这个,我就不拐弯抹角了,直接进入正题。
如果我在 Pari-GP 中定义一个函数 beta_function
并将其写为,
beta_function(z,l,n) =
{
out = 0;
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
一切都很好,而且很有效。现在 MatLab 中 beta_function
的代码并没有太大的不同。没有比添加更复杂的了。正如我最初要求 MatLab,我再次要求 Pari-GP。这是编写函数代码的方法 tau_K(z,l,n,k)
;这是完全可行的。我只是遗漏了一些明显的东西。
MatLab 中tau_K(z,l,n,k)
的代码附在下面。一位友善的人在这里解释了如何在 MatLab 中执行此操作;对于那些感兴趣的人,我并没有真正事先正确定义递归。这是我当前使用的 MatLab 代码,
function f = tau_K(z,l,n,k)
if k == 1
f = -log(1+exp(-l*z));
return
end
f = log(1 + tau_K(z+1,l,n,k-1)./beta_function(z+1,l,n)) - log(1+exp(-l*z));
end
问题很简单。如何在 Pari-GP 中定义这种递归?你如何在 Pari-GP 中编写代码?
当我尝试直接翻译这段代码时,一切似乎都朝着 return 值崩溃。对上帝诚实;我知道这只是因为我在如何将输出调用到下一次迭代时犯了一些语法错误。我已经尝试了我能想到的一切。而教程,他们似乎没有帮助。我已经尝试了一切。在这一点上,我知道我在语法上遗漏了一些愚蠢的东西。
我只是希望这里有人能像我在幼儿园一样向我解释这一点。我听说尾递归在这里很重要。如果是这样,我将如何编写代码?只需添加一个跟踪所有内容的变量?
再次感谢您能深入了解这个问题。
问问题的时候,如果你能为一些指定的给定参数提供预期的输出会有所帮助,否则很难测试。我不懂 MATLAB,但你的函数可以用 PARI 编写:
beta_function(z,l,n)={
my(out = 0);
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
tau_K(z,l,n,k)={
if(k == 1,
-log(1+exp(-l*z)),
log(1 + tau_K(z+1,l,n,k-1)/beta_function(z+1,l,n)) - log(1+exp(-l*z))
)
}
在beta_function
中,重要的是把my()
放在out = 0
周围。这使变量保持在函数的局部。如果不这样做,意味着 out
将是一个全局变量,并且可能会出现许多细微的错误。
PARI 是一种函数式编程语言,这意味着您通常不需要将内容显式分配给临时变量。例如 if
将 return 一个值,这可以从你的 tau_K
函数中 returned(在你的 MATLAB 代码中你分配给一个临时变量 f,但在 PARI 中这个没有必要)。
递归调用函数没有问题。在这种情况下,tau_K
可以根据需要调用自身。
在您的 MATLAB 程序中有 ./
。我不知道这是什么意思——我已经用 /
代替了,它只是普通的除法运算符。
在 运行 之前,您需要为数字运算设置一些精度。实现此目的的最简单方法是在 PARI-GP 提示符下输入 \p100
。 (或者 \p1000 如果您需要 1000 位十进制数字的精度)。如果您需要以高精度执行某些部分的计算而其他部分以较低的精度执行,或者如果精度需要依赖于 n
.
,则可以动态控制精度
各位!
我已经 post 解决了一个类似的问题,最初是在 Stackexchange 上;它被移到这里,可以在 link 找到:
这本质上是我为自己制作的一个编码项目;这是为了有效地数值评估 Tetration 函数的某种构造。我已经能够在 MatLab 中很好地编写代码;问题是,因为我们正在处理像 e^e^e^e^e^e^e 这样的大数字;这些短路在 MatLab 中。 Pari-GP 对通常会导致溢出的数字有更好的理解;我现在完全明白为什么 Tetration 社区一直使用它。
尽管如此,Matlab 代码适用于小数字和对它们有好处的数字(放置虚构的参数)。为了这个问题的完整性; matlab 代码的 github 存储库是 https://github.com/JmsNxn92/Recursive_Tetration 这不是我们想要的代码;我进一步优化了它;这完全不是最新的。但是对于这个问题的目的来说,已经足够了。
现在,我不是最好的程序员。我从 09 年开始就没编程了,也许吧;但我仍然知道我的出路。但更多的是我有编码的框架;而更少的实际语法。想象一下熟悉法国哲学和法国写作;但是在点咖啡厅时结结巴巴
至于这个,我就不拐弯抹角了,直接进入正题。
如果我在 Pari-GP 中定义一个函数 beta_function
并将其写为,
beta_function(z,l,n) =
{
out = 0;
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
一切都很好,而且很有效。现在 MatLab 中 beta_function
的代码并没有太大的不同。没有比添加更复杂的了。正如我最初要求 MatLab,我再次要求 Pari-GP。这是编写函数代码的方法 tau_K(z,l,n,k)
;这是完全可行的。我只是遗漏了一些明显的东西。
MatLab 中tau_K(z,l,n,k)
的代码附在下面。一位友善的人在这里解释了如何在 MatLab 中执行此操作;对于那些感兴趣的人,我并没有真正事先正确定义递归。这是我当前使用的 MatLab 代码,
function f = tau_K(z,l,n,k)
if k == 1
f = -log(1+exp(-l*z));
return
end
f = log(1 + tau_K(z+1,l,n,k-1)./beta_function(z+1,l,n)) - log(1+exp(-l*z));
end
问题很简单。如何在 Pari-GP 中定义这种递归?你如何在 Pari-GP 中编写代码?
当我尝试直接翻译这段代码时,一切似乎都朝着 return 值崩溃。对上帝诚实;我知道这只是因为我在如何将输出调用到下一次迭代时犯了一些语法错误。我已经尝试了我能想到的一切。而教程,他们似乎没有帮助。我已经尝试了一切。在这一点上,我知道我在语法上遗漏了一些愚蠢的东西。
我只是希望这里有人能像我在幼儿园一样向我解释这一点。我听说尾递归在这里很重要。如果是这样,我将如何编写代码?只需添加一个跟踪所有内容的变量?
再次感谢您能深入了解这个问题。
问问题的时候,如果你能为一些指定的给定参数提供预期的输出会有所帮助,否则很难测试。我不懂 MATLAB,但你的函数可以用 PARI 编写:
beta_function(z,l,n)={
my(out = 0);
for(i=0,n-1,
out = exp(out)/(exp(l*(n-i-z)) +1));
out;
}
tau_K(z,l,n,k)={
if(k == 1,
-log(1+exp(-l*z)),
log(1 + tau_K(z+1,l,n,k-1)/beta_function(z+1,l,n)) - log(1+exp(-l*z))
)
}
在beta_function
中,重要的是把my()
放在out = 0
周围。这使变量保持在函数的局部。如果不这样做,意味着 out
将是一个全局变量,并且可能会出现许多细微的错误。
PARI 是一种函数式编程语言,这意味着您通常不需要将内容显式分配给临时变量。例如 if
将 return 一个值,这可以从你的 tau_K
函数中 returned(在你的 MATLAB 代码中你分配给一个临时变量 f,但在 PARI 中这个没有必要)。
递归调用函数没有问题。在这种情况下,tau_K
可以根据需要调用自身。
在您的 MATLAB 程序中有 ./
。我不知道这是什么意思——我已经用 /
代替了,它只是普通的除法运算符。
在 运行 之前,您需要为数字运算设置一些精度。实现此目的的最简单方法是在 PARI-GP 提示符下输入 \p100
。 (或者 \p1000 如果您需要 1000 位十进制数字的精度)。如果您需要以高精度执行某些部分的计算而其他部分以较低的精度执行,或者如果精度需要依赖于 n
.