MATLAB Answers

How to create a local function during the code run

31 views (last 30 days)
Ivan Khomich
Ivan Khomich on 5 Jun 2020 at 12:30
Commented: Steven Lord on 5 Jun 2020 at 16:03
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.

  0 Comments

Sign in to comment.

Answers (1)

Ameer Hamza
Ameer Hamza on 5 Jun 2020 at 13:24
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

Ivan Khomich
Ivan Khomich on 5 Jun 2020 at 13:33
O, very thanks.
It turned out to be very easy, but when I tried this myself I use this notation:
options(i)=odeset('Events', @(t,x,i) odeEvent, 'RelTol',1e-9,'AbsTol',1e-9);
and got the errors.
So, it turns out that @(a,b,...z) is the variables that go the solver, and odeEvent(t,x,i) - is the variables that go to the function odeEvent, right?
Ameer Hamza
Ameer Hamza on 5 Jun 2020 at 13:41
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 at 16:03
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.