assume can't constrain vpasolve
4 views (last 30 days)
Show older comments
Hello,
I am attempting to solve a system of nonlinear equations, but unfortunately, vpasolve find answer outside the range I specified and also ignores the constrain condition using "assume".
Here is my code:
% ------------ Parameters --------------------
M = 2;
N = 4;
a = 22.3702/25.4;
beta_10 = 3.41;
k0 = 4.9348;
K2 = 493.2753;
V = [0.7509 1.0000 1.0000 0.7509];
Zb = [-13.0203-6.9290i -19.0747-10.8648i -38.1365-9.9235i -46.2847-14.8522i];
X = [0.1672 -0.2434 0.1502 -0.0871 ; 0.0871 -0.1502 0.2434 -0.1672];
% ------------ Required Functions --------------------
syms g(x) h1(y) h2(y) v(x)
g(x) = 1.177.*sin((pi.*x)./a).^2;
h1(y) = 1-275.*(y-1).^2;
h2(y) = -14.*(y-1);
h(y) = h1(y) + 1i*h2(y);
v(x) = 1.517+1.833.*x.^2;
% ------------ Equation Functions --------------------
x = sym('x',[M N]);
y = sym('y',[M N]);
E1 = []; E2 = []; E3 = []; eq3 = 0; eq4 = 0;
j = 1;
for i = 1:N
Fn = ((cos((beta_10/k0)*y(j,i)*v(x(j,i)))-cos(y(j,i)*v(x(j,i))))/sin(y(j,i)*v(x(j,i))))*(sin(pi*x(j,i))/a);
Ya_G0 = (K2*Fn^2) / (((K2*Fn^2)/(g(x(j,i))*h(y(j,i))))+(Zb(j,i)));
E1 = [E1; imag((K2*Fn^2)/(g(x(j,i))*h(y(j,i)))) == -1*imag(Zb(j,i))];
if i==1 && j==1
Fn_1 = Fn;
Ya_G0_1 = Ya_G0;
else
if mod(i-1,2) == 1
sign = -1;
else
sign = +1;
end
E2 = [E2; (Ya_G0/(Fn)) == (-1)^(j-1)*sign * abs(V(j,i)/V(1,1)) * (sin(y(j,i)*v(x(j,i)))/(sin(y(1,1)*v(x(1,1))))) * (Ya_G0_1/(Fn_1)) ];
end
eq3 = eq3 + Ya_G0;
end
E3 = [E3; eq3 == 2];
E = [E1.',E2.',E3.'];
assume(x,"real"); assumeAlso(x<0.48*a);
assume(y,"positive"); assumeAlso(y,"real");
X_T = X.';
X_trial = X_T(:).';
sol_initial = [X_trial(1:M*N/2),ones(1,M*N/2)];
% sol_range = [all_x_range(1:M*N/2,:);repmat([0.96 1.04],M*N/2,1)];
% sol_initial = sol_range;
x_T = x.'; x_unknown_vector = x_T(:).';
y_T = y.'; y_unknown_vector = y_T(:).';
unknown = [x_unknown_vector(1:M*N/2),y_unknown_vector(1:M*N/2)];
S = vpasolve(E,unknown,sol_initial);
MyFieldNames = fieldnames(S);
MyValuesX = zeros(1,M*N/2); MyValuesY = zeros(1,M*N/2);
for i=1:M*N/2
MyValuesX(1,i) = getfield(S,MyFieldNames{i});
MyValuesY(1,i) = getfield(S,MyFieldNames{i+N/2});
end
round(MyValuesY,3)
I also used the range for "vpasolver" as commented "sol_range" in the above code, but I didn't get the desired result either.
The solution to "y" should be a number around 1.
Thanks for your help in advance.
0 Comments
Accepted Answer
Torsten
on 4 Feb 2024
Moved: Torsten
on 4 Feb 2024
vpasolve is a numerical solver - symbolic commands like "assume" are not respected. But you can set ranges for the variables in "vpasolve" by setting "init_param" to a numerical search interval.
6 Comments
Torsten
on 6 Feb 2024
Edited: Torsten
on 6 Feb 2024
Enum = matlabFunction(E,'Vars',{[x(1,1:N),y(1,1:N)]})
Enum = @(z)real(Enum(z.'));
instead of
Enum = matlabFunction(E);
Enum = @(z)real(Enum(z(1),z(2),z(3),z(4),z(5),z(6),z(7),z(8)));
This is at least correct for the equations you solved above since j was not increased and remained 1 (so I don't know why you created x and y as x(M,N) and y(M,N) and not as x(1,N) and y(1,N))
More Answers (1)
Matt J
on 4 Feb 2024
Edited: Matt J
on 4 Feb 2024
There doesn't appear to be any good reason for you to be using sym variables. Your code doesn't seem to make use of any other Symbolic Math Toolbox functions like diff or simplify.... Just re-implement using non-symbolic variables and solve with lsqnonlin which does allow you to impose bounds on the variables. Or, use matlabFunction to convert your symbolic functions into nonsymbolic ones.
3 Comments
See Also
Categories
Find more on Special Values in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!