python - 我可以在 sympy 中使用符号叉积运算吗

标签 python sympy polynomials

你好,

我正在尝试编写一个用于计算 3D 多项式的符号库 以分析方式(变量是实值t,多项式的单项式是 3D 向量)。特别是,我想计算两个多项式的叉积(在 that question 的后续过程中)。在 Sympy 中,我发现我可以:

  1. 使用 sympy.physicals.mechanics 包中的显式向量变量(具有实数值),并在本例中定义叉积。
  2. 使用矩阵符号,但未为其定义叉积。

有什么方法可以在 sympy 中象征性地表示叉积吗?

编辑:特别是,我对消除两个相同向量的叉积感兴趣,并在根据向量之一分解多项式时考虑反交换性质。

新编辑: 为了让自己更清楚,我想停留在“象征层面”。那是, 我不想沿着每个变量开发向量的项。

例如,以下是计算贝塞尔曲线的代码:

from sympy import *

init_printing(use_unicode=True)

from scipy.special import binom

#default control points of a Bezier curve
p_is = [symbols('p'+str(i))  for i in range(5)] 


class Bezier:    
    #eq is the equation of the curve, pis are the stored control point
    #for special purpose such as the derivatives
    def __init__(self, deg, eq = None, pis = None):
        assert(deg)
        self.deg = deg;
        n_pts = deg +1 
        if pis == None:
            self.pis = p_is[:n_pts]
        else:
            self.pis = pis[:]; 
        if eq == None:
            #computing the bernstein polynoms for a given degree
            factors = [binom(deg,i) * t**i * (1-t)**(deg-i)*pis[i] for i in range(n_pts)]
            self.eq = sum(factors);
        else:
            self.eq = eq


    def __repr__(self):
        res  = "Degree : "        + str(self.deg) 
        res += "\nEquation : "    + self.eq.__repr__()
        res += "\nwaypoints :\n"  + str(self.pis) 
        return res


    def __str__(self):
        return self.__repr__()


b = Bezier(3)

print b 
# Degree : 3
# Equation : 1.0*p0*(-t + 1)**3 + 3.0*p1*t*(-t + 1)**2 + 3.0*p2*t**2*(-t + 1) + 1.0*p3*t**3
# waypoints :
# [p0, p1, p2, p3]

print b.eq
# 1.0*p0*(-t + 1)**3 + 3.0*p1*t*(-t + 1)**2 + 3.0*p2*t**2*(-t + 1) + 1.0*p3*t**3

正如我们所见,变量 p_is 是向量这一事实并不真正相关,除非出现叉积的情况。 如果我要计算 b 与其自身的叉积,那么一些项将会消失,因为某些向量将与自身交叉。

我尝试做的是通过简单的乘法“模拟”叉积,然后迭代所得方程以删除所有平方项(对应于零)。但这还不够 因为该乘积不保留叉积的反计算方面。

我真正想要的是方程中出现实际的叉积符号(比如 X)。我希望我更清楚

非常感谢您的帮助

史蒂夫

最佳答案

我找到了一个适合我的情况的解决方案(我只应用一次叉积,需要一些反射(reflection)来考虑扩展)。这个想法是使用附加符号来表示实现叉积的斜对称矩阵。例如 p0 ^ p1 将写作 Cp0 * p1。我实现了一个方法来实现这一点,并且还确保 pi ^ pi = 0。

为了实现更好的分解,我根据符号的字母顺序引入了任意顺序的转换。 这意味着 p2 ^ p1 将写成 -Cp1 * p2 这样做的原因是 sympy 将无法检测到诸如 Cp2 ^ p1 + Cp1 ^p2 = 0 之类的简化。

无论如何,这相当hacky,但就我而言,它允许我编写我的库,所以就在这里。

执行叉积的方法是“cross”,位于文件末尾。

#declaring vector symbols variables
p_is = [symbols('p'+str(i))  for i in range(20)]
#the cross product will be represented 
#by the skew symmetric matrix Cpi for a vector pi.
#Since in the resulting equation, symbols seem to appeer
#in alphabetic order, the matrix multiplication will be coherent
p_isX = [symbols('Cp'+str(i)+'')  for i in range(20)]

#achieves the cross product between two elements
#s0 and s1 are the considered vector symbols (here, two pis)
#e0 and e1 are the scalar multiplier of each term
def crossElement(s0,e0,s1,e1):
    if s0 == s1:
        return 0
    else:
        # here, take order of apparition into account to allow 
        # future factorization. Otherwise
        # something like p0 X p1 + p1 X p0 will not be dientified as zero
        id0 = p_is.index(s0)
        id1 = p_is.index(s1)
        if(id0 < id1):
            return simplify(e1*e0*p_isX[id0]*s1)
        else:
            return simplify((-e1)*e0*p_isX[id1]*s0)

#retrieve all the pis and associate scalar factors
#from an equation
def getAllSymbols(eq):
    res = []
    for el in p_is:
        dic = eq.as_poly(el).as_dict()
        if(len(dic) > 1): 
            res += [(el, dic[(1,)])]
    return res;

#generates the cross product of two equations,
#where each pi term is a vector, and others
#are scalar variable.
#cross product
def cross(eq1,eq2):
    decomp1 = getAllSymbols(eq1)
    decomp2 = getAllSymbols(eq2)
    res = 0
    #applies distributive cross product between
    #all terms of both equations
    for (s0, e0) in decomp1:
        for (s1, e1) in decomp2:
            res += crossElement(s0,e0,s1,e1)
    return res

关于python - 我可以在 sympy 中使用符号叉积运算吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47656450/

相关文章:

python - 如何在 Django get_context_data 方法中访问模型的外部集合的元素?

python - 收集 sympy 中的相似术语

python - 如何在 sympy 中创建符号变量向量

scilab - 在 Scilab 中生成符号插值多项式

r - 如何在 R 中对多项式回归建模?

haskell - 求多项式的根

python - 如何将元组数据提取为单元素格式

python - 如何将此代码写入单行命令

python - 杀死子进程,并在没有 psutil 或 subprocess 的情况下获取子进程 pid

python - 用 sympy 对方程进行数值计算