How to find solution of non-linear algebraic equations using MATLAB? - matlab

I have 10 non-linear equation,
L1 + 1.3*3*(P1^0.3) + 2*P1 = 12
L2 + 1.2*5*(P2^0.2) + 3*P2 = 20
L3 + 1.15*6*(P3^0.15) + 5*P3 = 28
L4 - L1*0.9*0.4*(X1^-0.1) = 0
L4 - L2*0.8*0.5*(X2^-0.2) = 0
L4 - L3*0.7*0.6*(X3^-0.3) = 0
P1 - 0.4*(X1^0.9) = 0
P2 - 0.5*(X2^0.8) = 0
P3 - 0.6*(X3^0.7) = 0
X1 + X2 + X3 = 10
I do not have any initial guesses for the solutions, however, all variables are essentially non-negative i.e.,
L1>0, L2>0, L3>0, L4>0, P1>0, P2>0, P3>0, X1>0, X2>0, X3>0
I am trying to solve these equations by executing following command,
clear
clc
syms L1 L2 L3 L4 P1 P2 P3 X1 X2 X3
sol=solve([ L1 + 1.3*3*(P1^0.3) + 2*P1 == 12, L2 + 1.2*5*(P2^0.2) + 3*P2 == 20, L3 + 1.15*6*(P3^0.15) + 5*P3 == 28, ...
L4 - L1*0.9*0.4*(X1^-0.1) == 0, L4 - L2*0.8*0.5*(X2^-0.2) == 0, L4 - L3*0.7*0.6*(X3^-0.3) == 0, ...
P1 - 0.4*(X1^0.9) == 0, P2 - 0.5*(X2^0.8) == 0, P3 - 0.6*(X3^0.7) ==0, X1+X2 +X3 == 10, ...
L1>0, L2>0, L3>0, L4>0, P1>0, P2>0, P3>0, X1>0, X2>0, X3>0], [L1, L2, L3, L4, P1, P2, P3, X1, X2, X3]);
But it shows error as
Warning: 32 equations in 11 variables.
> In C:\Program Files\MATLAB\R2013a\toolbox\symbolic\symbolic\symengine.p>symengine at 56
In mupadengine.mupadengine>mupadengine.evalin at 97
In mupadengine.mupadengine>mupadengine.feval at 150
In solve at 170
Warning: Explicit solution could not be found.
> In solve at 179
>>
How to solve these nonlinear equations?
UPDATE: DIFF was actually the difference that would be a number, say
10, 20 or 30. I have removed DIFF from here.

You have 10 equations, but you have 10 variables.
You can help by hand.
Reduce linear equation:
P1 = 0.4(x^(0.9))
P2 = 0.5(x^(0.8))
P3 = 0.6(x^(0.7))
and
L4 = 0.36L1*X1^(-0.1) = 0.4L2*X2^(-0.2) = 0.42L3*X3^(-0.3)
then we get 4 equations on 4 variables:
L1 + 3.9*((0.4^(0.3))*X1^(0.27)) + 0.8*X1^(0.9) - 12 = 0
0.9*(X1^(-0.1))*(X2^(0.2))*L1 + 6*((0.5^0.2)*(x2^(0.16))) + 1.5*X2^(0.8) - 20 = 0
(6/7)*(X1^(-0.1))*(X3^(0.3))*L1 + 6.9*((0.6^0.15)*(X3^(0.105))) + 3*(x3^0.7) - 28 = 0
x1 + X2 + X3 = 10
and try to solve
sol=solve([X1+X2+X3 == 10,L1 + 3.9*((0.4^(0.3))*X1^(0.27)) + 0.8*X1^(0.9) - 12 == 0, 0.9*(X1^(-0.1))*(X2^(0.2))*L1 + 6*((0.5^0.2)*(X2^(0.16))) + 1.5*X2^(0.8) - 20 == 0,(6/7)*(X1^(-0.1))*(X3^(0.3))*L1 + 6.9*((0.6^0.15)*(X3^(0.105))) + 3*(X3^0.7) - 28 == 0, X1 > 0, X2 > 0, X3 > 0, L1 > 0]);
I try to solve it, but I out of memory.
It want to smarter method.

Related

matlab system of equations with one unchanging solution ('q')

I am trying to solve a model of 4 equations, where everything is real. It is essentially a pipe branch problem with "1" being upstream of the pump (with some head on it), and "2" and "3" are downstream w/o head. The units are English.
Anyway, I'm just solving the system of 4 equations and 4 unknowns and looking at a plot of head (ha) vs. total flow rate (Q1). Across this space though I only am collecting points in a vertical line, i.e. the head changes but the flowrate doesn't.
I was thinking the problem may be some variables are being held onto, but I treat "ha" the same as "Q1" so that doesn't seem likely... Realistically, this is matching a system curve to a pump curve, and of course that point moves when the system changes (both flowrate and head), so it seems I am doing something wrong....
Here is the script:
clear sol1 sol2 sol3 sol4 S q h
clc; clearvars; close all;
syms Q1 Q2 Q3 ha
D1 = 1.25/12; Z1 = 0; P1 = 62.4*10; A1 = pi*(1/4)*D1*D1; f1 = 0.011; L1 = 50;
D2 = 0.5/12; Z2 = 25; P2 = 0; A2 = pi*(1/4)*D2*D2; f2 = 0.011; L2 = 100; %V2 = Q2 / A2;
D3 = 0.5/12; Z3 = 10; P3 = 0; A3 = pi*(1/4)*D3*D3; f3 = 0.011; L3 = 100; %V3 = Q3 / A3;
gamma = 62.468;
origPumpData = [0 150; 0.4 148; 0.8 145; 1.2 143; 1.6 141; 2 139; 2.4 138; 2.8 136; 3.2 134; 3.6 132; 4 130; 4.4 128; 4.8 127; 5.2 125; 5.6 124; 6 121; 6.4 118; 6.8 117; 7.2 115; 7.6 113; 8 111; 8.4 110; 8.8 108; 9.2 106; 9.6 104; 10 102; 10.4 100; 10.8 98; 11.2 97;
11.6 94; 12.0 93; 12.4 91; 12.8 89; 13.2 87; 13.6 86; 14 84; 14.4 82; 14.8 80; 15.2 78; 15.6 76; 16 74; 16.4 72; 16.6 70];
pumpData(:,1) = origPumpData(:,1)/448.8312;
pumpData(:,2) = origPumpData(:,2);
polyFit = fit(pumpData(:,1),pumpData(:,2),'poly2');
assume(in(Q1,'real') & Q1 > 0.0001 & Q1 < 1 );
assume(in(Q2,'real') & Q2 > 0.0001 & Q2 < 1 );
assume(in(Q3,'real') & Q3 > 0.0001 & Q3 < 1 ) ;
assume(in(ha,'real') & ha > 0.0001 & ha < 1000.0);
eq1 = #(Q1) polyFit.p1*Q1*Q1 + polyFit.p2*Q1 + polyFit.p3;
eq2 = #(P1,Z1,F1,Q1,A1,L1,D1,P2,Z2,F2,Q2,A2,L2,D2) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F2,L2,D2,Q2,A2) + ha == P2/gamma + ((Q2/A2)^2)/64.4 + Z2;
eq3 = #(P1,Z1,F1,Q1,A1,L1,D1,P3,Z3,F3,Q3,A3,L3,D3) P1/gamma + ((Q1/A1)^2)/64.4 + Z1 - hf(F1,L1,D1,Q1,A1) - hf(F3,L3,D3,Q3,A3) + ha == P3/gamma + ((Q3/A3)^2)/64.4 + Z3;
eq4 = Q1 == Q2 + Q3;
guesses = [0.07116936917086152675558661517184;
0.035125850031368916048762418970837;
0.036043519139492610706824196201003;
303.02361035523126099594683749354];
for i = 1:1:2
disp(i)
disp(Z1)
Z1 = Z1-5
f1 = f1+0.01
f3 = f3 + 0.01
S(i) = vpasolve([eq1(Q1) eq2(P1,Z1,f1,Q1,A1,L1,D1,P2,Z2,f2,Q2,A2,L2,D2) eq3(P1,Z1,f1,Q1,A1,L1,D1,P3,Z3,f3,Q3,A3,L3,D3) eq4], [Q1 Q2 Q3 ha], guesses )
S(i).Q1
S(i).Q2
S(i).Q3
S(i).ha
q(i) = S(i).Q1
h(i) = S(i).ha
guesses = [S(i).Q1 S(i).Q2 S(i).Q3 S(i).ha]'
clear S
end
plot( q, h, '*b');
function hf = hf(f,L,D,Q,A)
hf = f*(L/D)*(1/64.4)*(Q/A)^2;
end
you're solving eq1 == 0(default) and computing Q1, independent of other equations and parameters. that's why you get constant Q1 in every iteration.

Symbolic comprision operation and summation cant get right answer

I'm confused about MATLAB's symbolic operation precedence. My code does not produce the desired output.
syms x1 x2 x3 x4
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]))
I expect the output of
bb=
0.1051
but the actual output is
bb =
logical
0
Why does MATLAB do this?
I use MATLAB R2018b
Case 1: x == y
syms x y z
aa = (x == y) + z
Meaning
aa = [x or y] + z = x + z = y + z
Wherever you have x, you can replace it by y, interchangeably.
It does not check if x and y are the same
Case 2: isequal(x, y)
syms x y z
aa = (x == y) + z
aa = isequal(x, y) + z
Meaning
aa = [check if x and y are the same] + z = 0 + z = z
Modify the given code to this using isequal()
syms x1 x2 x3 x4
aa=((isequal(x1, 0)& isequal(x2, 0) & isequal(x3, 0) & isequal(x4, 0)) + ...
((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]));
Result
bb = 0.1051
I think MATLAB tries to reduce the number of brackets necessary to produce the simplest output. Note that if a is equal to b, a+c is also equal to b+c, so the statement is not wrong. If you call simplify(aa) you even get a simple a == b, which is indeed the simplest form as one can cancel the c on both sides:
syms a b c
aa=(a==b)+c
aa =
a + c == b + c
pretty(aa)
a + c == b + c
simplify(aa)
ans =
a == b
With respect to your edited question: why are you using symbolic variables at all? They are slow and cumbersome (not to speak about the unspeakable evil that is eval). Using numeric computation does yield the correct result:
syms x1 x2 x3 x4
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]))
bb =
logical
0
x1=0.2;x2=0.2;x3=0.2;x4=0.2;
(x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0)
ans =
logical
0
((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000)
ans =
0.1051
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000))
aa =
0.1051
I suspect the problem is somewhere in the belly of subs and/or eval.

How do you factor over a Z field?

I have to factorize a polynomial e.g.
over the field of Z5 using Matlab or Mupad.
And i tried everything read a lot of Matlab and Mupad documentation and still can't find it, so i am guessing it is the math i don't know that's going to help me factor it.
Don't kill a mosquito with a cannon!
You only need to find a root between 0, 1, 2, -2, -1.
Also, given that x5 = x, the problem reduces to finding x such that
2x + 2x^4 + x^3 + 2x^2 - 3 = 0
and since x ≠ 0, x^4 = 1 hence
2x + x^3 + 2x^2 - 1 = 0
Well, let's try!
1: 2 + 1 + 2 - 1 -> -1
2: -1 + 3 - 2 - 1 -> -1
-2: 1 - 3 + 3 - 1 -> 0 -> root!
Then the polynomial is divisible by (x - 3), and you can repeat the procedure with the quotient until there are no roots left.
Addendum
After dividing by (x - 3) we get
x4 + x2 + 1
which we can expressed as
(x2 + 1)2 - x2
or
((x2 + 1) - x)((x2 + 1) + x)
To find the factors of degree 2 programmatically, just try with x2 + ax + b for a and b between 0 and 4.
I found a mupad command to do what i needed.
Still thanks for exaplaining the math behind it.

Does Maxima have a function for solving systems of linear inequalities, that would also be available on Moodle Stack-exams?

What's in the title. I've tried the following:
/*Constants*/
metalMaxTa : 37;/*rand_with_step(20,40,2);*/
elecMaxTa : 52;/*rand_with_step(40,60,2);*/
rateAa : 24;
rateBa : 44;
/*Conditions set by the problem*/
ineq1 : 1/2 * x1 + x2 <= metalMaxTa;
ineq2 : x1 + 1/2*x2 <= elecMaxTa;
ineq3 : x1 >= 0;
ineq4 : x2 >= 0;
/*Solution?*/
sol : solve_rat_ineq([ineq1,ineq2,ineq3,ineq4],[x1,x2]);
but all that returns is this:
In other words, nothing is really done to the input system, the expression is simply printed. The load-command is not available, so I can't actually load the function if it's not available, which seems to be the problem.
EDIT: to_poly_solve() also produces the same output. solve() seems to be available, but returns an empty list, as it is apparently meant for systems of equations, not inequalities.
fourier_elim can handle it.
load('fourier_elim)$
metalMaxTa : 37 $
elecMaxTa : 52 $
rateAa : 24 $
rateBa : 44 $
ineq1 : 1/2 * x1 + x2 <= metalMaxTa$
ineq2 : x1 + 1/2*x2 <= elecMaxTa $
ineq3 : x1 >= 0 $
ineq4 : x2 >= 0 $
sol : fourier_elim([ineq1,ineq2,ineq3,ineq4], [x1, x2]) $
map(disp, sol) $
returns
[x1 = 0, x2 = 0]
[x1 = 52, x2 = 0]
[x2 = 0, 0 < x1, x1 < 52]
[x1 = 0, x2 = 37]
[x1 = 0, 0 < x2, x2 < 37]
134 44
[x1 = ---, x2 = --]
3 3
x2 - 104 44
[x1 = - --------, 0 < x2, x2 < --]
2 3
44
[x1 = 74 - 2 x2, -- < x2, x2 < 37]
3
x2
[0 < x1, x1 < min(52 - --, 74 - 2 x2), 0 < x2, x2 < 37]
2
It uses only strict inequalities in the output and shows equities as
special cases. If you use strict inequalities in equations the output
looks more natural.
0 < x1
x2
x1 < min(52 - --, 74 - 2 x2)
2
0 < x2
x2 < 37

Numerical solutions of a nonlinear equation with different independent values in matlab

For example, if I have this function: g = t^3 - 5*t^2 + 2
And g = [3 4 6 2 9 10 17 1]
I would like to solve the equation for each g[i] and obtain the resulting t vector.
This might guide you:
>> syms t g %// define symbolic variables
>> y = t^3 - 5*t^2 + 2 - g; %// define y so that equation is: y=0
>> g_data = [3 4 6 2 9 10 17 1]; %// define g values
>> n = 1; %// choose first value. Or use a loop: for n = 1:numel(g_data)
>> s = solve(subs(y, g, g_data(n))) %// substitute g value and solve equation y=0
s =
25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) + ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3) + 5/3
5/3 - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)/2 - 25/(18*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - (3^(1/2)*(25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3))*i)/2
5/3 - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)/2 - 25/(18*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) + (3^(1/2)*(25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3))*i)/2
>> double(s) %// show solutions as floating point values
ans =
5.039377328113847
-0.019688664056924 + 0.445027607060817i
-0.019688664056924 - 0.445027607060817i