python中多项式的唯一元素

python中多项式的唯一元素,python,numpy,Python,Numpy,在python中展开和的乘积时,我需要得到成对项 e、 g.扩展(a1+a2+a3)(b1+b2+b3)(c1+c2+c3)给出: a1b1c1+a1b1c2+a1b1c3+a1b2c1+…+a3b3c3 有22条或更多条款 我需要找到一种方法来删除索引匹配的扩展中的任何元素(例如,任何带有a1和b1,或b2和c2的元素) 或在代码中: import numpy as np a = np.array([0,1,2]) b = np.array([3,4,5]) c = np.array([6,7

在python中展开和的乘积时,我需要得到成对项

e、 g.扩展
(a1+a2+a3)(b1+b2+b3)(c1+c2+c3)
给出:

a1b1c1+a1b1c2+a1b1c3+a1b2c1+…+a3b3c3

有22条或更多条款

我需要找到一种方法来删除索引匹配的扩展中的任何元素(例如,任何带有a1和b1,或b2和c2的元素)

或在代码中:

import numpy as np
a = np.array([0,1,2])
b = np.array([3,4,5])
c = np.array([6,7,8])

output = a.sum() * b.sum() * c.sum()
我需要删除术语
a[I]*b[j]*c[k]
,其中I==j,I==k或j==k

对于小的向量,这很简单,但是随着这些向量变长,它们的数量越来越多,有更多可能的组合可以尝试(我的向量是~200个元素)

我的老板在Mathematica中有一个这样做的方案,它显式地进行代数展开,并提取具有匹配指数的项,但这在很大程度上依赖于Mathematica的符号代数设置,所以我看不到如何在Python中实现它

itertools.combinations
为您提供了所有此类组合的列表,但对于较长的向量来说,这是非常缓慢的。我还研究了如何使用
sympy
,但这似乎也不适用于很长的向量


有人能推荐一种更好的Python方法吗?

类似的方法怎么样?这会加速你的计算吗

import numpy as np
import itertools
a = np.array([0,1,2])
b = np.array([3,4,5])
c = np.array([6,7,8])

combination = [a, b, c]
added = []

# Getting the required permutations
for p in itertools.permutations(range(len(a)), len(a)):
    # Using iterators and generators speeds up your calculations
    # zip(combination, p) pairs the index to the correct lists
    # so for p = (0, 1, 2) we get (a,0), (b, 1), (c, 2)
    # now find sum of (a[0], b[1], c[2]) and appened to added
    added.append(sum(i[j] for i, j in zip(combination, p)))

# print added and total sum
print(added)
print(sum(added))

我不知道它是否比您当前的实现快,但是通过滚动一个NumPy数组(
special\u sum
),您可以避免比“显而易见的”实现更快地复制索引的术语(
regular\u sum
):

我得到:

In [44]: %timeit regular_sum(a,b,c)
1 loops, best of 3: 454 ms per loop

In [45]: %timeit special_sum(a,b,c)
100 loops, best of 3: 6.44 ms per loop

第一步可以是查看:它的返回值是
out[i,j]=A[i]*b[j]
。因此,将对角线设置为
0
,然后求和得到第一次展开所需的结果。不过,我不确定第二次扩建的情况。总是有3个不同但相同维度的向量吗?我的第一次尝试与此非常相似,但当你通过第一次扩展时,我也遇到了麻烦。更棘手的是,载体的数量会发生变化(这是一个基于遗传标记将半同胞分为全同胞的方案,你无法提前知道应该有多少全同胞)。谢谢你的提示!但是,是的,我尝试了长度为100的向量,它已经很难做到了。对于长度为1000的向量,我的机器在22.8秒内完成了
special_sum
。当然是一个巨大的进步!
In [44]: %timeit regular_sum(a,b,c)
1 loops, best of 3: 454 ms per loop

In [45]: %timeit special_sum(a,b,c)
100 loops, best of 3: 6.44 ms per loop