2014-01-09 14 views
1

Я преобразовываю файл matlab в код python. мой файл MATLAB является:Преобразование кода из matlab в python

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?

+1

какие проблемы? – ShinTakezou

+0

Во-первых, вы не определяете инициализацию 'v' в любом месте' curve_to_q', что может вызвать проблемы. То же самое для 'L'. Если 'v' является массивом, вы должны использовать' * ', а не' np.dot', а если 'v' - это матрица, вы должны использовать' np.multiply' (потому что вы хотите '. *', который является элементарным умножением, а не матричным умножением). – senshin

+0

@ShinTakezou: Я не могу понять, как np.sum (v.np.dot (v))) будет работать в python? – sam

ответ

1

Работая с numpy, лучше инициализировать все массивы как массивы numpy, а не массивы python (списки списков), а затем преобразовать их в numpy во время выполнения. Итак, для первого шага я поставил v = np.zeros(n, N) для инициализации. Это должно решить вашу вторую проблему.

Следующий шаг - сделать ваш код более читаемым. Удалите N + 1/i-1 и т. Д. L не обязательно должен быть списком - только текущее значение когда-либо используется, поэтому измените его на локальную переменную, а не на список.

В matlab: v.*v не является точечным продуктом, это элемент по умножению элементов на два массива. Кроме того, когда вы пытаетесь взять точечный продукт v с собой, v не является квадратным, поэтому он не будет работать. Тем не менее, мы можем использовать dot-продукт с транспозицией, чтобы упростить этот шаг.

Код, приведенный ниже, должен помочь. Первый sum в коде matlab суммируется по «размеру первого массива» (я забыл, что это такое) - так что вам нужно будет проверить, что v_squared_sum имеет одинаковые размеры на обоих языках.

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_ 
0

Вашей первая проблема заключается в том, что в Matlab, sum суммы за последнее измерение по умолчанию, в то время как в NumPy, np.sum суммы по сплющенному массиву по умолчанию.

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.

Смежные вопросы