How to fix it ? Warning: Do not specify equations and variables as character strings. Instead, create symbolic variables with syms. > In solve>getEqns (line 455) In solve (line 227)

3 views (last 30 days)
my code
S=dsolve('Dx1=x2,Dx2=-lam2,Dlam1=0,Dlam2=-lam1,x1(0)=1,x2(0)=2,x1(tf)=3,lam2(tf)=0')
t='tf';
eq1=subs(S.x1)-'x1tf';
eq2=subs(S.x2)-'x2tf';
eq3=S.lam1-'lam1tf';
eq4=subs(S.lam2)-'lam2tf';
eq5='lam1tf*x2tf-0.5*lam2tf^2';
S2=solve(eq1,eq2,eq3,eq4,eq5,'tf,x1tf,x2tf,lam1tf,lam2tf','lam1tf<>0')
if i run, help pls
  2 Comments
Johny
Johny on 18 Dec 2022
how can i fix this
sdot= @(t,s) ....
[s(2);
[2*M*s(2)*s(4)*cos(s(3))*sin(s(3))+M*g*cos(s(3))*sin(s(3))-s(4)*L*cos(s(3))+k*s(1)]/(M*sin^2(s(3))+m);
s(4);
[-2*M*s(2)*s(4)*sin(s(3))[cos^2(s(3))-sin^2(s(3))]-sin(s(3))[M*g*cos^2(s(3))-2*m*s(2)*s(4)-g*m-(g+(M*sin^2(s(3)))]+s(4)*L*cos^2(s(3))-k*cos(s(3))]/(L*m+L*M*sin^2(s(3)))];
Walter Roberson
Walter Roberson on 18 Dec 2022
What about it? That code cannot generate the error message being discussed -- not in itself, as it just defines an array.
You need to fix some portions of the code.
sin(s(3))[M*g..etc]
That is invalid.
In MATLAB, the [] operator is used only for array (or vector) building. It can never be used to index a result -- if you want M*g..etc to be used to index the resut of sin(s(3)) then you would need to define a helper function, like
IndexAt = @(EXPRESSION, INDEX) EXPRESSION(INDEX)
sdot= @(t,s) ....
[s(2);
[2*M*s(2)*s(4)*cos(s(3))*sin(s(3))+M*g*cos(s(3))*sin(s(3))-s(4)*L*cos(s(3))+k*s(1)]/(M*sin^2(s(3))+m);
s(4);
[-2*M*s(2)*s(4)*sin(s(3))[cos^2(s(3))-sin^2(s(3))]-INDEXAT(sin(s(3)),M*g*cos^2(s(3))-2*m*s(2)*s(4)-g*m-(g+(M*sin^2(s(3))))+s(4)*L*cos^2(s(3))-k*cos(s(3))]/(L*m+L*M*sin^2(s(3)))];
But it seems very unlikely that the expression given will happen to work out as exactly an integer.
cos^2(s(3))
as far as MATLAB is concerned, that is equivalent to
INDEXAT(cos()^2,s(3))
which would try to invoke cos with no parameters, do a matrix squaring of the result, and index that result as s(3)
If you want to square the cosine then you need to square the result of the cosine call, such as
cos(s(3)).^2
It is recommended that [] not be used to indicate prioritization. You can certainly code things like 5*[x+9,y+7] which would in a sense give priority to calculating x+9 and y+7 before doing the multiplication. But if you had 5*[x+9] then the recommendation would be to instead write 5*(x+9) . 5*[x+9] is not invalid code, but it is not as efficient as it could be, as it is prod(5, horzcat(plus(x,9))) with the matrix-building call to horzcat() present, which is not as efficient as 5*(x+9) would be prod(5, plus(x,9)) with no extra call.
Using [] for prioritization risks unexpect results due to some subtle details of what spacing means inside [] and {} operators. [] is only recommended if you are building lists or arrays.

Sign in to comment.

Accepted Answer

Steven Lord
Steven Lord on 25 Mar 2021
As per the warning at the top of the documentation page for the dsolve function: "Support for character vector or string inputs will be removed in a future release. Instead, use syms to declare variables and replace inputs such as dsolve('Dy = -3*y') with syms y(t); dsolve(diff(y,t) == -3*y)."
  7 Comments
Muhammad Giovani
Muhammad Giovani on 25 Mar 2021
i give a question
wrote a code
% Example 2.14
% Langkah pertama dengan menggunakan perintah dsolve
S=dsolve('Dx1=x2,Dx2=-lam2,Dlam1=0,Dlam2=-lam1,x1(0)=1,x2(0)=2,x1(tf)=3,lam2(tf)=0')
t='tf';
eq1=subs(S.x1)-'x1tf';
eq2=subs(S.x2)-'x2tf';
eq3=S.lam1-'lam1tf';
eq4=subs(S.lam2)-'lam2tf';
eq5='lam1tf*x2tf-0.5*lam2tf^2';
syms S2
S2=solve(eq1,eq2,eq3,eq4,eq5,'tf,x1tf,x2tf,lam1tf,lam2tf','lam1tf<>0')
%% lam1tf<>0 means lam1tf is not equal to 0;
%% This is a condition derived from eq5.
%% Otherwise, without this condition in the above
%% SOLVE routine, we get two values for tf (1 and 3 in this case)
tf=S2.tf
x1tf=S2.x1tf;
x2tf=S2.x2tf;
clear t
x1=subs(S.x1)
x2=subs(S.x2)
lam1=subs(S.lam1)
lam2=subs(S.lam2)
%% Convert the symbolic values to
%% numerical values as shown below.
j=1;
tf=double(subs(S2.tf))
%% coverts tf from symbolic to numerical
for tp=0:0.05:tf
t=sym(tp);
%% coverts tp from numerical to symbolic
x1p(j)=double(subs(S.x1));
%% subs substitutes S.x1 to x1p.
x2p(j)=double(subs(S.x2));
%% double converts symbolic to numeric
up(j)=-double(subs(S.lam2));
%% optimal control u = -lambda_2
t1(j)=tp;
j=j+1 ;
end
plot(t1,x1p,'k',t1,x2p,'k',t1,up,'k:')
xlabel('t')
gtext ('x_1(t)1')
gtext ('x_2(t) ')
gtext ('u(t)')
Walter Roberson
Walter Roberson on 18 Dec 2022
Unfortunately, dsolve() cannot work with more than one initial value per function, so you have to solve without the extra initial conditions, and then make the rest of the solution fit the initial condition.
% Example 2.14
% Langkah pertama dengan menggunakan perintah dsolve
%S=dsolve('Dx1=x2,Dx2=-lam2,Dlam1=0,Dlam2=-lam1,x1(0)=1,x2(0)=2,x1(tf)=3,lam2(tf)=0')
syms x_1(t) x_2(t) lam_1(t) lam_2(t) tf
Dx1 = diff(x_1);
Dx2 = diff(x_2);
Dlam1 = diff(lam_1);
Dlam2 = diff(lam_2);
eqn1 = Dx1 == x_2;
eqn2 = Dx2 == -lam_2;
eqn3 = Dlam1 == 0;
eqn4 = Dlam2 == -lam_1;
ic1 = x_1(0)==1;
ic2 = x_2(0)==2;
ic3 = x_1(tf)==3;
ic4 = lam_2(tf)==0;
sol_someic = dsolve([eqn1, eqn2, eqn3, eqn4, ic1, ic2, ic4])
sol_someic = struct with fields:
x_2: C1*t - (C1*t^2)/(2*tf) + 2 x_1: - (C1*t^3)/(6*tf) + (C1*t^2)/2 + 2*t + 1 lam_1: -C1/tf lam_2: (C1*t)/tf - C1
constant_var = setdiff(symvar(sol_someic.x_1), [t, tf])
constant_var = 
constant_value = solve(subs(sol_someic.x_1, t, tf) == 3, constant_var)
constant_value = 
sol = structfun(@simplify, subs(sol_someic, constant_var, constant_value), 'uniform', 0)
sol = struct with fields:
x_2: (3*t^2*(2*tf - 2))/(2*tf^3) - (3*t*(2*tf - 2))/tf^2 + 2 x_1: 2*t - (3*t^2*(2*tf - 2))/(2*tf^2) + (t^3*(2*tf - 2))/(2*tf^3) + 1 lam_1: (3*(2*tf - 2))/tf^3 lam_2: -(6*(t - tf)*(tf - 1))/tf^3
and then you would proceed from there.

Sign in to comment.

More Answers (0)

Tags

Products

Community Treasure Hunt

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

Start Hunting!