我正在将matlab文件转换为python代码。我的matlab文件是:
function [q,len] = curve_to_q(p)
[n,N] = size(p);
for i = 1:n
v(i,:) = gradient(p(i,:),1/(N));
end
len = sum(sqrt(sum(v.*v)))/N;
v = v/len;
for i = 1:N
L(i) = sqrt(norm(v(:,i)));
if L(i) > 0.0001
q(:,i) = v(:,i)/L(i);
else
q(:,i) = v(:,i)*0.0001;
end
end
转换后的代码是:
from __future__ import division
import numpy as np
from scipy.io import loadmat,savemat
import os
def curve_to_q(p):
n, N = p.shape # nargout=2
for i in range(1, (n +1)):
v[(i -1), :] = np.gradient(p[(i -1), :], 1 / (N))
len_ = np.sum(np.sqrt(np.sum(v.np.dot(v)))) / N
v = v / len_
for i in range(1, (N +1)):
L[(i -1)] = sqrt(norm(v[:, (i -1)]))
if L[(i -1)] > 0.0001:
q[:, (i -1)] = v[:, (i -1)] / L[(i -1)]
else:
q[:, (i -1)] = v[:, (i -1)] * 0.0001
return q, len_
但是,
似乎存在问题len_ = np.sum(np.sqrt(np.sum(v.np.dot(v)))) / N
和
L[(i -1)] = sqrt(norm(v[:, (i -1)]))
如何正确转换为python?
答案 0 :(得分:1)
使用numpy,最好将所有数组初始化为numpy数组而不是python数组(列表列表),然后在执行时转换为numpy。因此,对于第一步,我将v = np.zeros(n, N)
置于初始化状态。这应该可以解决你的第二个问题。
下一步是让您的代码更具可读性。删除N + 1 / i-1等。L
不需要是列表 - 只使用当前值,因此将其更改为局部变量而不是列表。
在matlab中:v.*v
不是点积,它是两个数组的元素乘法元素。此外,当您尝试将v
的点积与其自身对应时,v不是正方形,因此它将无法工作。但是,我们可以使用带有转置的点积来简化此步骤。
以下代码应该有所帮助。 matlab代码中的第一个sum
对“第一个数组维度”进行求和(我忘了这是哪一个) - 因此您必须检查v_squared_sum
在两种语言中是否具有相同的维度。 / p>
def curve_to_q(p):
n, N = p.shape # nargout=2
v = np.zeros((n, N))
for i in range(n):
v[i, :] = np.gradient(p[i, :], 1 / N)
v_squared_sum = v.dot(v.transpose()) # 1 x (n or N) array
len_ = np.sum(np.sqrt(v_squared_sum)) / N
v = v / len_
for i in range(N):
L = sqrt(norm(v[:, i]))
q[:, i] = v[:, i] / max(L, 0.0001)
return q, len_
答案 1 :(得分:0)
你的第一个问题是,在Matlab中,默认情况下,sum
对最后一个维度求和,而在默认情况下,对于展平数组的np.sum
求和。{/ p>
Matlab的
>> sum([5,5,5;5,5,5])
ans =
10 10 10
的Python:
>>> np.sum([[5,5,5],[5,5,5]])
30
你需要在python中使用这样的东西:
>>> np.sum([[5,5,5],[5,5,5]], axis=0)
array([10, 10, 10])
第二个问题是您需要np.sqrt
和np.norm
,而不是sqrt
和norm
。