solving multiple non linear equation (with power function)

Viewed 34

I would like to solve this kind of equations:

a*85**b+c=100
a*90**b+c=66
a*92**b+c=33

I tried this

import scipy.optimize

def fun(variables) :
    (a,b,c)= variables
    eq0=a*85**b+c-100
    eq1=a*90**b+c-66
    eq2=a*92**b+c-33
    return [eq0,eq1,eq2]
result = scipy.optimize.fsolve(fun, (1, -1, 0)) 
print(result)

But I get ValueError: Integers to negative integer powers are not allowed.

Then I tried the equivalent

    def fun(variables) :
    (a,b,c)= variables
    eq0=log(a)+b*log(85)-log(100-c)
    eq1=log(a)+b*log(90)-log(66-c)
    eq2=log(a)+b*log(92)-log(33-c)
    return [eq0,eq1,eq2]
result = scipy.optimize.fsolve(fun, (1, -1, 0)) 
print(result)

I get a solution but that is equal to the initial values (1, -1, 0) Thus when I test fun(result), I get values different from zero.

I have noticed that for this example the same problem is observed

import scipy.optimize
def fun(variables) :
    (x,y)= variables
    eqn_1 = x**2+y-4
    eqn_2 = x+y**2+3
    return [eqn_1,eqn_2]
result = scipy.optimize.fsolve(fun, (0.1, 1)) 
print(result)

fun(result)

Does anyone would know how I could do ? Thank you

PS I have posted here about sympy last week Resolution of multiple equations (with exponential)

1 Answers

When the initial condition is not well known, sometimes its best to try other methods first . For small problems, simplex minimization is useful:

import numpy as np
def func(x):
    a,b,c= x
    eq0=np.log(a)+b*np.log(85)-np.log(100-c)
    eq1=np.log(a)+b*np.log(90)-np.log(66-c)
    eq2=np.log(a)+b*np.log(92)-np.log(33-c)
    return eq0**2+ eq1**2 + eq2**2

def func_vec(x):
    a,b,c= x
    eq0=np.log(a)+b*np.log(85)-np.log(100-c)
    eq1=np.log(a)+b*np.log(90)-np.log(66-c)
    eq2=np.log(a)+b*np.log(92)-np.log(33-c)
    return eq0, eq1, eq2

from scipy.optimize import fsolve, minimize
out = minimize(func, [1,1,0], method="Nelder-Mead", options={"maxfev":100000})
print("roots:", out.x)
print("value at roots:", func_vec(out.x))

# roots: [ 7.87002460e+11 -1.07401055e-09 -7.87002456e+11]
# value at roots: (6.0964566728216596e-12, -1.2086331935279304e-11, 6.235012506294879e-12)

Note, I also tried [1,1,1] as an initial condition and found it converged to the wrong solution. Further increasing maxfev from 1e5 to 1e7 allowed [1,1,1] to converged to the proper solution, but then perhaps there are better methods to solve this.

Related