1
$\begingroup$

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
$\endgroup$
2
  • 2
    $\begingroup$ FindRoot[{EQ1,EQ2,EQ3,EQ4},{{Q1,1},{Q2,1},{Q3,1},{HJ,110}}] quickly returns your answer. $\endgroup$
    – Bill
    Commented Mar 11, 2021 at 6:28
  • $\begingroup$ Thanks!, I have a couple alternatives now. $\endgroup$
    – Rich L
    Commented Mar 11, 2021 at 21:54

1 Answer 1

1
$\begingroup$

Without knowledge of starting values, NMinimize solves your problem:

NMinimize[{1, EQ1, EQ2, EQ3, EQ4}, {Q1, Q2, Q3, HJ}]
(*{1., {Q1 -> 0.268222, Q2 -> 0.309396, Q3 -> 0.422382, HJ -> 118.311}}*) 
$\endgroup$
1
  • $\begingroup$ Thanks! I will try this with other NSolve hangs. $\endgroup$
    – Rich L
    Commented Mar 11, 2021 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.