有效地计算numpy中的parafac/CP产品

ant*_*ine 6 python numpy

这个问题集中在numpy上.

我有一组矩阵,它们共享相同数量的列并具有不同的行数.我们称它们为A,B,C,D等,让它们的尺寸为IaxK IbxK,IcxK等

我想要的是有效地计算IaxIbxIc ...张量P定义如下:P(ia,ib,ic,id,即......)=\sum_k A(ia,k)B(ib,k)C (IC,K)...

因此,如果我有两个因素,我最终得到简单的矩阵产品.

当然,我可以通过外部产品"手动"计算,例如:

    def parafac(factors,components=None):
        ndims = len(factors)
        ncomponents = factors[0].shape[1]
        total_result=array([])
        if components is None:
            components=range(ncomponents)

        for k in components:
            #for each component (to save memory)
            result = array([])
            for dim in range(ndims-1,-1,-1):
                #Augments model with next dimension
                current_dim_slice=[slice(None,None,None)]
                current_dim_slice.extend([None]*(ndims-dim-1))
                current_dim_slice.append(k)
                if result.size:
                    result = factors[dim].__getitem__(tuple(current_dim_slice))*result[None,...]
                else:
                    result = factors[dim].__getitem__(tuple(current_dim_slice))
            if total_result.size:
                total_result+=result
            else:
                total_result=result
        return total_result
Run Code Online (Sandbox Code Playgroud)

不过,我想要一些计算效率更高的东西,比如依赖内置的numpy函数,但我找不到相关的函数,有人可以帮助我吗?

干杯,谢谢

ant*_*ine 4

非常感谢大家的解答,我花了一天的时间终于找到了解决方案,所以我将其发布在这里以供记录

该解决方案需要 numpy 1.6 并使用 einsum,这是强大的巫术魔法

基本上,如果你有因子= [A,B,C,D],其中A,B,C和D矩阵具有相同的列数,那么你将使用以下方法计算parafac模型:

import numpy
P=numpy.einsum('az,bz,cz,dz->abcd',A,B,C,D)
Run Code Online (Sandbox Code Playgroud)

所以,一行!

在一般情况下,我最终会得到这样的结果:

def parafac(factors):
    ndims = len(factors)
    request=''
    for temp_dim in range(ndims):
        request+=string.lowercase[temp_dim]+'z,'
    request=request[:-1]+'->'+string.lowercase[:ndims]
    return einsum(request,*factors)
Run Code Online (Sandbox Code Playgroud)