Matlab Coder and ode45 with extra parameters - What implementation strategy?

조회 수: 7 (최근 30일)
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

채택된 답변

Titus Edelhofer
Titus Edelhofer 2015년 5월 5일
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
  댓글 수: 2
Nicolas
Nicolas 2015년 5월 5일
Hi Titus,
thank you for your prompt reply. The 'classical' way works.
Thanks a lot,
Nicolas
Mike Hosea
Mike Hosea 2015년 5월 6일
편집: Mike Hosea 2015년 5월 6일
For future reference, the persistent approach needs to have a persistent variable in rigidp2. You use the saved value when 2 arguments are passed, and when 3 arguments are passed, you ignore the first two arguments and just store the 3rd input in the saved value for VarAdd.

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

추가 답변 (1개)

Nicolas
Nicolas 2015년 5월 5일
Two additionnal informations:
  1. The program 'b)' works if we substitute 'persistent VarAdd2' by 'global VarAdd2' and if we add this latter in the function 'rigidp2'. But it doesn't work with 'persistent'. I don't know why.
  2. Here are two interesting webpages:
Nicolas

카테고리

Help CenterFile Exchange에서 Ordinary Differential Equations에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by