简体   繁体   中英

solving multiple non linear equation (with power function)

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM