python中多项式的唯一元素

2024-04-16 06:08:51 发布

您现在位置:Python中文网/ 问答频道 /正文

在python中展开和的乘积时,我需要得到成对项。你知道吗

例如,扩展(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方法吗?你知道吗


Tags: 方法a2元素a1nparray向量b2
2条回答

我不知道它是否比您当前的实现快,但是通过滚动NumPy数组(special_sum下面),您可以避免比“显而易见的”实现(regular_sum)更快地出现索引重复的术语:

a = np.random.randint(15, size=100)
b = np.random.randint(15, size=100)
c = np.random.randint(15, size=100)

def regular_sum(a, b, c):
    n = len(a)
    s = 0
    for i in range(n):
        for j in range(n):
            for k in range(n):
                if i==j or i==k or j==k:
                    continue
                s += a[i] * b[j] * c[k]
    return s

def special_sum(a, b, c):

    # all combinations b1c1, b1c2, b1c3, b2c1, ..., b3c3
    A = np.outer(b, c)
    # remove bici terms
    np.fill_diagonal(A, 0)

    # Now sum terms like: a1 * (terms without b1 or c1),
    # a2 * (terms without b2 or c2), ..., rolling the array A
    # to keep the unwanted terms in the first row and first column:
    s = 0
    for i in range(0,len(a)):
        s += np.sum(a[i] * A[1:,1:])
        A = np.roll(A, -1, axis=0)
        A = np.roll(A, -1, axis=1)
    return s

我得到:

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

像这样的怎么样?这会加速你的计算吗?你知道吗

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))

相关问题 更多 >