Function Iteration for n times, but n is NOT a fixed number

1 view (last 30 days)
I want to achieve this:
v, x are parameters, n is a variable. I want to define l(n) as a function of n by iteration. l(n) can be an implicit function/expression, as long as Matlab knows what l(n) is, and can call l(n) within other functions any time I want. But n is NOT a fixed number.
syms n v x
l(0) = 1 / sqrt(gamma(v + 1));
l(1) = (1 + v - x) / sqrt(gamma(v + 2));
for i = 2:n
l(i) = (v + 2 * i - 1 - x) / sqrt(i * (v + i)) * l(i - 1) - sqrt((v + i - 1) * (i - 1) / (v + i) / i) * l(i - 2);
end
Thank you!

Answers (2)

Walter Roberson
Walter Roberson on 6 Oct 2017
Edited: Walter Roberson on 6 Oct 2017
This is not possible with symfun(). symfun() cannot be recursive.
The syntax of symfun for 1 variable is
output = symfun(expression, variablename)
This follows standard MATLAB calling sequence, so expression is fully evaluated without binding the given variable as a dummy parameter, and the result is what is passed into symfun, which will then bind the variable name as the dummy parameter for whatever symbolic expression it got.
For example,
syms x
f = symfun(mod(x,1), x)
is the equivalent of
syms x
temp = mod(x,1);
f = symfun(temp, x)
It happens that mod(x,1) applied to symbolic variable x is defined as 0. This is not the same
f = @(x) mod(x, 1)
which defers evaluation of x until it is passed an argument.
You can get a fraction of the way there using piecewise(), but anonymous functions have no way to refer to themselves, so you cannot do the equivalent of
f(x,y) = piecewise(x == 1, SOMETHING(y), x == 2, SOMETHING_ELSE(y), SELF(x-1, y)*A_THIRD_THING(x,y) )
The only way to do anything like this for symbolic functions is to not use symfun or equivalent, and instead build some careful MuPAD code -- and being very careful about how it is evaluated and even more so about how it is displayed (error messages are typical if you accidentally try to display MuPAD code inside MATLAB.)
  3 Comments
Walter Roberson
Walter Roberson on 6 Oct 2017
I would suggest to you that your assigned value in your for loop should be l(i) rather than l(n) . If that change is made then you would have a recurrence equation; https://www.mathworks.com/help/symbolic/mupad_ref/rec.html . Unfortunately no direct MATLAB interface is provided to that MuPAD functionality; also, it is difficult to come up with a closed form for that equation.
I do not think the item you linked to has any relevance here.
The code would be easy to express as a MATLAB function, since MATLAB functions are able to refer to themselves. Also, if you are using R2017a or later, you could take advantage of memoize() to reduce the computation.
Pierre Deligne
Pierre Deligne on 12 Oct 2017
Hi Mr. Roberson. Thanks for your great help! I have made significant improvement following your guide. But the code still contains error. Please redirect to this page:
https://cn.mathworks.com/matlabcentral/answers/360971-matlab-calling-functions-from-mupad-notebooks
and help me with the error. Thank you very much!

Sign in to comment.


Stefan Wehmeier
Stefan Wehmeier on 9 Oct 2017
Why don't you make your last source code the body of a function? Is l at any time called with non-constant argument, such that you need to use it as a symbol? If yes, you have to write a function that, for constant integer arguments, does the loop you have given; and returns a call to a symfun otherwise.
This is a classical case where you would use "option remember" in MuPAD. Your definition of l(i) invokes two recursive calls, each of which invokes two recursive calls again etc. Thus Walter's piecewise could run into efficiency problems. If you wanted to emulate this behavior in MATLAB, you would need a persistent variable containing an array of all previously computed results.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!