为什么numpy.linalg.solve()对于相同大小的数组具有非恒定的计算时间?

时间:2019-02-18 01:15:39

标签: python numpy linear-algebra

我一直在使用numpy.linalg.solve(A,B)来求解线性方程。就我而言:A约为10,000x10,000,而B约为10,000x5。如果我使用以下方法随机初始化AB

A = numpy.random.rand(10000,10000)
B = numpy.random.rand(10000,5)

则计算时间为<3秒。但是,在需要求解该方程的程序中,计算时间始终约为14秒。这段代码是在一个循环中迭代的,因此加速将近5倍非常重要。 linalg.solve()的解对于常数大小的数组应该不是大致恒定的吗?

两个实现都使用float64。而且肯定有足够的内存(128 GB)。我尝试更新计算机上的blas库(Ubuntu 16.04-安装了conda的numpy),它显示了随机生成的数据对解决方案的改进,但不适用于程序中的数据。

如果有人在寻找有关该代码的更多详细信息,请访问[1]中.py文件的第27行。该程序正在注册点云。

任何想法或帮助将不胜感激。

[1] https://github.com/siavashk/pycpd/blob/master/pycpd/deformable_registration.py

编辑: 为了使它更具可重复性,我生成了一些代码来尝试将我带到可疑的np.linalg.solve()行:

import numpy as np
import time

def gaussian_kernel(Y, beta):
    diff = Y[None,:,:] - Y[:,None,:]
    diff = diff**2
    diff = np.sum(diff, axis=2)
    return np.exp(-diff / (2 * beta**2))

def initialize_sigma2(X, Y):
    diff = X[None,:,:] - Y[:,None,:]
    err  = diff**2
    return np.sum(err) / (X.shape[0] * Y.shape[0] * X.shape[1])

alpha = 0.1
beta = 3

X = np.random.rand(10000,5) * 100
Y = X + X*0.1

N, D = X.shape
M, _ = Y.shape

G = gaussian_kernel(Y, beta)
sigma2 = initialize_sigma2(X,Y)

TY = Y + np.random.rand(10000,5)

P = np.sum((X[None,:,:] - TY[:,None,:])**2, axis=2)
P /= np.sum(P,axis=0)

P1 = np.sum(P, axis=1)
Np = np.sum(P1)

A = np.dot(np.diag(P1), G) + alpha * sigma2 * np.eye(M)
B = np.dot(P, X) - np.dot(np.diag(P1), Y)

%time W = np.linalg.solve(A,B)

但是,此代码不会产生时间滞后。除了X和Y数组的实际创建之外,所有内容都与当前脚本中的所有内容相同。这些应该是在3D空间中彼此接近的两个点云-这就是为什么我基于另一个创建了一个点云的原因。

0 个答案:

没有答案