我想尝试从Matlab到Python实现以下代码(我一般不熟悉Python,但我尝试使用基础知识从Matlab翻译它(
% n is random integer from 1 to 10
% first set the random seed (because we want our results to be reproducible;
% the seed sets a starting point in the sequence of random numbers the program
rng(n)
% Generate random columns
a = rand(n, 1);
b = rand(n, 1);
c = rand(n, 1);
% Convert to a matrix
A = zeros(n);
for i = 1:n
if i ~= n
A(i + 1, i) = a(i + 1);
A(i, i + 1) = c(i);
end
A(i, i) = b(i);
end
这是我在Python中的尝试:
import numpy as np
## n is random integer from 1 to 10
np.random.seed(n)
### generate random columns:
a = np.random.rand(n)
b = np.random.rand(n)
c = np.random.rand(n)
A = np.zeros((n, n)) ## create zero n-by-n matrix
for i in range(0, n):
if (i != n):
A[i + 1, i] = a[i + 1]
A[i, i + 1] = c[i]
A[i, i] = b[i]
我在线路A[i + 1, i] = a[i]
上遇到一个错误。Python中有没有我遗漏的结构?
由于上面的注释清楚地指出了索引错误,这里有一种基于np.diag:的numpy方法
import numpy as np
# for reproducibility
np.random.seed(42)
# n is random integer from 1 to 10
n = np.random.randint(low=1, high=10)
# first diagonal below main diag: k = -1
a = np.random.rand(n-1)
# main diag: k = 0
b = np.random.rand(n)
# first diagonal above main diag: k = 1
c = np.random.rand(n-1)
# sum all 2-d arrays in order to obtain A
A = np.diag(a, k=-1) + np.diag(b, k=0) + np.diag(c, k=1)
简单的答案是for i = 1:n
迭代[1, n]
,在两个边界上都包含,而for i in range(n):
迭代[0, n)
,在右边界上不包含。因此,检查if i ~= n
可以正确地测试您是否处于右边缘,而if (i!=n):
则不会。更换为
if i != n - 1:
长期的答案是,你不需要任何一种语言的代码,因为MATLAB和numpy都是用于矢量化操作的。在MATLAB中,您可以编写
A = diag(a(2:end), -1) + diag(b, 0) + diag(c(1:end-1), +1)
在numpy中,它非常相似:
A = np.diag(a[1:], -1) + np.diag(b, 0) + np.diag(c[:-1], +1)
你还可以使用其他技巧,尤其是如果你只想在矩阵中使用随机数:
A = np.random.rand(n, n)
A[np.tril_indices(n, -2)] = A[np.triu_indices(n, 2)] = 0
您可以使用其他基于索引的方法:
i, j = np.diag_indices(n)
i = np.concatenate((i[:-1], i, i[1:]))
j = np.concatenate((j[1:], j, j[:-1]))
A = np.zeros((n, n))
A[i, j] = np.random.rand(3 * n - 2)