Python 如何将np.linalg.solve映射到矩阵数组并保持速度?
我有一个线性问题要解决很多次:Ax=B A是一个维数为n的方阵,B是一个维数为n的向量。我需要找到x:Python 如何将np.linalg.solve映射到矩阵数组并保持速度?,python,numpy,linear-algebra,Python,Numpy,Linear Algebra,我有一个线性问题要解决很多次:Ax=B A是一个维数为n的方阵,B是一个维数为n的向量。我需要找到x: import numpy as np A = np.random.rand(2,2) B = np.random.rand(2) x = np.linalg.solve(A,B) 这是非常基本的。问题是我想多次解决这个问题。当前的实现如下所示: import numpy as np k = 50 # the number of systems to solve A_list = np.ran
import numpy as np
A = np.random.rand(2,2)
B = np.random.rand(2)
x = np.linalg.solve(A,B)
这是非常基本的。问题是我想多次解决这个问题。当前的实现如下所示:
import numpy as np
k = 50 # the number of systems to solve
A_list = np.random.rand(k,2,2)
B_list = np.random.rand(k,2)
x = np.array([np.linalg.solve(A,B) for A, B in zip(A_list, B_list)])
但是它相当慢。在这个网站的帮助下,我可以使用np.newaxis
进行智能广播,从而消除代码中的一个巨大瓶颈。我想知道这类函数是否有类似的技巧(np.linalg.solve
,np.linalg.det
,等等)
我用np.vectorize
测试失败
编辑:
输出
>>将numpy作为np导入
>>>k=50#需要求解的系统数
>>>A_list=np.random.rand(k,2,2)
>>>B_list=np.random.rand(k,2)
>>>x=np.array([np.linalg.solve(A,B)表示zip中的A,B(A_列表,B_列表)])
---------------------------------------------------------------------------
LinalError回溯(最近一次调用上次)
在()
---->1解=np.linalg.solve(A_列表,B_列表)
/solve(a,b)中的usr/lib/python3.3/site-packages/numpy/linalg/linalg.py
309如果一个均衡器:
310 b=b[:,新轴]
-->311_资产等级2(a、b)
312_资产平方度(a)
313 n_eq=a.shape[0]
/usr/lib/python3.3/site-packages/numpy/linalg/linalg.py in_assertRank2(*数组)
153如果len(a.形状)!=2:
154 raise LinAlgError(“%d-维数组已给定。数组必须为”
-->155'二维“%len(a.形状))
156
157 def_assertSquareness(*数组):
LinalError:给定了三维数组。数组必须是二维的
Numpy 1.8
您不必从numpy版本开始执行任何操作:
演示:
Numpy 1.7及更早版本
在较旧的版本上,可以尝试使用scipy.linalg.block_diag
,但它会带来一些开销,包括内存和速度,对于较大的k,它将失去zip
方法:
import scipy.linalg
A = scipy.linalg.block_diag(*A_list)
B = B_list.reshape(-1)
solution = np.linalg.solve(A,B)
solution.reshape(-1,2)
1.8的速度测试
对于k=2000;种子=11
:
>>> timeit('from __main__ import np, A_list, B_list; np.linalg.solve(A_list, B_list)', number = 100)
0.2786309433182055
>>> timeit('from __main__ import np, A_list, B_list; np.array([np.linalg.solve(A,B) for A, B in zip(A_list, B_list)])', number = 100)
8.431871369126554
>>> timeit('from __main__ import np, A, B; np.linalg.solve(A,B)', number = 100)
43.4851636171674712
哦,我明白了。。。也许是裸体版。。。1.7.1. 这里有明确的断言。您能在您和我的解决方案中添加
%timeit
的结果吗?只是为了计算出速度差的数量级。如果可以的话,我希望你对k=2000或者类似的东西做同样的事情。“那就是它了。”盖尔找速度测试专家!这是伟大的,有一个想法的相对速度,这些。再次感谢。是的,检查了1.7,这确实是一个新的算法实现啊好,那么除了升级没有解决方案
>>> import numpy as np
>>> np.random.seed(11)
>>> k = 10
>>> A_list = np.random.rand(k,2,2)
>>> B_list = np.random.rand(k,2)
>>> solution = np.linalg.solve(A_list,B_list)
>>> all(np.allclose(np.dot(A_list[i, :], solution[i,:]), B_list[i, :])
... for i in range(A_list.shape[0]))
True
import scipy.linalg
A = scipy.linalg.block_diag(*A_list)
B = B_list.reshape(-1)
solution = np.linalg.solve(A,B)
solution.reshape(-1,2)
>>> timeit('from __main__ import np, A_list, B_list; np.linalg.solve(A_list, B_list)', number = 100)
0.2786309433182055
>>> timeit('from __main__ import np, A_list, B_list; np.array([np.linalg.solve(A,B) for A, B in zip(A_list, B_list)])', number = 100)
8.431871369126554
>>> timeit('from __main__ import np, A, B; np.linalg.solve(A,B)', number = 100)
43.4851636171674712