MATLAB: Matlab Coder and ode45 with extra parameters – What implementation strategy

extra parametersmatlab coderode45persistent variable

Hi all,
I'd like to apply Matlab Coder to an 'ode45' function used with extra parameters. My problem is that Matlab coder does not support anonymous function so I tried to use persistent variable instead. But I obtain an error message.
Do you know where is the mistake in my code or what is the best implementation strategy for this case?
  1. As a benchmark, from the Matlab help, it is possible to modify the ‘rigid’ example and to use anonymous function (although there is no meaning here). It works. See section a)
  2. But I obtain an error message with the following code when I use persistent variable instead. See section b)
a) Code with anonymous function: no problem
VarAdd = 0.1;
options = odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
[T,Y] = ode45(@(t,y) rigid2(t,y,VarAdd),[0 12],[0 1 1],options);
plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),'.')
function dy = rigid2(t,y,VarAdd)
dy = zeros(3,1); % a column vector

dy(1) = y(2) * y(3) + VarAdd;
dy(2) = -y(1) * y(3) + VarAdd;
dy(3) = -0.51 * y(1) * y(2) + VarAdd;
b) Code with persistent variable: problem
Script:
VarAdd = 0.1;
t = [0 12];
y = [0 1 1];
[ T,Y ] = rigidp(t, y, VarAdd);
plot(T,Y(:,1),'-',T,Y(:,2),'-.',T,Y(:,3),'.')
Function #1
function [ T,Y ] = rigidp(t, y, VarAdd)
%#codegen

persistent VarAdd2;
VarAdd2 = VarAdd;
rigidp2(t,y,VarAdd2);
options = odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
[T,Y] = ode45(@rigidp2, t, y, options);
end
Function #2
function dy = rigidp2(t, y, VarAdd2)
%#codegen
dy = zeros(3,1); % a column vector
dy(1) = y(2) * y(3) + VarAdd2;
dy(2) = -y(1) * y(3) + VarAdd2;
dy(3) = -0.51 * y(1) * y(2) + VarAdd2;
Here is the error message:
Error using rigidp2 (line 5)
Not enough input arguments.
Thanks.
Nicolas

Best Answer

Hi Nicolas,
one way to do this is the "classical" way, i.e., the way it was done before anonymous functions existed. If you add parameters after the options, then ode45 knows that these are parameters for the ode function:
function Y = compute(VarAdd)
options = odeset('RelTol',1e-4,'AbsTol',[1e-4 1e-4 1e-5]);
[T,Y] = ode45(@rigid2,[0 12],[0 1 1],options,VarAdd);
function dy = rigid2(t,y,VarAdd)
dy = zeros(3,1); % a column vector
dy(1) = y(2) * y(3) + VarAdd;
dy(2) = -y(1) * y(3) + VarAdd;
dy(3) = -0.51 * y(1) * y(2) + VarAdd;
Titus