【问题标题】:Nesting a specific recursion in Pari-GP在 Pari-GP 中嵌套特定的递归
【发布时间】:2021-05-02 04:37:03
【问题描述】:

大家!

我已经发布了一个类似的问题,最初是在 Stackexchange 上;它已移至此处,可以在链接中找到:Declaring a functional recursive sequence in Matlab 我正在尝试在这篇文章中做类似的事情,但我认为 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 中编写代码?

当我尝试直接翻译这段代码时,一切似乎都在朝着返回值 0 崩溃。对上帝诚实;我知道这只是因为我在将输出调用到下一次迭代时出现了一些语法错误。我已经尝试了我能想到的一切。和教程,他们似乎没有帮助。我已经尝试过一切。在这一点上,我知道我在语法上遗漏了一些愚蠢的东西。

我只是希望这里有人能像我在幼儿园一样向我解释这一点。我听说尾递归在这里很重要。如果是这样,我将如何编码?只需添加一个跟踪所有内容的变量?

再次感谢您对问题的深入了解。

【问题讨论】:

    标签: matlab recursion pari-gp


    【解决方案1】:

    在提问时,如果您为某些指定的给定参数提供预期的输出会有所帮助,否则很难测试。我不知道 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 将返回一个值,这可以从您的tau_K 函数中返回(在您的 MATLAB 代码中您分配给一个临时变量 f,但在 PARI 中这不是必需的)。

    递归调用函数没有问题。在这种情况下,tau_K 可以根据需要调用自己。

    在 MATLAB 程序中,您有 ./。我不知道这意味着什么 - 我已替换为 /,这只是普通的除法运算符。

    在运行之前,您需要为数值运算设置一些精度。实现此目的的最简单方法是在 PARI-GP 提示符下输入 \p100。 (或 \p1000 如果您需要 1000 个十进制数字的精度)。如果您需要以高精度执行某些计算而其他部分以较低精度执行,或者精度需要依赖于n,则可以动态控制精度。

    【讨论】:

    • 非常感谢!您建议的代码与我写的非常接近。我想我明白我做错了什么。我没有将变量设置为本地;当我尝试构建 tau_K 时,我使用了相同的变量名。虽然,我的代码比你的有点丑;我无法理解为什么它不起作用。这绝对是地方问题。非常感谢!
    猜你喜欢
    • 2021-04-19
    • 2013-03-25
    • 1970-01-01
    • 2013-01-25
    • 2018-02-25
    • 2014-03-10
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多