Spurious solutions when solving system of equations - matlab

I'm trying to solve a system of equations in Matlab.
The system of equations is defined as follows:
syms x1 x2 lambda
Grad =
2*lambda*x1 + (8*x1*(((x2 - 10)^2 + x1^2)^(1/2) - 10))/((x2 - 10)^2 + x1^2)^(1/2) + (4*x1*(((x2 + 10)^2 + x1^2)^(1/2) - 10))/((x2 + 10)^2 + x1^2)^(1/2) - 5
2*lambda*x2 + (4*(((x2 - 10)^2 + x1^2)^(1/2) - 10)*(2*x2 - 20))/((x2 - 10)^2 + x1^2)^(1/2) + (2*(((x2 + 10)^2 + x1^2)^(1/2) - 10)*(2*x2 + 20))/((x2 + 10)^2 + x1^2)^(1/2) - 10
x1^2 + x2^2 - 36
I tried solving it using:
[X1 X2 LAMBDA] = solve([Grad(1) == 0, Grad(2) == 0, Grad(3) == 0],[x1, x2, lambda]);
and
[X1 X2 LAMBDA] = solve(Grad,[x1, x2, lambda]);
But I get the error:
Warning: Possibly spurious solutions.
> In symengine
In mupadengine/evalin (line 102)
In mupadengine/feval (line 158)
In solve (line 292)
In Ex (line 63)
I don't understand why Matlab does this, I have three equations with three variables, so Matlab should be able to find a solution right?

The answer can be fixed by substituting the values back into the equation and checking whether or not the values are correct:
[X1, X2, LAMBDA] = solve([Grad(1) == 0, Grad(2) == 0, Grad(3) == 0],[x1, x2, lambda]);
clc;
X1 = double(X1); X2 = double(X2); LAMBDA = double(LAMBDA);
X1 = real(X1); X2 = real(X2); LAMBDA = real(LAMBDA);
i = 1;
while i < 17
Sub(i,:) = subs(Grad,[x1, x2, lambda],[X1(i),X2(i),LAMBDA(i)]);
if abs(Sub(i,1)) < 0.00001 & abs(Sub(i,2)) < 0.00001 & abs(Sub(i,3)) < 0.00001
I(i,:) = i;
Var(i,1) = X1(i); Var(i,2) = X2(i); Var(i,3) = LAMBDA(3);
end
i = i + 1;
end
I already knew the approximate values of my x1 and x2 values (from another optimization technique I used), therefore I could easily run a check if the correct values were found (they were). I also knew that only the real part was relevant.
FF = find(Var(:,1)>5&Var(:,1)<6&Var(:,2)>1&Var(:,2)<2);
RealVar = Var(FF,:)
Which gave me the variables I was looking for.

Related

How to fix Matlab Solve Calculation Error/solver gives a variable back instead of a numerical answer?

I'm trying to solve for q. However, this error, in the image attached, shows up and I have no clue how to fix it. The code runs smoothly without the fifth blob [k5*z5/(1+q*(k5-1))] in the equation and it solves for q. But when I add it to the equation, you get the error... Help....
z1 = 0.01188354;
z2 = 0.20291147;
z3 = 0.03386809;
z4 = 0.6087344;
z5 = 0.1426025;
k1 = 0.00211577;
k2 = 433.816504;
k3 = 0.00651267;
k4 = 12.8652437;
k5 = 3.25E-06;
syms q
eqn = k1*z1/(1+q*(k1-1)) + k2*z2/(1+q*(k2-1)) + k3*z3/(1+q*(k3-1)) + k4*z4/(1+q*(k4-1))+ k5*z5/(1+q*(k5-1)) == 1;
qvalue = solve(eqn,q,'Real',true)
You messed a bit with solve. It looks like your equation doesn't have real solution and you force it with 'Real',true It should be:
z1 = 0.01188354;
z2 = 0.20291147;
z3 = 0.03386809;
z4 = 0.6087344;
z5 = 0.1426025;
k1 = 0.00211577;
k2 = 433.816504;
k3 = 0.00651267;
k4 = 12.8652437;
k5 = 3.25E-06;
syms q
eqn = k1*z1/(1+q*(k1-1)) + k2*z2/(1+q*(k2-1)) + k3*z3/(1+q*(k3-1)) + k4*z4/(1+q*(k4-1))+ k5*z5/(1+q*(k5-1)) == 1;
qvalue = solve(eqn,q)
And the output is:
root(z^5 - (553951988707451897271725042874967932463648393519489496501295701298760653356885564069*z^4)/146344515065711958525050250689493211538989295698771861545387136571113311336350613504 + (877647369043978904163970290106419962713606423192038983322127636310825879207936*z^3)/164487327751721471763565140886077743965784030575734255347857322244873703346919 - (3796080934806054258394941458065140559250786119491250988496078448019381612969984*z^2)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + (838076006172751803233223399262272123114675605549658858976242221943722830987264*z)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + 21452770321210561747759866301918995558818778263453224281332504760441104236544/1151411294262050302344955986202544207760488214030139787435001255714115923428433, z, 1)
root(z^5 - (553951988707451897271725042874967932463648393519489496501295701298760653356885564069*z^4)/146344515065711958525050250689493211538989295698771861545387136571113311336350613504 + (877647369043978904163970290106419962713606423192038983322127636310825879207936*z^3)/164487327751721471763565140886077743965784030575734255347857322244873703346919 - (3796080934806054258394941458065140559250786119491250988496078448019381612969984*z^2)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + (838076006172751803233223399262272123114675605549658858976242221943722830987264*z)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + 21452770321210561747759866301918995558818778263453224281332504760441104236544/1151411294262050302344955986202544207760488214030139787435001255714115923428433, z, 2)
root(z^5 - (553951988707451897271725042874967932463648393519489496501295701298760653356885564069*z^4)/146344515065711958525050250689493211538989295698771861545387136571113311336350613504 + (877647369043978904163970290106419962713606423192038983322127636310825879207936*z^3)/164487327751721471763565140886077743965784030575734255347857322244873703346919 - (3796080934806054258394941458065140559250786119491250988496078448019381612969984*z^2)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + (838076006172751803233223399262272123114675605549658858976242221943722830987264*z)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + 21452770321210561747759866301918995558818778263453224281332504760441104236544/1151411294262050302344955986202544207760488214030139787435001255714115923428433, z, 3)
root(z^5 - (553951988707451897271725042874967932463648393519489496501295701298760653356885564069*z^4)/146344515065711958525050250689493211538989295698771861545387136571113311336350613504 + (877647369043978904163970290106419962713606423192038983322127636310825879207936*z^3)/164487327751721471763565140886077743965784030575734255347857322244873703346919 - (3796080934806054258394941458065140559250786119491250988496078448019381612969984*z^2)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + (838076006172751803233223399262272123114675605549658858976242221943722830987264*z)/1151411294262050302344955986202544207760488214030139787435001255714115923428433 + 21452770321210561747759866301918995558818778263453224281332504760441104236544/1151411294262050302344955986202544207760488214030139787435001255714115923428433, z, 4)
root(z^5 - (553951988707451897271725042874967932463648393519489496501295701298760653356885564069*z^4)

Symbolic summation in matlab

I'm using MATLAB R2014b. I pasted code from example in documentation:
https://www.mathworks.com/help/symbolic/symbolic-summation.html
syms x
assume(x > 1)
S_sum = sum(x.^(1:10))
S_symsum = symsum(x^k, k, 1, 10)
and I got an error:
Undefined function or variable 'k'.
Error in SymbolicExperience2 (line 4)
S_symsum = symsum(x^k, k, 1, 10)
How do you think what's wrong? Should I migrate to MATLAB R2016b? Thank you.
That documentation page assumes you're working through the entire page, not starting midway, hence you missed the declaration of k as a symbolic variable:
syms k
syms x
assume(x > 1)
S_sum = sum(x.^(1:10))
S_symsum = symsum(x^k, k, 1, 10)
S_sum =
x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x
S_symsum =
x^11/(x - 1) - x/(x - 1)

Matlab: Nonlinear equation Optimization

This question is related to the post below:
Matlab: Nonlinear equation solver
With 8 variables x0-x8, I got great results. However, when I increase to solving 10 variables, the results aren't so good. Even if my "guess" is close to the actual value and change the max iteration to 100000, the results are still poor. Is there anything else I can do?
Here is the code:
function F = fcn(x)
F=[x(6) + x(7) + x(8) + x(9) + x(10)-2 ;
x(6)*x(1) + x(7)*x(2) + x(8)*x(3) + x(9)*x(4) + x(10)*x(5) ;
x(6)*x(1)^2 + x(7)*x(2)^2 + x(8)*x(3)^2 + x(9)*x(4)^2 + x(10)*x(5)-2/3 ;
x(6)*x(1)^3 + x(7)*x(2)^3 + x(8)*x(3)^3 + x(9)*x(4)^3 + x(10)*x(5) ;
x(6)*x(1)^4 + x(7)*x(2)^4 + x(8)*x(3)^4 + x(9)*x(4)^4 + x(10)*x(5)-2/5 ;
x(6)*x(1)^5 + x(7)*x(2)^5 + x(8)*x(3)^5 + x(9)*x(4)^5 + x(10)*x(5) ;
x(6)*x(1)^6 + x(7)*x(2)^6 + x(8)*x(3)^6 + x(9)*x(4)^6 + x(10)*x(5)-2/7 ;
x(6)*x(1)^7 + x(7)*x(2)^7 + x(8)*x(3)^7 + x(9)*x(4)^7 + x(10)*x(5) ;
x(6)*x(1)^8 + x(7)*x(2)^8 + x(8)*x(3)^8 + x(9)*x(4)^8 + x(10)*x(5)-2/9 ;
x(6)*x(1)^9 + x(7)*x(2)^9 + x(8)*x(3)^9 + x(9)*x(4)^9 + x(10)*x(5)
];
end
clc
clear all;
format long
x0 = [0.90; 0.53; 0; -0.53; -0.90; 0.23; 0.47; 0.56; 0.47; 0.23]; %Guess
F0 = fcn(x0);
[x,fval]=fsolve(#fcn, x0) %solve without optimization
options = optimset('MaxFunEvals',100000, 'MaxIter', 100000); %optimization criteria
[x,fval]=fsolve(#fcn, x0, options) %solve with optimization
Here are the actual values I'm trying to get:
x1 = 0.906179
x2 = 0.538469
x3 = 0.000000
x4 = -0.53846
x5 = -0.906179
x6 = 0.236926
x7 = 0.478628
x8 = 0.568888
x9 = 0.478628
x10 = 0.236926
The result of such optimization functions like fsolve depends on the initial point very much. A non-linear function like yours can have a lot of local minima and your option is to randomly dice the initial point and hope it will lead the optimization to a better minimum than before.
You can do like this:
clear;
options = optimset('MaxFunEvals',2000, 'MaxIter', 1000, 'Display', 'off');
n = 200; %how many times calculate f with different initial points
z_min = 10000; %the current minimum Euclidian distance between fval and zeros
for i=1:n
x0 = rand(10, 1);
[x,fval]=fsolve(#fcn, x0, options);
z = norm(fval);
if (z < z_min)
z_min = z;
x_best = x;
f_best = fval;
display(['i = ', num2str(i), '; z_min = ', num2str(z_min)]);
display(['x = ', num2str(x_best')]);
display(['f = ', num2str(f_best')]);
fprintf('\n')
end
end
Change the maximum number of the optimization loops and look at the z value. It shows how close your function is to a zero vector.
The best solution I've got so far:
x_best =
0.9062
-0.9062
-0.5385
0.5385
0.0000
0.2369
0.2369
0.4786
0.4786
0.5689
f_best =
1.0e-08 * %these are very small numbers :)
0
0.9722
0.9170
0.8740
0.8416
0.8183
0.8025
0.7929
0.7883
0.7878
For this solution z_min is 2.5382e-08.

fminsearch error: DOUBLE cannot convert the input expression into a double array

I am encountering a problem during an optimization exercise. I am trying to use fminsearch() in matlab to solve it. The following error is generated when the code is run:
The following error occurred converting from sym to double: Error
using symengine (line 59) DOUBLE cannot convert the input expression
into a double array. If the input expression contains a symbolic
variable, use VPA.
Error in fminsearch (line 190) fv(:,1) = funfcn(x,varargin{:});
Error in Optimization (line 22) sol2 = fminsearch(J, x0);
The script I use can be seen below. The f is the minimization problem where g1 & g2 are constraints. The p is there so that I can turn it into for loop later.
syms x1 x2 x3 x4;
syms p;
f = x1.^4 - x3.^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1.^2 + x2.^2 + x3.^2 + x4.^2 - 1;
g2 = x1 + x3 - 1;
x0 = [2 2 2 2];
p = 3;
J = #(x1,x2,x3,x4) sym(f + p * g1.^2 + g2.^2);
sol2 = fminsearch(J, x0);
This Stackoverflowpost has the same problem but in another perspective.According to this post it might be a problem with allocating the in a valid way. I tried a few different ways to solve my problem. I have tried matlabFunction() and putting the function in a seperate file.
If the input expression contains a symbolic variable, use the VPA function instead?
Thanks in advance for the help.
fminsearch is designed for numerical minimization. There is little point in using symbolic math in this case (it can be used, but it will be slower, complicate your code, and the results will still be in double precison). Second, if you read the documentation and look at the examples for fminsearch, you'll see that it requires a function that takes a single vector input (as opposed to four scalars in your case). Here's how you could rewrite your equations using anonymous functions:
f = #(x)x(1).^4 - x(3).^2 + x(1).*x(3) + x(2).*x(4) - 5*x(2) + 3;
g1 = #(x)x(1).^2 + x(2).^2 + x(3).^2 + x(4).^2 - 1;
g2 = #(x)x(1) + x(3) - 1;
x0 = [2 2 2 2];
p = 3;
J = #(x)f(x) + p*g1(x).^2 + g2(x).^2;
sol2 = fminsearch(J, x0)
this returns
sol2 =
0.149070165097281 1.101372214292880 0.326920462283209 -0.231885482601008
Using symbolic math and subs:
syms x1 x2 x3 x4;
f = x1^4 - x3^2 + x1*x3 + x2*x4 - 5*x2 + 3;
g1 = x1^2 + x2^2 + x3^2 + x4^2 - 1;
g2 = x1 + x3 - 1;
x0 = [2 2 2 2];
p = sym(3);
J = #(X)subs(f + p*g1^2 + g2^2,[x1 x2 x3 x4],X);
sol2 = fminsearch(J, x0)
which returns identical results.

MATLAB's 'solve,' applied to a system of equations, gives me a solution that doesn't satisfy one of the equations

I'm using the MATLAB function 'solve' to solve a system of six equations and six variables. In the solution it gives, at least one of the equations seems not to be satisfied. Here's my code for the problem:
% given parameters
alpha = .05; % exogenous rate of cost reductions
sigma = .05; % exogenous uncertainty (infinitessimal st dev)
p0 = 10; % initial carbon price
p1 = 50; % carbon price under policy
lambda_p = .05; % Poisson arrival rate of policy
lambda_q = .01; % Probability of reversion to no policy state
r = .03; % discount rate
% exponents for solution
beta1 = (.5*sigma^2 + alpha + sqrt((.5*sigma^2 + alpha)^2 + 2*sigma^2*(r+lambda_p)))/sigma^2;
beta2 = (.5*sigma^2 + alpha - sqrt((.5*sigma^2 + alpha)^2 + 2*sigma^2*(r+lambda_p)))/sigma^2;
beta3 = (.5*sigma^2 + alpha - sqrt((.5*sigma^2 + alpha)^2 + 2*sigma^2*r))/sigma^2;
beta4 = (.5*sigma^2 + alpha - sqrt((.5*sigma^2 + alpha)^2 + 2*sigma^2*(r+lambda_p+lambda_q)))/sigma^2;
syms a0 a1 ka ks B1 B2
S = solve(p1 - a1 == (lambda_p*lambda_q*ka*a1^beta3 + lambda_q*ks*a1^beta4)/(lambda_p + lambda_q), ...
-1 == (lambda_p*lambda_q*ka*beta3*a1^(beta3-1) + lambda_q*ks*beta4*a1^(beta4-1))/(lambda_p + lambda_q), ...
p0 - a0 == B1*a0^beta1 + B2*a0^beta2 - lambda_p*a0/(alpha+lambda_p+r) + lambda_p*p1/(r+lambda_p), ...
-1 == B1*beta1*a0^(beta1-1) + B2*beta2*a0^(beta2-1) - lambda_p/(alpha+lambda_p+r), ...
(lambda_p*lambda_q*ka*a1^beta3 - lambda_p*ks*a1^beta4)/(lambda_p + lambda_q) == B1*a1^beta1 + B2*a1^beta2 - lambda_p*a1/(alpha+lambda_p+r) + lambda_p*p1/(r+lambda_p), ...
(lambda_p*lambda_q*ka*beta3*a1^(beta3-1) - lambda_p*ks*beta4*a1^(beta4-1))/(lambda_p + lambda_q) == B1*beta1*a1^(beta1-1) + B2*beta2*a1^(beta2-1) - lambda_p/(alpha+lambda_p+r));
The third equation isn't satisfied. When I obtain the output S, I calculate
>> p0-S.a0
ans =
-51.139888401602841212761952348352
and
>> S.B1*S.a0^beta1 + S.B2*S.a0^beta2 - lambda_p*S.a0/(alpha+lambda_p+r) + lambda_p*p1/(r+lambda_p)
ans =
4.58887467530944339251344448794
which aren't equal. Any ideas as to what's wrong? Thanks.