# NSolve hangs on what should be a simple problem

This hangs:

EQ1 = Q1 == ((250 - HJ)/1502.56)^(1/1.85);
EQ2 = Q2 == ((150 - HJ)/277.62)^(1/1.85);
EQ3 = Q3 == ((150 - HJ)/156.08)^(1/1.85);
EQ4 = Q1 + Q2 + Q3 == 1;
NSolve[{EQ1, EQ2, EQ3, EQ4, 100 < HJ < 130}, {Q1, Q2, Q3,
HJ}, PositiveReals]


This is a(n) hydraulics problem that is quite easy. Note the Q's as a function of HJ are monotonic. I've run into other NSolve hangs, I wonder if there is something I'm missing when formulating problems for NSolve.

What makes that formulation hang? I've tried experimenting and changing the formulation, but I'm not sure what guidelines to follow to avoid this problem. This change works, it solves immediately:

Clear[hj];
q1 = ((250 - hj)/1502.56)^(1/1.85);
q2 = ((150 - hj)/277.62)^(1/1.85);
q3 = ((150 - hj)/156.08)^(1/1.85);
NSolve[q1 + q2 + q3 == 1, hj, PositiveReals]

{{hj -> 118.311}}


But it is not always so easy to combine equations like that.

What also is interesting, is if I change some of the exponents 1.85 to 2, then NSolve will find an answer, and if I change all three exponents, it finds an answer immediately:

EQ1 = Q1 == ((250 - HJ)/1502.56)^(1/2);
EQ2 = Q2 == ((150 - HJ)/277.62)^(1/2);
EQ3 = Q3 == ((150 - HJ)/156.08)^(1/2);
EQ4 = Q1 + Q2 + Q3 == 1;
NSolve[{EQ1, EQ2, EQ3, EQ4, 100 < HJ < 130}, {Q1, Q2, Q3,
HJ}, PositiveReals]

{{Q1 -> 0.289291, Q2 -> 0.304544, Q3 -> 0.406165, HJ -> 124.252}}


Just changing the exponent seems to play a role. I've also tried putting bounds on the Q's to help NSolve know where to look, but without success.

Here are the solutions to the original problem from python scipy fsolve:

def equations(vars):
q1, q2, q3, hj = vars
eq1 = q1 - ((250-hj)/1502.56)**(1/1.85)
eq2 = q2 - ((150-hj)/277.62)**(1/1.85)
eq3 = q3 - ((150-hj)/156.08)**(1/1.85)
eq4 = q1 + q2 + q3 - 1
return [eq1, eq2, eq3, eq4]

%time
q1, q2, q3, hj = fsolve(equations,(0, 0, 0, 50))
print(q1, q2, q3, hj)

Wall time: 0 ns
0.26822249102421847 0.3093956402654036 0.422381868710378 118.31147673547605

• FindRoot[{EQ1,EQ2,EQ3,EQ4},{{Q1,1},{Q2,1},{Q3,1},{HJ,110}}] quickly returns your answer.
– Bill
Commented Mar 11, 2021 at 6:28
• Thanks!, I have a couple alternatives now. Commented Mar 11, 2021 at 21:54

Without knowledge of starting values, NMinimize solves your problem:
NMinimize[{1, EQ1, EQ2, EQ3, EQ4}, {Q1, Q2, Q3, HJ}]