假设我在sympy
中有一个符号计算,该计算通过向数字添加错误来修改数字的基本算术运算:
from sympy import *
p0,p1,p2 = symbols("p0:3")
ep0,ep1,ep2 = symbols("ep0:3")
x0,x1,x2 = symbols("x0:3")
ex0,ex1,ex2 = symbols("ex0:3")
q0,q1,q2 = symbols("q0:3")
eq0,eq1,eq2 = symbols("eq0:3")
r0,r1,r2 = symbols("r0:3")
er0,er1,er2 = symbols("er0:3")
n0,n1,n2 = symbols("n0:3")
en0,en1,en2 = symbols("en0:3")
p = Matrix([p0,p1,p2])
x = Matrix([x0,x1,x2])
q = Matrix([q0,q1,q2])
r = Matrix([r0,r1,r2])
n = Matrix([n0,n1,n2])
errors = []
def fl_op(a,b,op,e):
return op(a,b)*(1 + e)
def fl_add(a,b):
# Append an addition error to the global list of errors
errors.append(symbols("err_add" + str(len(errors)+1)))
return fl_op(a,b, lambda x,y : x + y, errors[-1])
def fl_sub(a,b):
# Append an addition error to the global list of errors
errors.append(symbols("err_sub" + str(len(errors)+1)))
return fl_op(a,b, lambda x,y : x - y, errors[-1])
def fl_mul(a,b):
# Append an addition error to the global list of errors
errors.append(symbols("err_mul" + str(len(errors)+1)))
return fl_op(a,b, lambda x,y : x * y, errors[-1])
def fl_div(a,b):
# Append an addition error to the global list of errors
errors.append(symbols("err_div" + str(len(errors)+1)))
return fl_op(a,b, lambda x,y : x / y, errors[-1])
def fl_vsub(va,vb):
assert (len(va) == len(vb))
return [fl_sub(va[i],vb[i]) for i in range(len(va))]
def fl_vadd(va,vb):
assert (len(va) == len(vb))
return [fl_add(va[i],vb[i]) for i in range(len(va))]
def fl_vsum(va):
return fl_add(fl_add(va[0],va[1]),va[2])
def fl_dot(va,vb):
assert (len(va) == len(vb))
return fl_vsum([fl_mul(va[i],vb[i]) for i in range(len(va))])
dotSub = fl_sub(fl_dot(r,n), fl_dot(p,n))
dotSub = simplify(dotSub)
vSubDot = fl_dot(fl_vsub(r,p),n)
vSubDot = simplify(vSubDot)
print(expand(dotSub))
打印语句的结果是:
-err_add10 * err_add9 * err_mul6 * err_sub11 * n0 * p0-err_add10 * err_add9 * err_mul6 * n0 * p0- err_add10 * err_add9 * err_mul7 * err_sub11 * n1 * p1- err_add10 * err_add9 * err_mul7 * n1 * p1-err_add10 * err_add9 * err_sub11 * n0 * p0 -err_add10 * err_add9 * err_sub11 * n1 * p1-err_add10 * err_add9 * n0 * p0-err_add10 * err_add9 * n1 * p1-err_add10 * err_mul6 * err_sub11 * n0 * p0- err_add10 * err_mul6 * n0 * p0-err_add10 * err_mul7 * err_sub11 * n1 * p1- err_add10 * err_mul7 * n1 * p1-err_add10 * err_mul8 * err_sub11 * n2 * p2- err_add10 * err_mul8 * n2 * p2-err_add10 * err_sub11 * n0 * p0- err_add10 * err_sub11 * n1 * p1-err_add10 * err_sub11 * n2 * p2- err_add10 * n0 * p0-err_add10 * n1 * p1-err_add10 * n2 * p2 + err_add4 * err_add5 * err_mul1 * err_sub11 * n0 * r0 + err_add4 * err_add5 * err_mul1 * n0 * r0 + err_add4 * err_add5 * err_mul2 * err_sub11 * n1 * r1 + err_add4 * err_add5 * err_mul2 * n1 * r1 + err_add4 * err_add5 * err_sub11 * n0 * r0 + err_add4 * err_add5 * err_sub11 * n1 * r1 + err_add4 * err_add5 * n0 * r0 + err_add4 * err_add5 * n1 * r1 + err_add4 * err_mul1 * err_sub11 * n0 * r0 + err_add4 * err_mul1 * n0 * r0 + err_add4 * err_mul2 * err_sub11 * n1 * r1 + err_add4 * err_mul2 * n1 * r1 + err_add4 * err_sub11 * n0 * r0 + err_add4 * err_sub11 * n1 * r1 + err_add4 * n0 * r0 + err_add4 * n1 * r1 + err_add5 * err_mul1 * err_sub11 * n0 * r0 + err_add5 * err_mul1 * n0 * r0 + err_add5 * err_mul2 * err_sub11 * n1 * r1 + err_add5 * err_mul2 * n1 * r1 + err_add5 * err_mul3 * err_sub11 * n2 * r2 + err_add5 * err_mul3 * n2 * r2 + err_add5 * err_sub11 * n0 * r0 + err_add5 * err_sub11 * n1 * r1 + err_add5 * err_sub11 * n2 * r2 + err_add5 * n0 * r0 + err_add5 * n1 * r1 + err_add5 * n2 * r2-err_add9 * err_mul6 * err_sub11 * n0 * p0- err_add9 * err_mul6 * n0 * p0-err_add9 * err_mul7 * err_sub11 * n1 * p1- err_add9 * err_mul7 * n1 * p1-err_add9 * err_sub11 * n0 * p0- err_add9 * err_sub11 * n1 * p1-err_add9 * n0 * p0-err_add9 * n1 * p1 + err_mul1 * err_sub11 * n0 * r0 + err_mul1 * n0 * r0 + err_mul2 * err_sub11 * n1 * r1 + err_mul2 * n1 * r1 + err_mul3 * err_sub11 * n2 * r2 + err_mul3 * n2 * r2- err_mul6 * err_sub11 * n0 * p0-err_mul6 * n0 * p0-err_mul7 * err_sub11 * n1 * p1- err_mul7 * n1 * p1-err_mul8 * err_sub11 * n2 * p2-err_mul8 * n2 * p2- err_sub11 * n0 * p0 + err_sub11 * n0 * r0-err_sub11 * n1 * p1 + err_sub11 * n1 * r1 -err_sub11 * n2 * p2 + err_sub11 * n2 * r2-n0 * p0 + n0 * r0-n1 * p1 + n1 * r1-n2 * p2 + n2 * r2
所有err_
术语互不相同,但是它们的乘积可以忽略。做这个的最好方式是什么? subs
中的sympy
函数是否可以接受所有err_
项的乘积的规则,使乘积等于0?是否可以重载用于符号符号的算术运算符*
来检查两个乘积运算符的名称是否都以err_
开头并以符号0得出结果?
不可能很快为err_
项的乘积指定所有可能的组合,因为组合的数量增长很快。
如果使用python.regex
解析字符串以排除所有乘积,可能会更容易。怎么办?
我尝试了以下python regex
,但它对字符串没有影响:
import regex
dotSubStr = str(expand(dotSub))
re.sub("[+,-,\s]err_*\*err_*\s",'', dotSubStr)
提取第一个产品适用于
re.sub("err_(add|sub|mul|div)\d+\*err_(add|sub|mul|div)\d+",'', dotSubStr)
'-** n0 * p0-* err_mul6 * n0 * p0-** n1 * p1-* err_mul7 * n1 * p1- * err_sub11 * n0 * p0-* err_sub11 * n1 * p1-* n0 * p0-* n1 * p1-* err_sub11 * n0 * p0-* n0 * p0-* err_sub11 * n1 * p1-* n1 * p1-* err_sub11 * n2 * p2-* n2 * p2-* n0 * p0-* n1 * p1-* n2 * p2-err_add10 * n0 * p0-err_add10 * n1 * p1-err_add10 * n2 * p2 + ** n0 * r0 + * err_mul1 * n0 * r0 + ** n1 * r1 + * err_mul2 * n1 * r1 + * err_sub11 * n0 * r0 + * nr * sub1 * n1 * r1 + * n0 * r0 + * n1 * r1 + * err_sub11 * n0 * r0 + * n0 * r0 + * err_sub11 * n1 * r1 + * n1 * r1 + * n0 * r0 + * n1 * r1 + err_add4 * n0 * r0 + err_add4 * n1 * r1 + * err_sub11 * n0 * r0 + * n0 * r0 + * err_sub11 * n1 * r1 + * n1 * r1 + * err_sub11 * n2 * r2 + * n2 * r2 + * n0 * r0 + * n1 * r1 + * n2 * r2 + err_add5 * n0 * r0 + err_add5 * n1 * r1 + err_add5 * n2 * r2-* err_sub11 * n0 * p0-* n0 * p0-* err_sub11 * n1 * p1-* n1 * p1-* n0 * p0-* n1 * p1-err_add9 * n0 * p0-err_add9 * n1 * p1 + * n0 * r0 + err_mul1 * n0 * r0 + * n1 * r1 + err_mul2 * n1 * r1 + * n2 * r2 + err_mul3 * n2 * r2-* n0 * p0-err_mul6 * n0 * p0-* n1 * p1-err_mul7 * n1 * p1-* n2 * p2-err_mul8 * n2 * p2-err_sub11 * n0 * p0 + err_sub11 * n0 * r0-err_sub11 * n1 * p1 + err_sub11 * n1 * r1-err_sub11 * n2 * p2 + err_sub11 * n2 * r2-n0 * p0 + n0 * r0-n1 * p1 + n1 * r1-n2 * p2 + n2 * r2'
因此,如果表达式最多具有3个乘积操作数,则此操作将删除乘积,但在乘积完好后保留所有内容,因此也应将其删除。
答案 0 :(得分:0)
我弄清楚了如何使用regex
过滤产品,以便在有人需要时回答。
从带有算术表达式的起始字符串开始:
-err_add10 * err_add9 * err_mul6 * err_sub11 * n0 * p0-err_add10 * err_add9 * err_mul6 * n0 * p0- err_add10 * err_add9 * err_mul7 * err_sub11 * n1 * p1- err_add10 * err_add9 * err_mul7 * n1 * p1-err_add10 * err_add9 * err_sub11 * n0 * p0 -err_add10 * err_add9 * err_sub11 * n1 * p1-err_add10 * err_add9 * n0 * p0-err_add10 * err_add9 * n1 * p1-err_add10 * err_mul6 * err_sub11 * n0 * p0- err_add10 * err_mul6 * n0 * p0-err_add10 * err_mul7 * err_sub11 * n1 * p1- err_add10 * err_mul7 * n1 * p1-err_add10 * err_mul8 * err_sub11 * n2 * p2- err_add10 * err_mul8 * n2 * p2-err_add10 * err_sub11 * n0 * p0- err_add10 * err_sub11 * n1 * p1-err_add10 * err_sub11 * n2 * p2- err_add10 * n0 * p0-err_add10 * n1 * p1-err_add10 * n2 * p2 + err_add4 * err_add5 * err_mul1 * err_sub11 * n0 * r0 + err_add4 * err_add5 * err_mul1 * n0 * r0 + err_add4 * err_add5 * err_mul2 * err_sub11 * n1 * r1 + err_add4 * err_add5 * err_mul2 * n1 * r1 + err_add4 * err_add5 * err_sub11 * n0 * r0 + err_add4 * err_add5 * err_sub11 * n1 * r1 + err_add4 * err_add5 * n0 * r0 + err_add4 * err_add5 * n1 * r1 + err_add4 * err_mul1 * err_sub11 * n0 * r0 + err_add4 * err_mul1 * n0 * r0 + err_add4 * err_mul2 * err_sub11 * n1 * r1 + err_add4 * err_mul2 * n1 * r1 + err_add4 * err_sub11 * n0 * r0 + err_add4 * err_sub11 * n1 * r1 + err_add4 * n0 * r0 + err_add4 * n1 * r1 + err_add5 * err_mul1 * err_sub11 * n0 * r0 + err_add5 * err_mul1 * n0 * r0 + err_add5 * err_mul2 * err_sub11 * n1 * r1 + err_add5 * err_mul2 * n1 * r1 + err_add5 * err_mul3 * err_sub11 * n2 * r2 + err_add5 * err_mul3 * n2 * r2 + err_add5 * err_sub11 * n0 * r0 + err_add5 * err_sub11 * n1 * r1 + err_add5 * err_sub11 * n2 * r2 + err_add5 * n0 * r0 + err_add5 * n1 * r1 + err_add5 * n2 * r2-err_add9 * err_mul6 * err_sub11 * n0 * p0- err_add9 * err_mul6 * n0 * p0-err_add9 * err_mul7 * err_sub11 * n1 * p1- err_add9 * err_mul7 * n1 * p1-err_add9 * err_sub11 * n0 * p0- err_add9 * err_sub11 * n1 * p1-err_add9 * n0 * p0-err_add9 * n1 * p1 + err_mul1 * err_sub11 * n0 * r0 + err_mul1 * n0 * r0 + err_mul2 * err_sub11 * n1 * r1 + err_mul2 * n1 * r1 + err_mul3 * err_sub11 * n2 * r2 + err_mul3 * n2 * r2- err_mul6 * err_sub11 * n0 * p0-err_mul6 * n0 * p0-err_mul7 * err_sub11 * n1 * p1- err_mul7 * n1 * p1-err_mul8 * err_sub11 * n2 * p2-err_mul8 * n2 * p2- err_sub11 * n0 * p0 + err_sub11 * n0 * r0-err_sub11 * n1 * p1 + err_sub11 * n1 * r1 -err_sub11 * n2 * p2 + err_sub11 * n2 * r2-n0 * p0 + n0 * r0-n1 * p1 + n1 * r1-n2 * p2 + n2 * r2
regex
可以这样删除所有err_*
项的所有乘积:
import re
dotSubFinal = re.sub("(err_(add|sub|mul|div)\d+\*){2,}",'del', dotSubStr)
dotSubFinal = re.sub("[+-]\s*del[npr]\d\*[npr]\d",'', dotSubFinal)
dotSubFinal = re.sub("\s{2,}",'', dotSubFinal)
导致:
打印(dotSubFinal)
-err_add10 * n0 * p0-err_add10 * n1 * p1-err_add10 * n2 * p2 + err_add4 * n0 * r0 + err_add4 * n1 * r1 + err_add5 * n0 * r0 + err_add5 * n1 * r1 + er2 * n0 * p0- err_add9 * n1 * p1 + err_mul1 * n0 * r0 + err_mul2 * n1 * r1 + err_mul3 * n2 * r2- err_mul6 * n0 * p0- err_mul7 * n1 * p1- err_mul8 * n2 * p2- err_sub11 * n0 * p0 + err_sub11 * n0 * r0-err_sub11 * n1 * p1 + err_sub11 * n1 * r1 -err_sub11 * n2 * p2 + err_sub11 * n2 * r2-n0 * p0 + n0 * r0-n1 * p1 + n1 * r1-n2 * p2 + n2 * r2