Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python NumPy:n个向量的稀疏外积(双曲线交叉)_Python_Algorithm_Performance_Numpy - Fatal编程技术网

Python NumPy:n个向量的稀疏外积(双曲线交叉)

Python NumPy:n个向量的稀疏外积(双曲线交叉),python,algorithm,performance,numpy,Python,Algorithm,Performance,Numpy,我试图计算n向量的完全外积的某个子集。完整外积的计算如中所述 形式上:设v1,v2,…,vk为某种长度的向量n,K为正常数。我想要一个包含所有产品的列表,v1[i1]v2[i2]…vk[ik]对于这些产品,i1*i2*…*ik如果索引与简单循环相比变得太混乱,我通常用C编写swig包装器和生成函数。这可以实现良好的性能(很容易用openmp并行执行),保持逻辑性和可读性,并且在我的numpy调用之间作为函数很好地匹配。由于这不是一个“纯”的numpy解决方案,我把它作为一个注释放在这里。您能展示

我试图计算
n
向量的完全外积的某个子集。完整外积的计算如中所述


形式上:设
v1
v2
,…,
vk
为某种长度的向量
n
K
为正常数。我想要一个包含所有产品的列表,
v1[i1]v2[i2]…vk[ik]
对于这些产品,
i1*i2*…*ik如果索引与简单循环相比变得太混乱,我通常用C编写swig包装器和生成函数。这可以实现良好的性能(很容易用openmp并行执行),保持逻辑性和可读性,并且在我的numpy调用之间作为函数很好地匹配。由于这不是一个“纯”的numpy解决方案,我把它作为一个注释放在这里。您能展示一下当前解决方案的代码,以及一个带有预期输入和输出的详细工作示例吗?因为这不容易理解这到底是如何工作的。特别是,可以有多组索引来验证
i1*i2*…*ik
,那么您如何知道应该使用哪些索引呢?还是我遗漏了什么?(关于你链接到的外部产品的另一篇文章中没有提到这个条件。)那么,一个常规的叉积就是
k
k
都等于2或3吗?你对这些产品加总了吗?
import numpy as np

def get_cross_indices(n, k, K):
    """
    Assume k > 0.
    Returns a hierarchical list containg elements of type
      (i1, list) with
        - i1 being a index (zero based!)
        - list being again a list (possibly empty) with all indices i2, such
          that (i1+1) * (i2+1) * ... * (ik+1) <= K  (going down the hierarchy)
    """
    if k == 1:
        num = min(n, K)
        return (num, [(x, []) for x in range(num)])
    else:
        indices = []
        nums = 0
        for i in xrange(min(n, K)):
            (num, tail) = get_cross_indices(n,
                k - 1, K // (i + 1))
            indices.append((i,  tail))
            nums += num
        return (nums, indices)

def calc_cross_outer_product(vectors, result, factor, indices, pos):
    """
    Fills the result list recursively with all products
        vectors[0][i1] * ... * vectors[k-1][ik]

    such that i1,...,ik is a feasible index sequence
    from `indices` (they are in there hierarchically,
    also see `get_cross_indices`).
    """
    for (x, list) in indices:
        if not list:
            result[pos] = factor * vectors[0][x]
            pos += 1
        else:
            pos = calc_cross_outer_product(vectors[1:], result,
                factor * vectors[0][x], list, pos)
    return pos

k = 3 # number of vectors
n = 4 # vector length
K = 3
# using random values here just for demonstration purposes
vectors = np.random.rand(k, n)

# get all indices which meet the condition
(count, indices) = get_cross_indices(n, k, K)

result = np.ones(count)
calc_cross_outer_product(vectors, result, 1, indices, 0)


## Equivalent version ##
alt_result = np.ones(count)
# create full outer products
outer_product = reduce(np.multiply, np.ix_(*vectors))
pos = 0
for inds in np.ndindex((n,)*k):
    # current index set is feasible?
    if np.product(np.array(inds) + 1) <= K:
        # compute [ vectors[0][inds[0]],...,vectors[k-1][inds[k-1]] ]
        values = map(lambda x: vectors[x[0]][x[1]],
            np.dstack((np.arange(k), inds))[0])
        alt_result[pos] = np.product(values)
        pos += 1