fsolve exitflag -2, 9 equations 9 variables

The way I am solving it:
function h = tst(x)
h(1)= x(7) - 50;
h(2)= x(2) + 20;
h(3)= x(3) + 40;
h(4) = -(1.29e9) * (x(4) * abs(x(4))) + 1e10*( x(7)^2 - x(8)^2 );
h(5) = -(1.29e9) * (x(5) * abs(x(5))) + 1e10*( x(8)^2 - x(9)^2 );
h(6) = -(1.29e9) * (x(6) * abs(x(6))) + 1e10*( x(9)^2 - x(7)^2 );
h(7) = x(1) + x(6) - x(4) ;
h(8) = x(2) + x(4) - x(5) ;
h(9) = x(3) + x(5) - x(6) ;
end
and I am trying to solve it like:
x0 = abs(randn(9, 1))
fun = @(x) tst(x);
options = optimoptions('fsolve','Display','iter','MaxIterations',2000,...
'MaxFunctionEvaluations',3000,'TolFun',1e-30,'TolX',1e-30)
[x_sol,fval,exitflag,output]= fsolve(fun,x0, options)
my fval is:
0 0 0 -0.0027 0.0006 0.0022 0 -0.0000 0
And this is the message:
No solution found.
fsolve stopped because the relative size of the current step is less than the
value of the step size tolerance squared, but the vector of function values
is not near zero as measured by the value of the function tolerance.
So what is the problem here? Why this cannot be solved?

 Réponse acceptée

Torsten
Torsten le 2 Juin 2022
Modifié(e) : Torsten le 2 Juin 2022
delta_lambda = 0.1;
lambda_start = delta_lambda;
lambda_end = 1.0;
lambda = lambda_start:delta_lambda:lambda_end;
n = numel(lambda);
x0 = ones(9,1);
x_guess = x0;
for i = 1:n
x = fsolve(@(x)lambda(i)*tst(x)+(1-lambda(i))*(tst(x)-tst(x0)),x_guess);
xguess = x
end
tst(x)
function h = tst(x)
h(1)= x(7) - 50;
h(2)= x(2) + 20;
h(3)= x(3) + 40;
h(4) = -(1.29e9) * (x(4) * abs(x(4))) + 1e10*( x(7)^2 - x(8)^2 );
h(5) = -(1.29e9) * (x(5) * abs(x(5))) + 1e10*( x(8)^2 - x(9)^2 );
h(6) = -(1.29e9) * (x(6) * abs(x(6))) + 1e10*( x(9)^2 - x(7)^2 );
h(7) = x(1) + x(6) - x(4) ;
h(8) = x(2) + x(4) - x(5) ;
h(9) = x(3) + x(5) - x(6) ;
end

6 commentaires

Daniel H.
Daniel H. le 2 Juin 2022
Actually, this is giving the same results as I got before with lower TolFun and TolX. If you just set the 'TolFun',1e-30,'TolX',1e-30 the exit flag would be -2 again. The variables are the same but my fval is non zero again.
Now fval is:
0 0 0 -0.0021 0.0053 -0.0034 0 0.0000 -0.0000
Torsten
Torsten le 2 Juin 2022
Modifié(e) : Torsten le 2 Juin 2022
Do you have in mind how large your residuals in equations 4,5 and 6 are ? The variable values squared are multiplied by 1e10 and 1.3e9, respectively ! How can you then demand a TolX and TolFun of 1e-30 ?????
Just divide equations 4-6 by 1.0e9, and fsolve will work like a charm.
Daniel H.
Daniel H. le 2 Juin 2022
Thanks @Torsten, actually because this value (1.29e9) is not just a coefficient and actually is a function called and in each equation has a different value (but on the same scale), this did not came to my mind :)
Torsten
Torsten le 2 Juin 2022
For the large scale system, you should first check the order of the coeffcients of the equations and then scale each equation by a suitable factor.
Daniel H.
Daniel H. le 2 Juin 2022
Yes that is wise
Hi, just reform your equations:
From:
h(4) = -(1.29e9) * (x(4) * abs(x(4))) + 1e10*( x(7)^2 - x(8)^2 );
h(5) = -(1.29e9) * (x(5) * abs(x(5))) + 1e10*( x(8)^2 - x(9)^2 );
h(6) = -(1.29e9) * (x(6) * abs(x(6))) + 1e10*( x(9)^2 - x(7)^2 );
To:
h(4) = -(x(4) * abs(x(4))) + 1e10*( x(7)^2 - x(8)^2 )/(1.29e9);
h(5) = -(x(5) * abs(x(5))) + 1e10*( x(8)^2 - x(9)^2 )/(1.29e9);
h(6) = -(x(6) * abs(x(6))) + 1e10*( x(9)^2 - x(7)^2 )/(1.29e9);
and then the result will be got without difficult:
x1: 59.9999999999115
x2: -19.9999999999964
x3: -40.0000000000186
x4: 29.2820323027161
x5: 9.28203230277714
x6: -30.717967697215
x7: 50.0000000000274
x8: -48.5521764665935
x9: -48.4043035184201

Connectez-vous pour commenter.

Plus de réponses (3)

Walter Roberson
Walter Roberson le 2 Juin 2022

0 votes

If you use the symbolic toolbox, you can work stepwise to solve except for the 4th and 6th equation, solving for variables except x4 and x8. At that point you have to start taking branches of solutions and solving each branch. There is at least one exact solution.

10 commentaires

Daniel H.
Daniel H. le 2 Juin 2022
One thing that I should mention, this example is just a toy example, actually my problem right now has 40 variables, and in future would be definitely much bigger than that.
So what I did was to water my problem down to this one, because for the 40 variables I am getting the same message.
The solution you are suggesting can also help me for larger scale problems?
Torsten
Torsten le 2 Juin 2022
It can help if this system is representative for the large scale problem. So does the large scale problem have a similar structure to your toy problem ?
Daniel H.
Daniel H. le 2 Juin 2022
It has exactly the same structure, just the number of equations and variables would be larger.
So, if it can help, how I can do that? I have not used symbolic math toolbox.
is there a particular reason you have x4*abs(x4) instead of sign(x4) * x4^2 ? Can we assume real variables only?
Daniel H.
Daniel H. le 2 Juin 2022
Yes they are all real numbers, and there is no difference between sign(x4) * x4^2 and x4*abs(x4), is it? :)
The most important thing is this part of the equations; (1.29e9) * (x(a) * abs(x(a))) should be able to be positive or negative.
Daniel H.
Daniel H. le 2 Juin 2022
I tired this now sign(xa) * xa^2
but the results are exactly the same
Matt J
Matt J le 2 Juin 2022
Modifié(e) : Matt J le 2 Juin 2022
Yes they are all real numbers, and there is no difference between sign(x4) * x4^2 and x4*abs(x4), is it? :)
There is no difference under the assumption that x4 is real, but had x4 been complex then sign(x4) would be undefined.
Daniel H.
Daniel H. le 2 Juin 2022
Good to know, but they are real.
Actually, sign(x4) wouldn't be undefined, but they don't give the same results:
x4=complex(rand,rand);
sign(x4) * x4^2
ans = -0.3368 - 0.5786i
x4*abs(x4)
ans = 0.1170 + 0.6592i
Daniel H.
Daniel H. le 2 Juin 2022
Thanks for the update. But the problem is still unsolved :)

Connectez-vous pour commenter.

Daniel H.
Daniel H. le 3 Juin 2022

0 votes

Thanks again, yes the problem is solved. But I would like to dig a bit deeper.
Why the order of the coefficients are important here? Why again in the first place TolX and TolFun of 1e-30 could not help?

1 commentaire

Tolerances are only meaningful if the values of the expression can be distinguished within the given tolerance. That requires that eps() of the value of the expression is less than the tolerance. In order for eps() of a value to be less than 1e-30, the value must have absolute magnitude less than 1e-15 or so. But instead your values are in the range of 1e9 which can only be distinguished down to roughly 1e-5

Connectez-vous pour commenter.

Daniel H.
Daniel H. le 3 Juin 2022

0 votes

@Walter Roberson Thanks, but I need more explanation, maybe also a reference to read from in detail
  • What do you mean by "In order for eps() of a value to be less than 1e-30, the value must have absolute magnitude less than 1e-15 "?
  • And how we can say when the order is 1e9 the tolerance would be around 1e-5? "But instead your values are in the range of 1e9 which can only be distinguished down to roughly 1e-5"

3 commentaires

Walter Roberson
Walter Roberson le 3 Juin 2022
Modifié(e) : Walter Roberson le 3 Juin 2022
MATLAB stores (most) numbers as IEEE 754 Double Precision, which is industry standard and which is what is built in to the hardware of your CPU (GPU might not follow some of the obscure behaviors.)
IEEE 754 uses 1 sign bit, 11 exponent bits, and 52 bits of precision, but the choice of exponent effectively gives you one more bit of precision. The representation is sign*(2^53 + 52 bit unsigned integer)/2^53 * 2^(exponent - 1024). Two values that differ by less than 2^-53 times the effect of the exponent cannot be distinguished with this format. That works out to approximately 1.6*10^-16 * 2^floor(log2(abs(number)). Each doubling of the input keeps the same relative precision but loses a bit of absolute precision.
You have values in the range of 5e9. In order to be able to distinguish 10^-30 over that range, I calculate that you would need about 130 bits of precision. Even if you were using 128 bit extended precision numbers, that would not be enough.
Walter Roberson
Walter Roberson le 3 Juin 2022
Modifié(e) : Walter Roberson le 7 Juin 2022
MATLAB does not store numbers in decimal, with the exception of the symbolic toolbox (and even that is a bit questionable, with some hints that it chains together groups of 2^30)
Daniel H.
Daniel H. le 7 Juin 2022
It is more complicated that i thought, I expected it to be more mathematical rather computer science :)
but anyway, thank you very much

Connectez-vous pour commenter.

Produits

Version

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by