简体   繁体   中英

How do you solve a non-linear equation using fsolve on python?

I attempted to use the code below as a guide, in order to solve a non-linear equation, but I continue to get errors such as "object too deep for desired array" and "Result from function call is not a proper array of floats".

from scipy.optimize import fsolve
from math import exp

def equations(vars):
    x, y = vars
    eq1 = x+y**2-4
    eq2 = exp(x) + x*y - 3
    return [eq1, eq2]

x, y =  fsolve(equations, (1, 1))

print(x, y)

My code will be posted below. It points out the error on the line "Q = fsolve(equations, 1)"

%reset -f
from math import *
T = 4 # N·m
ω = 1800*(pi/30) # rad/s
A1 = .00131 # m^2
A2 = .00055 # m^2
P1 = 12000 # Pa
P2 = 200000 # Pa
ρ = 1000 # kg/m^3
μ = .89e-3 # N·s/m^2
η = .57 # % efficiency
g = 9.81 # m/s^2
γ = 9810 # N/m^3
Z2 = .7 # m

P_motor = T*ω
print(P_motor)

P_pump = P_motor*η
print(P_pump)

from scipy.optimize import fsolve

def equations(vars):
   Q = vars 
   eq1 = γ*Q*( ((P2-P1)/γ) + ( ( ( (Q**2) / (A2**2) ) - ( (Q**2) / (A1**2) ) )/2*g) + Z2) - P_pump
   return [eq1]
                    
Q = fsolve(equations, 1)

print(Q)

Since you have only one equation with one unknown variable, you don't need to put the output in a list. You can replace return [eq1] with return eq1 .

The new code would be:

%reset -f
from math import *
T = 4 # N·m
ω = 1800*(pi/30) # rad/s
A1 = .00131 # m^2
A2 = .00055 # m^2
P1 = 12000 # Pa
P2 = 200000 # Pa
ρ = 1000 # kg/m^3
μ = .89e-3 # N·s/m^2
η = .57 # % efficiency
g = 9.81 # m/s^2
γ = 9810 # N/m^3
Z2 = .7 # m

P_motor = T*ω
print(P_motor)

P_pump = P_motor*η
print(P_pump)

from scipy.optimize import fsolve

def equations(vars):
   Q = vars 
   eq1 = γ*Q*( ((P2-P1)/γ) + ( ( ( (Q**2) / (A2**2) ) - ( (Q**2) / (A1**2) ) )/2*g) + Z2) - P_pump
   return eq1

Q = fsolve(equations, 1)

print(Q)

Output:

753.9822368615503
429.7698750110836
[0.0011589]

The documentation states

func : callable f(x, *args)
A function that takes at least one (possibly vector) argument, and returns a value of the same length.

if your input is a list of 2 values, it is expecting the function to return something of the same shape. So in your 1st example, you pass [x,y] and you return [eq1, eq2] , so it works, but in second case, you pass a scalar and return a list

So, you can change your input to Q = fsolve(equations, (1,)) or change your returned value to return eq1 :

def equations(vars):
   Q = vars 
   eq1 = γ*Q*( ((P2-P1)/γ) + ( ( ( (Q**2) / (A2**2) ) - ( (Q**2) / (A1**2) ) )/2*g) + Z2) - P_pump
   return eq1

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