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.

 採用された回答

Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日

1 投票

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 件のコメント

Bathala Teja
Bathala Teja 2021 年 9 月 7 日
Nice try
But i want go through 'sym' for evaluating A and B. Its my limitation.
Jan
Jan 2021 年 9 月 7 日
Yes, providing A and B as parameters through an anonymous function is a good solution.
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
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.
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
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??
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
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.
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
編集済み: Fabio Freschi 2021 年 9 月 8 日
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
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
have u run this???
is this have any errors??
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
yes. Why do you ask? Do you find any error?
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
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.
Bathala Teja
Bathala Teja 2021 年 9 月 8 日
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??
Fabio Freschi
Fabio Freschi 2021 年 9 月 8 日
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
Bathala Teja
Bathala Teja 2021 年 9 月 8 日
what is the need of h = figure; line??
Fabio Freschi
Fabio Freschi 2021 年 9 月 8 日
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.
Bathala Teja
Bathala Teja 2021 年 9 月 8 日
If i want to plot first 2 waveforms in one figure and other one in separate figure then???
Fabio Freschi
Fabio Freschi 2021 年 9 月 8 日
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');
Bathala Teja
Bathala Teja 2021 年 9 月 8 日
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).
Fabio Freschi
Fabio Freschi 2021 年 9 月 8 日
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.
Bathala Teja
Bathala Teja 2021 年 9 月 8 日
Ok thank you

サインインしてコメントする。

その他の回答 (1 件)

Jan
Jan 2021 年 9 月 7 日
編集済み: Jan 2021 年 9 月 7 日

0 投票

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 件のコメント

Bathala Teja
Bathala Teja 2021 年 9 月 7 日
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.
Jan
Jan 2021 年 9 月 7 日
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
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
Can you explain what is the meaning behind the two lines(persistent and if isempty)??
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
You can find an explanation of persistent and its usage here
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
One more doubt.
why only isempty(A) condition, what about B??
Fabio Freschi
Fabio Freschi 2021 年 9 月 7 日
when you create A you create B s well, so you must check only one of them
Bathala Teja
Bathala Teja 2021 年 9 月 7 日
ok thank you for your explanation

サインインしてコメントする。

製品

リリース

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by