What is the best practice for creating a recursion loop?

Hello all! I am trying to create a simple program that creates a fractal. It is supposed to be putting complex values into an array from the initial conditions and I will plot them later.
My Questions are:
1. What is the correct way to implement an Anonymous Function?
2. What is the best practice in Matlab for a recursion loop?
The answer to question 1 may not be necessary if the answer to 2 does not use Anonymous Functions.
clear all
clc
F = @(z) z^2 + c;
Re = [];
Im = [];
x = 1;
y = 1;
a = 2;
b = 3;
n = 10;
c = x+y*1i;
z0 = a+b*1i;
% Placing values in arrays to be plotted
Re(1,1) = real(z0 + c);
Im(1,1) = imag(z0 + c);
F(z0) = z; % First step of the recursion outside for loop?
% Second values for the array
Re(2,1) = real(z);
Im(2,1) = imag(z);
for h = (3:n) % Begin recursion
F(z) = z;
Re(h,1) = real(z);
Im(h,1) = imag(z);
h = h + 1;
end

 채택된 답변

Walter Roberson
Walter Roberson 2025년 1월 21일
F = @(z) z^2 + c;
That statement says that you are creating an anonymous function that takes a single parameter (shortcut name: z), and that the body of the loop will eventually square whatever is passed in the first parameter and then add c. But the value of c that is used will be whatever the value of c is at the time of the definition of the anonymous function... and c has no definition at the time. So the execution of the anonymous function will first attempt to square the first parameter and then will generate an error about c being undefined.
c = x+y*1i;
That definition of c after the definition of the anonymous function does not affect the anonymous function. The anonymous function does not look up the current value of c and use it: the anonymous function binds in the value of c as-of the time the anonymous function is created.
z0 = a+b*1i;
ok, z0 is a complex-valued quantity.
F(z0) = z;
There is a problem... z is not defined at that point.
When an anonymous function call appears on the left hand side of an assignment statement, the datatype of the right hand side of the assignment is first checked, and the assignment is rejected if the right hand side is not a function handle.
If z happened to be a function handle, such as
z = @(Z) Z.^3 - Z + 1;
then the subscript z0 would be evaluated, and the assignment would be rejected unless z0 is a positive integer. Which is not the case here, as z0 is a complex-valued result.
Lastly, the assignment F(z0) = z would check that z0 is a positive integer within the range of the number of elements of the function handle F ... which is to say that z0 would have to be exactly 1.
Under the condition that z0 was exactly 1 and z is a function handle, then the statement F(z0) = z would replace the function handle stored in F with the function handle stored in z.
When F is an anonymous function, F(z0) = z does not instruct the anonymous function to return the value of z when given parameter z0. If you really want to do that, then you would need to code something like
F = @(Z) (Z==z0).*z + (Z~=z0).*F(Z)
and hope that none of the values involved are infinite.
Note that this code ends up invoking all of the previous F definitions: MATLAB is not smart enough to know that when Z~=z0 is false that the 0 that results from the comparison will zero out whatever F(Z) is and so the F(Z) does not have to be done. (Except it does have to be done, because F(Z) might happen to be infinite and 0 * infinite is nan rather than 0)

댓글 수: 4

The best way to define an anoymous function is to define it once (well, once each time any bound variables are changed.) Using tricks such as F = @(Z) (Z==z0).*z + (Z~=z0).*F(Z) works (more or less) to define anonymous functions iteratively works, but it is not recommended... it's pretty inefficient.
If you are going to define a function iteratively, then consider using the Symbolic Toolbox to define the function using piecewise()
syms x
F = piecewise(x==0, 1, sin(x)/x)
F = 
F = piecewise(x==10, 2, F)
F = 
Observe that the first piecewise() has been merged with the second one, producing one single piecewise() structure.
What is the best practice in Matlab for a recursion loop?
Much of the time, the best practice is to define the function iteratively instead of recursively.
Still, sometimes recursive definition is a lot easier to formulate than iterative definitions.
The key to recursive functions is:
  1. First thing in the function body is to check whether the boundary conditions have been reached; if so return the appropriate boundary value
  2. Only once the boundary conditions have been checked do you have the recursive call(s)
  3. It is usually quite important that any recursive calls pass parameters are in some sense "easier" to process than the current parameters. For example, if you are currently working on a vector of length 20 then the recursive call might work on a vector of length 19 (and then that might pass a vector of length 18 and so on.) This is not strictly necessary, but any time it is not true, you need to have a strong reason to believe that the recursive call will in fact terminate at some point.
  4. The built-in recursion limit is 500 levels. That is usually plenty. When it is not, then you can use set(0,'Rec​ursionLimi​t',N) to increase it.
  5. When you use recursive functions it is often a good idea to use memoize()
That said, I am not convinced that fractals need either complicated anonymous functions or recursive definition. fractals usually just need a lot of iteration.
Christopher Scott
Christopher Scott 2025년 1월 22일
이동: Walter Roberson 2025년 1월 22일
Thank you all for your help! I will rework the code to avoid recursion.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Fractals에 대해 자세히 알아보기

제품

릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by