Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.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
如何将带有网格和数组的Matlab代码转换为Python代码?_Python_Matlab_Numpy - Fatal编程技术网

如何将带有网格和数组的Matlab代码转换为Python代码?

如何将带有网格和数组的Matlab代码转换为Python代码?,python,matlab,numpy,Python,Matlab,Numpy,我正试图写一个程序来构造一个矩阵,并对其进行奇异值分解。我正在网格上评估函数ax^2+bx+1。然后,我将a和b组成一个统一的网格。矩阵的行对应于不同的二次系数,而每列对应于计算函数的网格点 matlab代码如下所示: % Collect data x = linspace(-1,1,100); [a,b] = meshgrid(0:0.1:1,0:0.1:1); D=zeros(numel(x),numel(a)); sz = size(D) % Build “Dose” matrix

我正试图写一个程序来构造一个矩阵,并对其进行奇异值分解。我正在网格上评估函数ax^2+bx+1。然后,我将
a
b
组成一个统一的网格。矩阵的行对应于不同的二次系数,而每列对应于计算函数的网格点

matlab代码如下所示:

% Collect data

x = linspace(-1,1,100);

[a,b] = meshgrid(0:0.1:1,0:0.1:1);

D=zeros(numel(x),numel(a));
sz = size(D)
% Build “Dose” matrix

for i=1:numel(a)

D(:,i) = a(i)*x.^2+b(i)*x+1;

end

% Do the SVD:

[U,S,V]=svd(D,'econ');

D_reconstructed = U*S*V';

plot(diag(S))
scatter3(a(:),b(:),V(:,1))

这是我尝试的解决方案:


import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)

def f(x, a, b):
    return a*x*x + b*x + 1

a, b = np.mgrid[0:1:0.1,0:1:0.1]
#a = b = np.arange(0,1,0.01)

D = np.zeros((x.size, a.size))

for i in range(a.size):
    D[i] = a[i]*x*x +b[i]*x +1

U, S, V = np.linalg.svd(D)

plt.plot(np.diag(S))

fig = plt.figure()
ax = plt.axes(projection="3d")


ax.scatter(a, b, V[0])

但我总是会遇到广播错误,我不知道如何修复。

首先,在MATLAB中,您将分配给
D(:,I)
,但在python中,您将分配给
D[I]
。后者相当于
D[i,…]
,在您的例子中是
D[i,:]
。相反,您似乎需要
D[:,i]

其次,在MATLAB中,使用二维数组的线性索引(即
a
b
)将为您提供平坦视图。如果您使用numpy执行此操作,则会得到数组的切片,就像我在
D[I]
中提到的那样

通过
.ravel
ling(或重塑)您的
a
b
阵列,您可以取消循环并获得所需的2d阵列:

x = np.linspace(-1, 1, 100)[:, None]  # inject trailing singleton for broadcasting
a, b = np.mgrid[0:1:0.1, 0:1:0.1]
D = a.ravel() * x**2 + b.ravel() * x + 1
其工作方式是,在我们注入一个尾随单体后,
x
具有形状
(100,1)
(在MATLAB中,尾随单体是隐含的,在numpy的前导单体中),并且
a.ravel()
b.ravel()
都具有形状
(10*10,)
,这与
(1,10*10)兼容,使广播成为可能的形状
(100,10*10)
。您还可以将对
ravel
的调用替换为

a, b = np.mgrid[...].reshape(2, -1)
这是我有时使用的技巧,但是如果你不熟悉这个模式,这就很难理解了


旁注:最好在维度大小不同的情况下使用示例数据,以便注意是否有东西最终被转置。

首先,在MATLAB中,您将赋值给
D(:,i)
,但在python中,您将赋值给
D[i]
。后者相当于
D[i,…]
,在您的例子中是
D[i,:]
。相反,您似乎需要
D[:,i]

其次,在MATLAB中,使用二维数组的线性索引(即
a
b
)将为您提供平坦视图。如果您使用numpy执行此操作,则会得到数组的切片,就像我在
D[I]
中提到的那样

通过
.ravel
ling(或重塑)您的
a
b
阵列,您可以取消循环并获得所需的2d阵列:

x = np.linspace(-1, 1, 100)[:, None]  # inject trailing singleton for broadcasting
a, b = np.mgrid[0:1:0.1, 0:1:0.1]
D = a.ravel() * x**2 + b.ravel() * x + 1
其工作方式是,在我们注入一个尾随单体后,
x
具有形状
(100,1)
(在MATLAB中,尾随单体是隐含的,在numpy的前导单体中),并且
a.ravel()
b.ravel()
都具有形状
(10*10,)
,这与
(1,10*10)兼容,使广播成为可能的形状
(100,10*10)
。您还可以将对
ravel
的调用替换为

a, b = np.mgrid[...].reshape(2, -1)
这是我有时使用的技巧,但是如果你不熟悉这个模式,这就很难理解了


旁注:最好在维度大小不同的情况下使用示例数据,以便您注意到是否有东西最终被转置。

不确定您想用什么:对于范围内的i(a.size):D[i]=a[i]*x*x+b[i]*x+1,但您的问题是a和b是10,10,但D是100100,x是100,1.x是100x1向量,而a是10x10矩阵。试试x.shape,a.shape来检查。嗨,Paula,我希望我的D矩阵是一个m x n矩阵,其中a是我拥有的a和b系数的数量,n是我拥有的x点的数量。每行对应一个不同的值a,b,而每列对应一个网格点,在该网格点上计算二次曲线。为什么它在Matlab而不是Python中工作?但我总是收到广播错误,请分享整个错误消息。你看过NumPy文件了吗?这将是一个合乎逻辑的起点,不是吗?不确定你想要做什么:对于范围内的i(a.size):D[i]=a[i]*x*x+b[i]*x+1,但你的问题是a和b是10,10,但D是100100,x是100,1.x是100x1向量,而a是10x10矩阵。试试x.shape,a.shape来检查。嗨,Paula,我希望我的D矩阵是一个m x n矩阵,其中a是我拥有的a和b系数的数量,n是我拥有的x点的数量。每行对应一个不同的值a,b,而每列对应一个网格点,在该网格点上计算二次曲线。为什么它在Matlab而不是Python中工作?但我总是收到广播错误,请分享整个错误消息。你看过NumPy文件了吗?这是一个合乎逻辑的开始,不是吗?谢谢,我不会想到使用
ravel
。有一个问题,在matlab和python中,
D
数组中的元素似乎略有不同。你知道为什么吗?@pythonraptor原因可能是浮点运算不精确,一个可能的来源是meshgrid/mgrid调用。0.1是出了名的不可精确表示的(参见例如,
0.1*3==0.3
不是双精度的),并且可能涉及到两种实现之间不同的优化(例如)。或者,
linspace
也有类似的区别。或者,双值的打印可能不同。无论哪种方法,你都会在最新的
svd
阶段得到数值上的差异。@pythonraptor哦,是的,还有一件重要的事情:在MATLAB中,线性索引逐列进行,但在numpy中,线性索引逐行进行。这可能意味着您可能必须使用
a.T.ravel()
等来获得与MATLAB中相同的
D
中的项目顺序。您可以通过为
mgrid
中的两个参数使用不同的范围来确保,最好使用不同的大小,以及c