基于SymPy(或其他工具)的通用表达式优化:自定义域与操作实现
自定义SymPy域以支持GLM风格的向量操作与表达式优化
实现步骤
1. 定义自定义向量类
继承SymPy的Basic类(核心表达式基类),创建Vec3类封装三维向量,重写加法、点乘等操作,确保运算后保留向量整体结构,不自动拆分为分量:
from sympy import Basic, symbols class Vec3(Basic): def __init__(self, x, y, z): super().__init__(x, y, z) self.x = x self.y = y self.z = z def __add__(self, other): if isinstance(other, Vec3): return Vec3(self.x + other.x, self.y + other.y, self.z + other.z) return NotImplemented def __mul__(self, scalar): # 实现标量乘法 return Vec3(self.x * scalar, self.y * scalar, self.z * scalar) def dot(self, other): if isinstance(other, Vec3): return self.x*other.x + self.y*other.y + self.z*other.z return NotImplemented
2. 自定义化简逻辑
实现专属化简函数,让SymPy按照自定义规则优化表达式,比如保留Vec3实例,不展开分量:
def simplify_vec3(expr): if isinstance(expr, Vec3): return Vec3(expr.x.simplify(), expr.y.simplify(), expr.z.simplify()) # 处理点乘操作的化简 if hasattr(expr, 'func') and expr.func == Vec3.dot: return expr.args[0].dot(expr.args[1]).simplify() return expr.simplify() # 使用示例 a, b, c = symbols('a b c') v1 = Vec3(a, b, c) v2 = Vec3(c, b, a) simplified = simplify_vec3(v1 + v2) # 输出保留Vec3结构:Vec3(a + c, 2*b, a + c)
3. 注册自定义操作到SymPy系统
通过SymPy的Function类注册dot这类操作,让SymPy的表达式引擎能识别并处理:
from sympy import Function class Dot(Function): @classmethod def eval(cls, vec_a, vec_b): if isinstance(vec_a, Vec3) and isinstance(vec_b, Vec3): return vec_a.dot(vec_b) # 使用示例 dot_product = Dot(v1, v2) # 化简后得到:a*c + b**2 + a*c
相关SymPy官方文档
Basic类文档:讲解自定义表达式的核心基类,包含继承、属性重写的规则- 化简系统文档:介绍
_simplify、rewrite等机制的使用,自定义表达式化简逻辑的方法 - 自定义函数文档:说明如何注册自定义操作符与函数,让SymPy识别并处理
替代工具推荐
- SymPy Physics Module:内置矢量、张量的整体操作支持,可扩展适配GLM风格的运算规则,无需从零构建
- PyDy:基于SymPy的动力学库,提供自定义坐标系与矢量运算的扩展接口,适合3D向量操作场景
- SageMath:集成SymPy作为核心组件,拥有更灵活的代数结构扩展能力,可快速自定义域与运算规则
内容的提问来源于stack exchange,提问作者QT-1
相关产品推荐
相关产品推荐

