How to create a local function during the code run

1 view (last 30 days)
Hello, everyone!
I have a question about opportunity of creating local functions during the code run.
For example I have this code:
function diffprobe
x0=[1 1];
for i=1:2
a=strcat('@odeEvent', num2str(i));
str = str2func(a);
options(i)=odeset('Events', str, 'RelTol',1e-9,'AbsTol',1e-9);
[~,~,TE,XE,IE]=ode45(@System, [0 inf],x0, options(i));
end
function [value, isterminal, direction]=odeEvent1(~,x)
value=[x(1)];
isterminal=[1];
direction=0;
function [value, isterminal, direction]=odeEvent2(~,x)
value=[x(2)];
isterminal=[1];
direction=0;
function RPF=System(~,x)
RPF=[x(2);...
-x(2)-1];
It is work right, but i have an interest to somehow create local functions odeEvent1 and odeEvent2 during the cycle, because of I need to generalize the method on high order systems so the cycle might go not from 1 to 2, but from 1 to n, and obviously I don't want to rewrite the code every time, when I try the new system.

Accepted Answer

Ameer Hamza
Ameer Hamza on 5 Jun 2020
Dynamically creating a function name is not a recommended coding practice. Following shows how to do such a thing more efficiently
function diffprobe
x0=[1 1];
for i=1:2
options(i)=odeset('Events', @(t,x) odeEvent(t,x,i), 'RelTol',1e-9,'AbsTol',1e-9);
[~,~,TE,XE,IE]=ode45(@System, [0 inf],x0, options(i));
end
function [value, isterminal, direction]=odeEvent(~,x,i)
value=[x(i)];
isterminal=[1];
direction=0;
function RPF=System(~,x)
RPF=[x(2);...
-x(2)-1];
  3 Comments
Ameer Hamza
Ameer Hamza on 5 Jun 2020
Yes, @(t,x) is the requirement of the solver(), whereas odeEvent(t,x,i) shows how you pass the solver variables to your odeEvent functions. You can read the documentation related to anonymous functions to see in detail what is happening here.
Steven Lord
Steven Lord on 5 Jun 2020
What Ivan Khomich wrote:
options(i)=odeset('Events', @(t,x,i) odeEvent, 'RelTol',1e-9,'AbsTol',1e-9);
ode45 will call the anonymous function stored in the Events option with two inputs (that is what it is documented to do) and so the variable named i will be undefined. The anonymous function will call odeEvent with zero inputs.
What Ameer Hamza wrote:
options(i)=odeset('Events', @(t,x) odeEvent(t,x,i), 'RelTol',1e-9,'AbsTol',1e-9);
ode45 will call the anonymous function stored in the Events option with two inputs. The anonymous function will call odeEvent with three inputs, the two passed into it by ode45 and one the anonymous function "remembered" because that variable existed when the anonymous function was created.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!