Nesting a specific recursion in Pari-GP

151 Views Asked by At

everyone!

I've posted a similar problem, initially on Stackexchange; it was moved here and can be found at the link: Declaring a functional recursive sequence in Matlab I'm trying to do something similar in this post, but I've figured that Matlab isn't the place to do it. I'll have to use Pari-GP; and at this point there's no two ways about it.

This is essentially a coding project I've made for myself; which is to effectively numerically evaluate a certain construction of the Tetration function. I've been able to code it fairly well in MatLab; the trouble is, as we are dealing with large numbers like e^e^e^e^e^e^e; these short circuit in MatLab. Pari-GP has a much better understanding of numbers which would usually cause overflows; and I'm now fully realizing why it's used consistently by the Tetration community.

Nonetheless, the Matlab code works for small numbers and numbers with a niceness to them (well placed imaginary argument). For completeness of this question; the github repository for the matlab code is https://github.com/JmsNxn92/Recursive_Tetration This isn't the code we want though; I've optimized it further; this isn't up to date totally. But for the purpose of this question, it's enough.

Now, I'm not the best programmer. I haven't programmed since '09, maybe; but I still know my way around. But it's more that I have the framework of coding; and less the actual syntax. Imagine being well acquainted with french philosophy and french writing; but stumbling your words when ordering a cafe.

As to that, I'll stop beating around the bush, and get to the question.

If I define a function beta_function in Pari-GP and write it as,

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

Everything is good, and it works. Now the code for beta_function in MatLab isn't very different. There's nothing more complex being added. As I originally asked for MatLab, I'm asking again for Pari-GP. This is how to code a function tau_K(z,l,n,k); which is perfectly doable. I'm just missing something obvious.

The code for tau_K(z,l,n,k) in MatLab is attached below. A friendly person on here explained how to do this in MatLab; for those of you interested, I wasn't really defining the recursion properly beforehand. Here is the current MatLab code I'm using,

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

The question is simple. How would one define this recursion in Pari-GP; how do you code this in Pari-GP?

Everything seems to be collapsing towards a return value at 0, when I try to directly translate this code. And honest to god; I know it's just because I'm making some syntax error in how I'm calling the output into the next iteration. I've tried everything I could think of. And the tutorials, they don't seem to be helping. I've tried next to everything. And at this point, I know I'm missing something stupid syntactically.

I'm just hoping someone here would be so helpful as to explain this to me like I'm in kindergarten. I've heard that tail recursion is important here. And if so, how would I code this in? Simply add in a variable which keeps track of everything?

Again, thanks if you got this far into the question.

1

There are 1 best solutions below

1
On BEST ANSWER

When asking questions, it would help if you would provide expected output for some specified given arguments, otherwise it is hard to test. I don't know MATLAB, but your functions could be written in 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))
    )
}

In the beta_function, it is important to put my() around out = 0. This keeps the variable local to the function. Failure to do this, means that out will be a global variable, and many subtle bugs can arise.

PARI is a functional programming language which means you often don't need to assign things explicitly to temporary variables. For example if will return a value and this can be returned from your tau_K function (in your MATLAB code you assign to a temporary variable f, but in PARI this is not necessary).

There are no issues with calling a function recursively. In this case, tau_K can just call itself as needed.

In the MATLAB program you have ./. I don't know what this means - I have replaced by / which is just the normal division operator.

Before running you will need to set some precision for the numeric operations. The easiest way to achieve this is to enter \p100 at the PARI-GP prompt. (or \p1000 if you need a 1000 decimal digits of precision). It is possible to control precision dynamically, if you need some part of the calculation performed at high precision and other parts at a lower precision or if the precision needs to be dependent on n.