加快 Sympy 对大量变量的求解集计算
Speeding up Sympy's solveset calculation for a large array of variables
我正在尝试根据特定的不等式从特定点创建 space 中点的参数化。
我正在使用 Sympy.solevset
方法进行计算,而计算将 return 参数区间 t
代表我的数据框中那些点之间的所有点。
遗憾的是,执行 Sympy.solveset
超过 13 组值(即 13 次迭代)会导致总执行时间超过 20 秒,每组计算时间超过 1 秒。
代码:
from sympy import *
from sympy import S
from sympy.solvers.solveset import solveset, solveset_real
import pandas as pd
import time
t=symbols('t',positive=True)
p1x,p1y,p2x,p2y=symbols('p1x p1y p2x p2y')
centerp=[10,10]
radius=5
data={'P1X':[0,1,2,3,1,2,3,1,2,3,1,2,3],'P1Y':[3,2,1,0,1,2,3,1,2,3,1,2,3],'P2X':[3,8,2,4,1,2,3,1,2,3,1,2,3],'P2Y':[3,9,10,7,1,2,3,1,2,3,1,2,3],'result':[0,0,0,0,0,0,0,0,0,0,0,0,0]}
df=pd.DataFrame(data)
parameterized_x=p1x+t*(p2x-p1x)
parameterized_y=p1y+t*(p2y-p1y)
start_whole_process=time.time()
overall_time=0
for index,row in df.iterrows():
parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((parameterized_x-centerp[0])**2+(parameterized_y-centerp[1])**2)-radius
start=time.time()
df.at[index,'result']=solveset(expr>=0,t,domain=S.Reals)
end=time.time()
overall_time=overall_time+end-start
end_whole_process=time.time()
我需要知道是否有一种方法可以缩短计算时间,或者是否有另一个包可以对大量数据执行特定的不等式,而无需等待几分钟。
您当前的方法存在一个大错误,需要先修正。在你的 for 循环中你做了:
parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((parameterized_x-centerp[0])**2+(parameterized_y-centerp[1])**2)-radius
这是错误的:SymPy 表达式不能就地修改。这导致您的 expr
每行完全相同,即:
# sqrt((p1x + t*(-p1x + p2x) - 10)**2 + (p1y + t*(-p1y + p2y) - 10)**2) - 5
然后,solveset
尝试在每一行上求解相同的表达式。因为此表达式包含 3 个符号,solveset
需要很长时间来尝试计算解决方案,最终为每一行生成相同的答案:
# ConditionSet(t, sqrt((p1x + t*(-p1x + p2x) - 10)**2 + (p1y + t*(-p1y + p2y) - 10)**2) - 5 >= 0, Complexes)
记住:您应用于 SymPy 表达式的每个操作都会创建一个新的 SymPy 表达式。所以,上面的代码要修改为:
px_expr = parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
py_expr = parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((px_expr-centerp[0])**2+(py_expr-centerp[1])**2)-radius
在这样做的过程中,expr
对于每一行都是不同的,正如预期的那样。然后,solveset
计算不同的解决方案,而且速度要快得多。
这是您的完整示例:
from sympy import *
from sympy.solvers.solveset import solveset, solveset_real
import pandas as pd
import time
t=symbols('t',positive=True)
p1x,p1y,p2x,p2y=symbols('p1x p1y p2x p2y')
centerp=[10,10]
radius=5
data={'P1X':[0,1,2,3,1,2,3,1,2,3,1,2,3],'P1Y':[3,2,1,0,1,2,3,1,2,3,1,2,3],'P2X':[3,8,2,4,1,2,3,1,2,3,1,2,3],'P2Y':[3,9,10,7,1,2,3,1,2,3,1,2,3],'result':[0,0,0,0,0,0,0,0,0,0,0,0,0]}
df=pd.DataFrame(data)
parameterized_x=p1x+t*(p2x-p1x)
parameterized_y=p1y+t*(p2y-p1y)
start_whole_process=time.time()
overall_time=0
for index,row in df.iterrows():
px_expr = parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
py_expr = parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((px_expr-centerp[0])**2+(py_expr-centerp[1])**2)-radius
df.at[index,'result']=solveset(expr>=0,t,domain=S.Reals)
end_whole_process=time.time()
print("end_whole_process - start_whole_process", end_whole_process - start_whole_process)
我正在尝试根据特定的不等式从特定点创建 space 中点的参数化。
我正在使用 Sympy.solevset
方法进行计算,而计算将 return 参数区间 t
代表我的数据框中那些点之间的所有点。
遗憾的是,执行 Sympy.solveset
超过 13 组值(即 13 次迭代)会导致总执行时间超过 20 秒,每组计算时间超过 1 秒。
代码:
from sympy import *
from sympy import S
from sympy.solvers.solveset import solveset, solveset_real
import pandas as pd
import time
t=symbols('t',positive=True)
p1x,p1y,p2x,p2y=symbols('p1x p1y p2x p2y')
centerp=[10,10]
radius=5
data={'P1X':[0,1,2,3,1,2,3,1,2,3,1,2,3],'P1Y':[3,2,1,0,1,2,3,1,2,3,1,2,3],'P2X':[3,8,2,4,1,2,3,1,2,3,1,2,3],'P2Y':[3,9,10,7,1,2,3,1,2,3,1,2,3],'result':[0,0,0,0,0,0,0,0,0,0,0,0,0]}
df=pd.DataFrame(data)
parameterized_x=p1x+t*(p2x-p1x)
parameterized_y=p1y+t*(p2y-p1y)
start_whole_process=time.time()
overall_time=0
for index,row in df.iterrows():
parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((parameterized_x-centerp[0])**2+(parameterized_y-centerp[1])**2)-radius
start=time.time()
df.at[index,'result']=solveset(expr>=0,t,domain=S.Reals)
end=time.time()
overall_time=overall_time+end-start
end_whole_process=time.time()
我需要知道是否有一种方法可以缩短计算时间,或者是否有另一个包可以对大量数据执行特定的不等式,而无需等待几分钟。
您当前的方法存在一个大错误,需要先修正。在你的 for 循环中你做了:
parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((parameterized_x-centerp[0])**2+(parameterized_y-centerp[1])**2)-radius
这是错误的:SymPy 表达式不能就地修改。这导致您的 expr
每行完全相同,即:
# sqrt((p1x + t*(-p1x + p2x) - 10)**2 + (p1y + t*(-p1y + p2y) - 10)**2) - 5
然后,solveset
尝试在每一行上求解相同的表达式。因为此表达式包含 3 个符号,solveset
需要很长时间来尝试计算解决方案,最终为每一行生成相同的答案:
# ConditionSet(t, sqrt((p1x + t*(-p1x + p2x) - 10)**2 + (p1y + t*(-p1y + p2y) - 10)**2) - 5 >= 0, Complexes)
记住:您应用于 SymPy 表达式的每个操作都会创建一个新的 SymPy 表达式。所以,上面的代码要修改为:
px_expr = parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
py_expr = parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((px_expr-centerp[0])**2+(py_expr-centerp[1])**2)-radius
在这样做的过程中,expr
对于每一行都是不同的,正如预期的那样。然后,solveset
计算不同的解决方案,而且速度要快得多。
这是您的完整示例:
from sympy import *
from sympy.solvers.solveset import solveset, solveset_real
import pandas as pd
import time
t=symbols('t',positive=True)
p1x,p1y,p2x,p2y=symbols('p1x p1y p2x p2y')
centerp=[10,10]
radius=5
data={'P1X':[0,1,2,3,1,2,3,1,2,3,1,2,3],'P1Y':[3,2,1,0,1,2,3,1,2,3,1,2,3],'P2X':[3,8,2,4,1,2,3,1,2,3,1,2,3],'P2Y':[3,9,10,7,1,2,3,1,2,3,1,2,3],'result':[0,0,0,0,0,0,0,0,0,0,0,0,0]}
df=pd.DataFrame(data)
parameterized_x=p1x+t*(p2x-p1x)
parameterized_y=p1y+t*(p2y-p1y)
start_whole_process=time.time()
overall_time=0
for index,row in df.iterrows():
px_expr = parameterized_x.subs([[p1x,row['P1X']],[p2x,row['P2X']]])
py_expr = parameterized_y.subs([[p1y,row['P1Y']],[p2y,row['P2Y']]])
expr=sqrt((px_expr-centerp[0])**2+(py_expr-centerp[1])**2)-radius
df.at[index,'result']=solveset(expr>=0,t,domain=S.Reals)
end_whole_process=time.time()
print("end_whole_process - start_whole_process", end_whole_process - start_whole_process)