无法让 SymPy 对求解方程组的结果进行数值评估
Can't get SymPy to numerically evaluate results of solving a system of equations
***** 编辑 *****
添加一个简化的例子来更清楚地说明问题。原文post以下编辑
我正在尝试获取原始 post 中大量丑陋的代码以生成简单的数值结果。在这个简化示例中,我有三个方程式,EqA、EqB 和 EqC。 EqA 和 EqB 都采用数字输入。 EqC 然后从 EqA 获取输出并将其添加到 EqB 的输出。在执行了 solve() 和 evalf() 之后,我希望得到的结果是 11,但它只是给了我一个表达式。我将如何正确评估这样的方程组?
from sympy import *
from sympy.printing.mathml import print_mathml
init_printing()
Fa,Fb,a,b,c,d,T = symbols('F_a F_b a b c d T')
EqA = Eq(a+b,Fa)
print(EqA)
EqB = Eq(c+d,Fb)
print(EqB)
EqC = Eq(Fa + Fb,T)
print(EqC)
results = (solve([EqA,EqB,EqC],T))
print(results)
print('printing results')
print(results[T].evalf(subs={a:1,b:3,c:3,d:4}))
这会产生以下输出:
-F_a + a + b
-F_b + c + d
F_a + F_b - T
{T: F_a + F_b}
printing results
F_a + F_b
evalf() 语句的预期输出是 11。
***** /编辑 *****
似乎无法让此代码生成任何数字输出。我试图通过将其分解成更小的部分来构建更复杂的方程式,以便更容易地进行故障排除。所需的输出是求解 T。但是,当我 运行 求解器然后尝试对输出进行 evalf() 时,它只是将相同的表达式返回给我。该行为与我未能定义所有必要的数字输入时的行为相同,但我认为我在 evalf() 调用中定义了所有相关的输入。关于我做错了什么有什么想法吗?
from sympy import *
init_printing()
periodOfInterest = symbols('P') #constant
modDensity = symbols('D_m') # result of calculation
floorDensity = symbols('D_f') # result of calculation
distanceTraveledPerPickMod = symbols('x_m') # result of calculation
distanceTraveledPerPickFloor = symbols('x_f') # result of calculation
travelTimePerPickMod = symbols('t_modTravel') # result of calculation
travelTimePerPickFloor = symbols('t_floorTravel') # result of calculation
timePerPickMod = symbols('t_totalMod') # result of calculation
timePerPickFloor = symbols('t_totalFloor') # result of calculation
T = symbols('Total_picks') # result of calculation
unitsMod = symbols('U_m') #constant
zonesMod = symbols('Z_m') #constant
pathLengthMod = symbols('L_m') #constant
travelRate = symbols('R_p') #constant
pickTime = symbols('k_p') #constant
unitsFloor = symbols('U_f') #constant
zonesFloor = symbols('Z_f') #constant
pathLengthFloor = symbols('L_f') #constant
floorPickers = symbols('N_floor') #constant
modPickers = symbols('N_mod') #constant
modDensityEq = Eq(unitsMod/zonesMod , modDensity)
floorDensityEq = Eq(unitsFloor/zonesFloor , floorDensity)
distanceTraveledPerPickModEq = Eq(pathLengthMod/modDensity , distanceTraveledPerPickMod)
distanceTraveledPerPickFloorEq = Eq(pathLengthFloor/floorDensity , distanceTraveledPerPickFloor)
travelTimePerPickModEq = Eq(distanceTraveledPerPickMod/travelRate , travelTimePerPickMod)
travelTimePerPickFloorEq = Eq(distanceTraveledPerPickFloor/travelRate , travelTimePerPickFloor)
timePerPickModEq = Eq(travelTimePerPickMod+pickTime , timePerPickMod)
timePerPickFloorEq = Eq(travelTimePerPickFloor + pickTime , timePerPickFloor)
totalPicksEq = Eq(floorPickers*periodOfInterest/timePerPickFloor + modPickers*periodOfInterest/timePerPickMod, T)
results = (solve([totalPicksEq,timePerPickFloorEq,timePerPickModEq,travelTimePerPickFloorEq,
travelTimePerPickModEq,distanceTraveledPerPickModEq,distanceTraveledPerPickFloorEq,
floorDensityEq,modDensityEq],T))
(results)
results[T]
(results[T]).evalf(subs={
periodOfInterest:60*60,
unitsMod:5000*2/3,
zonesMod:4,
pathLengthMod:3000,
travelRate:1.34,
pickTime:10,
unitsFloor:5000/3,
zonesFloor:2,
pathLengthFloor:3000,
floorPickers:15,
modPickers:35
})
这会产生以下输出:
N_floor*P/t_totalFloor + N_mod*P/t_totalMod
怎么样:
results[T].subs({floorPickers: 15, modPickers: 35, periodOfInterest: 60*60, timePerPickMod: 1.0, timePerPickFloor: 1.0})
你想要的是让 SymPy 更新所有相关变量并给你结果:你想要你定义的方程 和 a - d 的值是 同时 正确。这样做的方法是将值作为必须为真的附加联立方程给出:
>>> solve((EqA,EqB,EqC,Eq(a,1),Eq(b,3),Eq(c,3),Eq(d,4)))
{c: 3, F_a: 4, a: 1, d: 4, F_b: 7, b: 3, T: 11}
这显示了您正在寻找的 T=11 值。
***** 编辑 *****
添加一个简化的例子来更清楚地说明问题。原文post以下编辑
我正在尝试获取原始 post 中大量丑陋的代码以生成简单的数值结果。在这个简化示例中,我有三个方程式,EqA、EqB 和 EqC。 EqA 和 EqB 都采用数字输入。 EqC 然后从 EqA 获取输出并将其添加到 EqB 的输出。在执行了 solve() 和 evalf() 之后,我希望得到的结果是 11,但它只是给了我一个表达式。我将如何正确评估这样的方程组?
from sympy import *
from sympy.printing.mathml import print_mathml
init_printing()
Fa,Fb,a,b,c,d,T = symbols('F_a F_b a b c d T')
EqA = Eq(a+b,Fa)
print(EqA)
EqB = Eq(c+d,Fb)
print(EqB)
EqC = Eq(Fa + Fb,T)
print(EqC)
results = (solve([EqA,EqB,EqC],T))
print(results)
print('printing results')
print(results[T].evalf(subs={a:1,b:3,c:3,d:4}))
这会产生以下输出:
-F_a + a + b
-F_b + c + d
F_a + F_b - T
{T: F_a + F_b}
printing results
F_a + F_b
evalf() 语句的预期输出是 11。
***** /编辑 *****
似乎无法让此代码生成任何数字输出。我试图通过将其分解成更小的部分来构建更复杂的方程式,以便更容易地进行故障排除。所需的输出是求解 T。但是,当我 运行 求解器然后尝试对输出进行 evalf() 时,它只是将相同的表达式返回给我。该行为与我未能定义所有必要的数字输入时的行为相同,但我认为我在 evalf() 调用中定义了所有相关的输入。关于我做错了什么有什么想法吗?
from sympy import *
init_printing()
periodOfInterest = symbols('P') #constant
modDensity = symbols('D_m') # result of calculation
floorDensity = symbols('D_f') # result of calculation
distanceTraveledPerPickMod = symbols('x_m') # result of calculation
distanceTraveledPerPickFloor = symbols('x_f') # result of calculation
travelTimePerPickMod = symbols('t_modTravel') # result of calculation
travelTimePerPickFloor = symbols('t_floorTravel') # result of calculation
timePerPickMod = symbols('t_totalMod') # result of calculation
timePerPickFloor = symbols('t_totalFloor') # result of calculation
T = symbols('Total_picks') # result of calculation
unitsMod = symbols('U_m') #constant
zonesMod = symbols('Z_m') #constant
pathLengthMod = symbols('L_m') #constant
travelRate = symbols('R_p') #constant
pickTime = symbols('k_p') #constant
unitsFloor = symbols('U_f') #constant
zonesFloor = symbols('Z_f') #constant
pathLengthFloor = symbols('L_f') #constant
floorPickers = symbols('N_floor') #constant
modPickers = symbols('N_mod') #constant
modDensityEq = Eq(unitsMod/zonesMod , modDensity)
floorDensityEq = Eq(unitsFloor/zonesFloor , floorDensity)
distanceTraveledPerPickModEq = Eq(pathLengthMod/modDensity , distanceTraveledPerPickMod)
distanceTraveledPerPickFloorEq = Eq(pathLengthFloor/floorDensity , distanceTraveledPerPickFloor)
travelTimePerPickModEq = Eq(distanceTraveledPerPickMod/travelRate , travelTimePerPickMod)
travelTimePerPickFloorEq = Eq(distanceTraveledPerPickFloor/travelRate , travelTimePerPickFloor)
timePerPickModEq = Eq(travelTimePerPickMod+pickTime , timePerPickMod)
timePerPickFloorEq = Eq(travelTimePerPickFloor + pickTime , timePerPickFloor)
totalPicksEq = Eq(floorPickers*periodOfInterest/timePerPickFloor + modPickers*periodOfInterest/timePerPickMod, T)
results = (solve([totalPicksEq,timePerPickFloorEq,timePerPickModEq,travelTimePerPickFloorEq,
travelTimePerPickModEq,distanceTraveledPerPickModEq,distanceTraveledPerPickFloorEq,
floorDensityEq,modDensityEq],T))
(results)
results[T]
(results[T]).evalf(subs={
periodOfInterest:60*60,
unitsMod:5000*2/3,
zonesMod:4,
pathLengthMod:3000,
travelRate:1.34,
pickTime:10,
unitsFloor:5000/3,
zonesFloor:2,
pathLengthFloor:3000,
floorPickers:15,
modPickers:35
})
这会产生以下输出:
N_floor*P/t_totalFloor + N_mod*P/t_totalMod
怎么样:
results[T].subs({floorPickers: 15, modPickers: 35, periodOfInterest: 60*60, timePerPickMod: 1.0, timePerPickFloor: 1.0})
你想要的是让 SymPy 更新所有相关变量并给你结果:你想要你定义的方程 和 a - d 的值是 同时 正确。这样做的方法是将值作为必须为真的附加联立方程给出:
>>> solve((EqA,EqB,EqC,Eq(a,1),Eq(b,3),Eq(c,3),Eq(d,4)))
{c: 3, F_a: 4, a: 1, d: 4, F_b: 7, b: 3, T: 11}
这显示了您正在寻找的 T=11 值。