Having trouble with nonpolynomial equation systems

5 views (last 30 days)
Hi everyone. I have the following equation system that I would like to solve:
eq1 = -l*cos(teta) + x == 0;
eq2 = -l*sin(teta) -0.5 + y == 0;
eq3 = -0.5*l*cos(teta)+d*cos(fi) == 0;
eq4 = -0.5*l*sin(teta) - d*sin(fi) + y == 0;
eq5 = sin(gama) == (0.5*d)/R;
eq6 = fi + gama + beta == 90;
However, when I use VPA solve, the command window displays the following error:
"Symbolic parameters not supported in nonpolynomial equations."
The thing is that I'm doing an assingment and thay have provided the data in terms of parameters. How should I even begin to tackle this problem?

Answers (3)

John D'Errico
John D'Errico on 29 Oct 2022
Edited: John D'Errico on 29 Oct 2022
You have how many equations? (6 by my count.)
You have how many parameters? l, teta, x, y, fi, d, R, gama. That is 8 parameters. Well, 9 if we count beta as a variable, But I will bet you intended to write teta, not beta, so that was a typo.
vpasolve CANNOT solve a problem with more unknowns than equations. That is called an under-determined problem.
You must have a value for exactly two of those parameters, since you must have as many unknowns as equations. If you have more equations than unknowns, then vpasolve will again fail, because it cannot handle an over-determined problem either.
And, by the way, sin and cos in MATLAB are defined in RADIANS, NOT degrees. Yet you are clearly trying to use degrees. If you want to work in degrees, then you need to use sind and cosd, which assume degree inputs.
I'll guess arbitrarily that R == 1. This is probably not a bad assumption, since it will merely scale the problem. R, D, l, x, y all will have units of length. Next, I'll use L, NOT the lower case l, which is far too easily confused with the number 1 in code. Never make that mistake, as it will cause you innumerable problems down the line.
The idea though is to non-dimensionalize the problem, by defining one of your unknown length variables. Then later on, you can scale if all, according to length. That is probably appropriate here.
But still that will leave you with too many unknowns. So I'll pick gama, and set it arbitrarily to 30 degrees. This is just an arbitrary choice on my part.
Next, store all of those equations in one variable, a vector. Learn to use vectors instead of numbered variable names.
R = 1;
gama = 30; % just a wild guess
syms x y L d fi teta
eq(1) = -L*cosd(teta) + x == 0;
eq(2) = -L*sind(teta) + -0.5 + y == 0;
eq(3) = -0.5*L*cosd(teta)+d*cosd(fi) == 0;
eq(4) = -0.5*L*sind(teta) - d*sind(fi) + y == 0;
eq(5) = sind(gama) == (0.5*d)/R;
eq(6) = fi + gama + teta == 90;
sol = vpasolve(eq,[x y L d fi teta])
sol = struct with fields:
x: 1.4290944219604424968481254065135 y: 0.89917444699420834234388518011439 L: 1.4837961807511108819366491706454 d: 1.0 fi: 44.393896258819878994986420070614 teta: 15.606103741180121005013579929386
Of course, this result is contingent on knowing the value of gama, which I set to 30 degrees. And it will scale with r. So if you double the value of R, then x,y, and L will all double commensurately.
  5 Comments
Imanol Fernandez de arroyabe Zabala
If I try to solve with the following code, the command widnow displays that it's unable to find an explicit solution:
syms L R d
L = L;
d = d;
R = R;
syms x y fi teta beta gama
eq(1) = -L*cosd(teta) + x == 0;
eq(2) = -L*sind(teta) + -0.5 + y == 0;
eq(3) = -0.5*L*cosd(teta)+d*cosd(fi) == 0;
eq(4) = -0.5*L*sind(teta) - d*sind(fi) + y == 0;
eq(5) = sind(gama) == (0.5*d)/R;
eq(6) = fi + gama + beta == 90;
sol = solve(eq,[x y fi teta beta gama])
Warning: Unable to find explicit solution. For options, see help.
sol = struct with fields:
x: [0×1 sym] y: [0×1 sym] fi: [0×1 sym] teta: [0×1 sym] beta: [0×1 sym] gama: [0×1 sym]
Does this mean the equation system is too complicated? If so, how can I go about this?
Thanks for answering my questions by the way, you are being inmensely helpful
John D'Errico
John D'Errico on 29 Oct 2022
Edited: John D'Errico on 29 Oct 2022
You did not set L, D, and R to ANYTHING. You set them to themselves!!!!!!!
L = L;
d = d;
R = R;
That adds NO information. You need to set them to a NUMBER. Otherwise, you are now trying to solve a systemm of equations with symbolic parameters. VPASOLVE CANNOT HANDLE THAT CASE. In fact, neither apparently in this case, can solve. The problem reduces to a nonlinear one, where most nonlinear equatinos you can write down have no analytical solution.

Sign in to comment.


Paul
Paul on 29 Oct 2022
Edited: Paul on 29 Oct 2022
Equations 1, 2, 5, and 6 can be solved for a parametric solution under some (I hope) reasonable asumptions on the variables. I changed all fo the angles to radians.
syms L R d positive
syms x y
syms fi teta beta gama real
assumeAlso(-sym(pi) <= teta < sym(pi));
assumeAlso(-sym(pi) <= fi < sym(pi));
assumeAlso(0 <= gama <= sym(pi)/2);
assumeAlso(-sym(pi) <= beta < sym(pi));
assumeAlso(d <= 2*R);
eq(1) = -L*cos(teta) + x == 0;
eq(2) = -L*sin(teta) + -0.5 + y == 0;
eq(3) = -0.5*L*cos(teta)+d*cos(fi) == 0;
eq(4) = -0.5*L*sin(teta) - d*sin(fi) + y == 0;
eq(5) = sin(gama) == (0.5*d)/R;
eq(6) = fi + gama + beta == sym(pi)/2;
sol = solve(eq([1 2 5 6]),[x y fi teta beta gama],'ReturnConditions',true);
sol.conditions
ans = 
sol.x
ans = 
sol.y
ans = 
sol.fi
ans = 
sol.teta
ans = 
sol.beta
ans = 
sol.gama
ans = 
I will confess I don't totally understand this result. eq(5) combined with the assumptions should yield a unique solution for gama.
Adding eq(3) and/or eq(4) into the mix results in no solution.

Walter Roberson
Walter Roberson on 2 Nov 2022
Moved: Walter Roberson on 2 Nov 2022
You can work step-wise to get further but you run into problems.
syms L R d
L = L;
d = d;
R = R;
syms x y fi teta beta gama real
eq(1) = -L*cosd(teta) + x == 0;
eq(2) = -L*sind(teta) + -0.5 + y == 0;
eq(3) = -0.5*L*cosd(teta)+d*cosd(fi) == 0;
eq(4) = -0.5*L*sind(teta) - d*sind(fi) + y == 0;
eq(5) = sind(gama) == (0.5*d)/R;
eq(6) = fi + gama + beta == 90;
partx = solve(eq(1), x, 'returnconditions', true);
simplify(partx.conditions)
ans = 
eq2 = subs(eq(2:end), x, partx.x);
party = solve([eq2(1), partx.conditions], y, 'returnconditions', true);
simplify(party.conditions)
ans = 
eq3 = subs(eq2(2:end), y, party.y);
partfi = solve([eq3(1), party.conditions], fi, 'returnconditions', true);
partfi_fi = subs(partfi.fi, partfi.parameters, 0);
simplify(partfi.conditions)
ans = 
Two solutions for fi that are negatives of each other, but the conditions are the same. We can process them separately... a bit of a nuisance but certainly possible.
eq4_a = subs(eq3(2:end), fi, partfi_fi(1));
eq4_b = subs(eq3(2:end), fi, partfi_fi(2));
partteta_a = solve(eq4_a(1), teta, 'returnconditions', true);
partteta_b = solve(eq4_b(1), teta, 'returnconditions', true);
simplify(partteta_a.teta)
ans = 
z
simplify(partteta_a.conditions)
ans = 
simplify(partteta_b.teta)
ans = 
z
simplify(partteta_b.conditions)
ans = 
These outputs tell you that the value of teta is the set of values, here named z such that all of those conditions apply. In the asin() the L and d are pure inputs; you run a calculation on them and take the arcsine in radians, and divide by . If you look at the part and mentally multiply through by the 360, you will see that you are doing a conversion from between radians and degrees. With "element of Z" part, the test is effectively saying that sin() of some integer number of degrees has to equal the L^2 etc expression. To be sure, you can construct such situations, but for arbitrary L and d, it will mostly not be the case.
The second condition, that (L^2-4*d^2+1)/L must be in the range -2 to +2 is probably not difficult to satisfy.
The third condition allows two possibilities, the second of which is that L*sin(pi*z/180) == -1 which is sin(pi*z/180) == -1/L . We have been tacitly assuming that L is positive, so this has the effect of forcing z to be in one of two particular quadrants where sind() is negative . But you could also reverse it and say that sin(pi*z/180) = -1/L so pi*z/180 = asin(-l/L) so z = 180*asin(-1/L)/pi . And that would have to be simultaneously true with the first condition that the asin() of a different expression had to be z. Perhaps not impossible, but it really restricts the conditions under which there is any solution.
The signIm() of an expression times i ... well first you have to ask whether the expression can be purely imaginary so that multiplying by i gives a real value. The answer to that is No, because the first condition requires a linear function of z to be an element of Z which is integers, so z must be real-valued . So that is signIm() of a real value multiplied by i . Which is defined as sign() of the real value. We thus arrive at the condition that (L*sin(pi*z/180) + 1)/d > 0 . So L*sin(pi*z/180)/d + 1/d > 0 so L*sin(pi*z/180)/d > -1/d and so sin(pi*z/180) > -1/L . Whereas the previous condition in the or was that sin(pi*z/180) = -1/L . Combine the two and we get sin(pi*z/180) >= -1/L . That might not be too bad to satisfy.
But... these are all conditions that are independent of any of the variables in the equation, dependent only on the input constants L and d . Especially with that first condition imposing an "integer number of degrees" part, most L and d combinations cannot satisfy the equations, so for most L and d combinations, there is no solution at all.
There is no general solution
teta_parm = solve(partteta_a.conditions, partteta_a.parameters, 'returnconditions', true)
Warning: Unable to find explicit solution. For options, see help.
teta_parm = struct with fields:
z: [0×1 sym] parameters: [1×0 sym] conditions: [0×1 sym]
But for a comparitively small number of combinations of L and d there are solutions. If we assume that the z in the above exists and has some definite value, we can continue the analysis, even if we cannot reasonably tell you what z is (though I guess we might be able to define z explicitly by breaking apart the first condition and generating the asin() )
eq5_a = subs(eq4_a(2:end), teta, partteta_a.teta);
eq5_b = subs(eq4_b(2:end), teta, partteta_b.teta);
partgama_a = solve(eq5_a(1), gama, 'returnconditions', true);
partgama_a_gama = subs(partgama_a.gama, partgama_a.parameters, 0);
partgama_b = solve(eq5_b(1), gama, 'returnconditions', true);
partgama_b_gama = subs(partgama_b.gama, partgama_b.parameters, 0);
simplify(partgama_a.conditions)
ans = 
simplify(partgama_b.conditions)
ans = 
eq6_aa = subs(eq5_a(2:end), gama, partgama_a_gama(1));
eq6_ab = subs(eq5_a(2:end), gama, partgama_a_gama(2));
eq6_ba = subs(eq5_b(2:end), gama, partgama_b_gama(1));
eq6_bb = subs(eq5_b(2:end), gama, partgama_b_gama(2));
partbeta_aa = solve(eq6_aa, beta, 'returnconditions', true);
%partbeta_aa.beta
simplify(partbeta_aa.conditions)
ans = 
partbeta_ab = solve(eq6_ab, beta, 'returnconditions', true);
%partbeta_ab.beta
simplify(partbeta_ab.conditions)
ans = 
partbeta_ba = solve(eq6_ba, beta, 'returnconditions', true);
%partbeta_ba.beta
simplify(partbeta_ba.conditions)
ans = 
partbeta_bb = solve(eq6_bb, beta, 'returnconditions', true);
%partbeta_bb.beta
simplify(partbeta_bb.conditions)
ans = 
So if we did generate an explicit value for z in terms of the asin() lf L^2 and so on, then it looks like we would be able to get all the way through the other conditions, generating partial solutions as we went. Not shown here, but you would then be able to back-substitute to get all the way back to explicit equations for everything.

Tags

Community Treasure Hunt

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

Start Hunting!