hello,

i got a quick and trivial (not to me though) question for ya involving matlab. i am relatively new to matlab and have encounter a few problems using the function command. here is my code:

**********main.m**********
clear all
IC = [1 0.1 2];
time = [0 30];
global test1
global test2
[T,Y] = ode45(@calc, time, IC);
figure (1)
plot(T,Y)
figure(2)
plot(T,test1)
figure(3)
plot(T,test2)

**********test1_fun.m**********
function test1 = test1_fun(y,c)
global test1
a = 2;
b = a*y(1); <-- i know this is not used at the moment
test1 = a + y(1);

**********test2_fun.m**********
function test2=test2_fun(y)
global test2
c = 3 - y(2);
test2 = y(3).*c;

**********calc.m**********
function dy = calc(t,y)
global test1
global test2
dy = zeros(3,1);
test1 = test1_fun(y);
test2 = test2_fun(y);
dy(1) = y(2).*y(3);
dy(2) = -test1.*y(1).*y(3);
dy(3) = -0.51*y(1) + test2.*y(2);

i'm aware this code is not 100% efficient, but that's also why i am here.

first: i would like to store the variables test1 and test2 as the ode function builds the solution. from what i know, this code builds these variables, but overwrites them each time it loops through when it steps the time up. i know i can use the solution to rebuild the vectors ( ie test1 = a + Y(:,2); ), but is there a way to have matlab store test1 and others i need as it builds them?

second: do i need all those global variable declaration? also, i know in practice it is recommended to use all caps for globals.

third: can i just combine the test1 and test2 function m.files into one m.file? my real application im working on has many (30+) algebriac functions that are dependent on the solutions of a system of 45+ non-linear ode's that are also dependent on these algebriac equations. it would be nice to have the ode loop through all the functions, update the variables accordingly, call them up when needed, and store ones of my choosing.

if any of this is unclear, please let me know. i will post what is needed asap. thanks.

Dani AI

Generated

Short answer up front for (and , ): you do not need globals to keep per-step algebraic values. The simplest, safest choices are (A) compute the algebraic variables from the returned solution Y after ode45 finishes, or (B) capture solver steps while it runs using an OutputFcn (or by asking ode45 for outputs at a fixed tspan). For a large system (many algebraic expressions) the recommended pattern is to centralize those algebraic calculations in one vectorized routine and avoid globals.

Example pattern (store solver internal steps, then compute algebraics afterwards). Put this in your main file so the nested store() shares workspace and you avoid globals:

% main.m (outline)
t_store = [];
y_store = [];

opts = odeset('OutputFcn',@store);
[T,Y] = ode45(@odefun,[0 30],y0,opts);

% after solve you can compute all algebraics from y_store (vectorized)
% e.g. alg = myAlgebraics(y_store);

function status = store(t,y,flag)
    status = 0;               % continue
    if isequal(flag,'init')
        t_store = []; y_store = [];
    elseif isempty(flag)      % normal solver step(s)
        t_store = [t_store, t(:)'];
        y_store = [y_store, y];   % y is n x m (columns are steps)
    end
end

Notes and practical tips

  • Recomputing algebraics from Y after the solve is often the simplest and fastest, since you can vectorize the whole set of algebraic formulas. Only use OutputFcn if you must capture values at the solver's internal nodes.
  • Avoid globals. Use nested functions (share workspace), or pass parameters via an anonymous function: ode45(@(t,y) calc(t,y,params),...).
  • If you have 30+ algebraic functions, combine them into one function that returns a vector/struct. That reduces call overhead and keeps logic in one place.
  • Be careful with performance in the OutputFcn: append preallocated arrays when possible (or collect y columns and convert after) and avoid expensive work inside the OutputFcn because it is called very often.

These approaches let you store and inspect test1/test2 (and many more algebraic quantities) without fragile globals and while keeping performance manageable.

Hi!
Have you found out how to do this? I have the same question and I was thinking that you might have an answer by now.

Thanks!

hello,

i got a quick and trivial (not to me though) question for ya involving matlab. i am relatively new to matlab and have encounter a few problems using the function command. here is my code:

**********main.m**********
clear all
IC = [1 0.1 2];
time = [0 30];
global test1
global test2
[T,Y] = ode45(@calc, time, IC);
figure (1)
plot(T,Y)
figure(2)
plot(T,test1)
figure(3)
plot(T,test2)

**********test1_fun.m**********
function test1 = test1_fun(y,c)
global test1
a = 2;
b = a*y(1); <-- i know this is not used at the moment
test1 = a + y(1);

**********test2_fun.m**********
function test2=test2_fun(y)
global test2
c = 3 - y(2);
test2 = y(3).*c;

**********calc.m**********
function dy = calc(t,y)
global test1
global test2
dy = zeros(3,1);
test1 = test1_fun(y);
test2 = test2_fun(y);
dy(1) = y(2).*y(3);
dy(2) = -test1.*y(1).*y(3);
dy(3) = -0.51*y(1) + test2.*y(2);

i'm aware this code is not 100% efficient, but that's also why i am here.

first: i would like to store the variables test1 and test2 as the ode function builds the solution. from what i know, this code builds these variables, but overwrites them each time it loops through when it steps the time up. i know i can use the solution to rebuild the vectors ( ie test1 = a + Y(:,2); ), but is there a way to have matlab store test1 and others i need as it builds them?

second: do i need all those global variable declaration? also, i know in practice it is recommended to use all caps for globals.

third: can i just combine the test1 and test2 function m.files into one m.file? my real application im working on has many (30+) algebriac functions that are dependent on the solutions of a system of 45+ non-linear ode's that are also dependent on these algebriac equations. it would be nice to have the ode loop through all the functions, update the variables accordingly, call them up when needed, and store ones of my choosing.

if any of this is unclear, please let me know. i will post what is needed asap. thanks.

I have the same problem. I have defined a variable in main function and I want to use it in a function which is called by another function ode45. It returns error that the variable is not defined. HELP!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.