How to call a variable matrix from one script to another script

I have two scripts. In first one i will get A and B matrices which are interms of theta as shown below.
sym theta
A = cos(theta).*[1 5 6;
2 9 3;
5 1 0]
B = tan(2*theta).*[8 5 1;
0 1 6;
2 4 7]
I want to use these A and B matrices in another script, which is given below
function dydt = scriptname(t, y)
theta = y(3); % Substitute y(3) in place of theta in A and B matrices
A % Extract A matrix
B % Extract B matrix
V = [1;
5;
3]
dydt = V-((A+B)*Y);
end
Finally i will plot these ODE's in another script that i didnt gave here.
My main doubt is how to extract A and B matrices(especially those are variable matrices) into another script.
After extracting these A and B matrices i will substitute y(3) so that i can get rid of theta.
I havent shown my exact problem because its too complicated. Focus on my main doubt dont care about values.
Thanks in advance.

 Accepted Answer

I am not sure I have understtod correctly your problem. I give it a try.
I would add an extra layer using an anonymous function to solve the porblem of passing A and B to your funciton
clear variables, close all
% anonymous functions to calculate A and B
A = @(theta)cos(theta).*[1 5 6; 2 9 3; 5 1 0];
B = @(theta)tan(2*theta).*[8 5 1; 0 1 6; 2 4 7];
% extra layer to pass also A and B to your dydt function
myfun = @(t,y)scriptname(t,y,A,B);
% dummy values for tspan and y0
tspan = [0 1];
y0 = [0; 0; 0];
% ode solver
sol = ode45(myfun,tspan,y0);
function dydt = scriptname(t,y,A,B)
theta = y(3); % Substitute y(3) in place of theta in A and B matrices
V = [1; 5; 3];
% actual calculation of A and B with the current value for theta
dydt = V-((A(theta)+B(theta))*y);
end

18 Comments

Nice try
But i want go through 'sym' for evaluating A and B. Its my limitation.
Yes, providing A and B as parameters through an anonymous function is a good solution.
May I ask you why do you want to use sym? I have understood you are solving an ODE and I see many "numbers" in your functions.
Actually i haven't shared my original script here.
In my original script calculating A and B matrices is a lengthy process, it consists of differentiation and integration operations. These can be easily solved using sym.
After 250-300 lines of script i will get A and B as result in my first script.
Now i want to extract these A and B matrices to evaluate ODE equations.
Got it??
I don't understand if you need to calculate A and B at each time step or not. if they are independent of t and y you can evaluate them outside your ODE function and pass them to the ODE.
From this last comment it seems it is not the case, but from your comment to Jan it seems that you don't need to evaluate them at each time step ("If it enters into this subscript for every time step imagine how much time it will take.")
Another point is that symbolic calculations usaully takes more time than numeric calculation, so it could be helpful to calculate A and B numerically.
If you want to keep your analytic evaluation, below you can find the method modified for symbolic A and B
clear variables, close all
syms theta
A = cos(theta).*[1 5 6; 2 9 3; 5 1 0];
B = tan(2*theta).*[8 5 1; 0 1 6; 2 4 7];
myfun = @(t,y)scriptname(t,y,A,B);
% dummy values for tspan and y0
tspan = [0 1];
y0 = [0; 0; 0];
% ode solver
sol = ode45(myfun,tspan,y0);
function dydt = scriptname(t,y,A,B)
V = [1; 5; 3];
% evaluation of A and B (numerical) with theta = y(3)
An = double(subs(A,y(3)));
Bn = double(subs(B,y(3)));
dydt = V-((An+Bn)*y);
end
have u run this???
is this have any errors??
yes. Why do you ask? Do you find any error?
No no i thought some error may come.
i didnt run it, because my code is still compiling from last 10hrs onwards.
Now only i cancelled the compilation. i will try your way now, lets hope i will get result.
This may be simple thing for you but if it gives result i will be very thankful to you.
Hello sir one last doubt
If i want to plot the results how to plot,
iam using these steps for plotting but its giving error
syms theta
A = cos(theta).*[1 5 6; 2 9 3; 5 1 0];
B = tan(2*theta).*[8 5 1; 0 1 6; 2 4 7];
myfun = @(t,y)scriptname(t,y,A,B);
% dummy values for tspan and y0
tspan = [0 1];
y0 = [0; 0; 0];
% ode solver
sol = ode45(myfun,tspan,y0);
function dydt = scriptname(t,y,A,B)
V = [1; 5; 3];
% evaluation of A and B (numerical) with theta = y(3)
An = double(subs(A,y(3)));
Bn = double(subs(B,y(3)));
dydt = V-((An+Bn)*y);
end
for i=1.:3.
stator=y(:,i);
figure(1.);
subplot(2.,2.,i);
plot(t,stator);
xlabel('time');
ylabel('Current');
title(['stator current # ',int2str(i)]);
end
But it is giving the below error
Function definitions in a script must appear at the end of the file.
Move all statements after the "scriptname" function definition to before the first local function definition.
How to resolve this error??
Simply follow the statement of the error: if you have a script with a function definition (in this case the function scriptname, this must be at the end of the file (I recommend to use a different file named scriptname.m)
Another correction: the solution is in the struct sol, so you must refer to this variable to plot the solution. t and y are visible only inside the function scriptname.
I also changed the use of subplot
syms theta
A = cos(theta).*[1 5 6; 2 9 3; 5 1 0];
B = tan(2*theta).*[8 5 1; 0 1 6; 2 4 7];
myfun = @(t,y)scriptname(t,y,A,B);
% dummy values for tspan and y0
tspan = [0 1];
y0 = [0; 0; 0];
% ode solver
sol = ode45(myfun,tspan,y0);
h = figure;
% plot
for i = 1:3
subplot(3,1,i);
plot(sol.x,sol.y(i,:));
xlabel('time');
ylabel('Current');
title(['stator current # ',int2str(i)]);
end
function dydt = scriptname(t,y,A,B)
V = [1; 5; 3];
% evaluation of A and B (numerical) with theta = y(3)
An = double(subs(A,y(3)));
Bn = double(subs(B,y(3)));
dydt = V-((An+Bn)*y);
end
what is the need of h = figure; line??
to create the figure! and the output variable is the handle to that figure, in case you need to make any change. I suggest you to check first the matlab documentation.
If i want to plot first 2 waveforms in one figure and other one in separate figure then???
We are going further the scope of the original post. In any case, have a look at the plot command
Possible solution (not tested)
h = figure;
subplot(2,1,1); hold on
plot(sol.x,sol.y(1:2,:));
xlabel('time');
ylabel('Current');
title('stator current # 1 and 2');
subplot(2,1,2);
plot(sol.x,sol.y(3,:));
xlabel('time');
ylabel('Current');
title('stator current # 3');
can i use this way?
Assume i have 27 ODE's
my aim is to plot 1st three in one figure(not graph),
next 3 to 23 are in one figure >>>20 graphs,
24th, 25th, 26th and 27th one as individual figures,
Can the below way work??
h = figure
for i=1:27
if i<=3
subplot(2.,2.,i);
plot(sol.x,sol.y(i,:));
title(['stator current # ',int2str(i)]);
elseif i>3 && i<=23
if rem(20,2)==0
subplot(20/2.,2.,i-3.);
else
subplot(21/2.,2.,i-3.);
end
plot(sol.x,sol.y(i,:));
title(['Rotor current # ',int2str(i-3)]);
elseif i==24
plot(sol.x,sol.y(i,:));
title('End Ring Current');
elseif i==25
plot(sol.x,sol.y(i,:));
title('Field current');
elseif i==26
plot(sol.x,sol.y(i,:)*30/pi);
title('Mechanical Angular Speed');
else
plot(sol.x,sol.y(i,:));
title('rotor position');
end
end
will it work???
i havnt tried because i dont want to waste time for this(Hope u will understand).
You should ask another question, because this is beyond the scope of the original post. If the answer solves your problem, please accept it.
It is pretty simple to test yourself your code, creating a random y matrix. You can also run your code in this window using the run comamnd.

Sign in to comment.

More Answers (1)

The first code shows a "script", the second one a "function". While scripts share their variables with the callers automatically, functions don't. As far as I understand all you havt to do is to call the script:
% Script file: "yourScript.m"
sym theta
A = cos(theta).*[1 5 6;
2 9 3;
5 1 0]
B = tan(2*theta).*[8 5 1;
0 1 6;
2 4 7]
% Function file: "scriptname.m" ( missleading name! This is not a script.)
function dydt = scriptname(t, y)
theta = y(3); % Substitute y(3) in place of theta in A and B matrices
yourScript; % <-- A and B are defined internally
V = [1;
5;
3]
dydt = V-((A+B)*Y);
end
For productive code, scripts are a shot in your knee, because you cannot see directly, where the variables are defined. Use functions instead, to forward variables explicitly:
% Script file: "yourFunction.m"
function [A, B] = yourFunction()
sym theta
A = cos(theta).*[1 5 6;
2 9 3;
5 1 0]
B = tan(2*theta).*[8 5 1;
0 1 6;
2 4 7]
end
% Function file: "theOtherFunction.m"
function dydt = theOtherFunction(t, y)
[A, B] = yourFunction();
V = [1;
5;
3]
dydt = V-((A+B)*Y);
end

7 Comments

Thank you for your suggestion.
I tried the second way already. It is working, but while ODE calculation for every time step it is entering that subscript and evaluating every step in that. It is too much time consuming. Here i just showed A and B matrices directly but in my original problem there are so many lines(270-300 lines) to evaluate A and B. If it enters into this subscript for every time step imagine how much time it will take.
Its been 5 hours still script is running.
I need an efficient way.
I need to extract A and B matrices, after that no turn back to that script again while doing ODE equations.
Hope you understand my problem.
Then:
function dydt = theOtherFunction(t, y)
persistent A B
if isempty(A)
[A, B] = yourFunction();
end
V = [1;
5;
3]
dydt = V-((A+B)*Y);
end
Now A and B are created once only. To reset the persistently stored variables:
clear theOtherFunction
Can you explain what is the meaning behind the two lines(persistent and if isempty)??
One more doubt.
why only isempty(A) condition, what about B??
when you create A you create B s well, so you must check only one of them
ok thank you for your explanation

Sign in to comment.

Products

Release

R2021a

Community Treasure Hunt

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

Start Hunting!