我必须对Python,Matlab和C ++的去趋势波动分析的简单程序进行速度比较。不幸的是,我的Python和Matlab代码的速度比我预期的慢了两个数量级。所以我读到的关于这些语言的错误,或者我以非常低效的方式编写代码。 这就是为什么我要问是否有任何明显的方法可以加快下面粘贴的代码。如果您想自己运行代码,可以下载数据here。
Python hrv_dfa模块
import numpy as np
import matplotlib.pyplot as plt
import math
import sys
import time
def hrv_dfa(file, version, verbose):
r_data = np.fromfile(file, dtype=float, count=-1, sep=" ")
# compute intervals
RR = RR_intervals_from_data(r_data)
RRavg = RR.mean(axis = 0)
y = (RR - RRavg).cumsum(axis = 0)
if (verbose):
fig = plt.ion().figure()
fig.ion()
fig.plot(y, 'o')
fig.show()
N = len(y)
#window size
lk = range(5, int(np.floor(N/10)+1))
E = np.zeros((len(lk), 1), dtype=float)
tic = time.time()
for k in range(0, len(lk)):
window = lk[k]
Sq_sum = 0
y_detrended = np.zeros((len(y), 1), dtype=float)
if (version == 1):
for i in range(0, N-window, window):
y_in_window = y[i:i+window]
x_in_window = range(i,i+window)
(a, b) = np.polyfit(x_in_window, y_in_window, 1)
y_regression = np.add(np.multiply(a, x_in_window), b)[np.newaxis]
y_detrended[i:i+window] = y_in_window - y_regression.T # bylo [i:i+window-1]
elif (version == 2):
for i in range(0, N-window):
#wybor danych z danego okna
x_in_window = range(i, i+window)
y_in_window = y[i:i+window]
#regresja liniowa dla danej probki
(a, b) = np.polyfit(x_in_window, y_in_window, 1)
#usuwanie trendu
if (not (window % 2 == 0)):
y_regression = a*(i+window/2+0.5)+b
y_detrended[i] = y[i+window/2+0.5] - y_regression
else:
y_regression1 = a*(i+window/2-0.5)+b
y_regression2 = a*(i+window/2+0.5)+b
y_detrended[i] = (y[i+window/2-0.5] - y_regression1 + y[i+window/2+0.5] - y_regression2)/2
else:
print( 'unsupported window version')
sys.exit([1])
if (verbose):
fig.plot(y_detrended, 'bl-')
fig.show()
Sq_sum = np.dot(y_detrended.T, y_detrended)
E[k] = np.sqrt(Sq_sum/N)
toc = time.time()
len(E)
if verbose:
fig = plt.figure()
x = np.log10(lk)
y = np.log10(E)
if (verbose):
plt.plot(x, y, 'o')
(a, b) = np.polyfit(x, y, 1)
if (verbose):
y_all_fitted = a*x+b
plt.plot(x, y_all_fitted)
#print lk[0:12]
(a1, b1) = np.polyfit(x[0:12], y[0:12], 1)
if (verbose):
y_short_term_fitted = a1*x[0:12]+b1
plt.plot(x[0:12], y_short_term_fitted)
(a2, b2) = np.polyfit(x[12:], y[12:], 1)
if (verbose):
y_long_term_fitted = a2*x[12:]+b2
plt.plot(x[12:], y_long_term_fitted)
if (verbose):
plt.show()
exec_time = toc - tic
print( "a = %f" % a)
print( "a1 = %f" % a1)
print( "a2 = %f" % a2)
print( "exec_time = %f" % exec_time)
#plt.show(block=True)
return a, a1, a2, exec_time
def RR_intervals_from_data(data):
RR = np.zeros((len(data), 1), dtype=float)
for t in range(len(data)-1):
RR[t] = (data[t+1]-data[t])
return RR
if __name__ == "__main__":
hrv_dfa(arg[1], arg[2], arg[3])
Python测试代码(每个样本运行10次并将结果和执行时间保存到csv)
import hrv_dfa34 as hrv_dfa
import sys
import csv
def test_hrv_dfa():
file_numbers = ["100", "101"] #, "102", "103", "104", "105", "106", "107", \
#"108", "109", "111", "112", "113", "114", "115", "116", \
#"117", "118", "119", "121", "122", "123", "124", "201", \
#"202", "203", "205", "207", "208", "209", "210", "212", \
#"213", "214", "215", "217", "219", "220", "221", "222", \
#"223", "228", "230", "231", "232", "233", "234"]
prefix = "..\Data\RPeakData"
file_names = []
for i in range(0, len(file_numbers)):
file_names.append(prefix + file_numbers[i] + ".txt")
for file_number_idx in range(0, len(file_numbers)):
for test_number in range(0, 10):
a, a1, a2, exec_time = hrv_dfa.hrv_dfa(file_names[file_number_idx], 1, False)
with open('fwrite_sw.csv', 'a', newline='') as fwrite_sw:
writer = csv.writer(fwrite_sw, delimiter=';', \
quotechar='"', quoting=csv.QUOTE_MINIMAL)
writer.writerow([file_numbers[file_number_idx], a[0], a1[0], a2[0], exec_time])
#fwrite_sw.write( + " " + a + " " + a1 + " " + a2 + " " + exec_time + "\n")
for file_number_idx in range(0, len(file_numbers)):
for test_number in range(0, 10):
a, a1, a2, exec_time = hrv_dfa.hrv_dfa(file_names[file_number_idx], 2, False)
with open('fwrite_mw.csv', 'a', newline='') as fwrite_mw:
writer2 = csv.writer(fwrite_mw, delimiter=';', \
quotechar='"', quoting=csv.QUOTE_MINIMAL)
writer2.writerow([file_numbers[file_number_idx], a[0], a1[0], a2[0], exec_time])
#fwrite_mw.write(file_numbers[file_number_idx] + " " + a + " " + a1 + " " + a2 + " " + exec_time + "\n")
print('\nDone!')
if __name__ == '__main__':
test_hrv_dfa()
Matlab hrv_dfa模块
function [ alpha, alpha1, alpha2, exec_time ] = hrv_dfa(file, version, verbose)
% skrypt ładujący dane i uruchamiający poszczególne metody hrv_dfa
% metoda 1 - stałe okno (obcinana nadmiarowa część próbek)
% metoda 2 - ślizgające się okno
fileID = fopen(file, 'r');
formatSpec = '%f';
r_data = fscanf(fileID, formatSpec);%cumsum(r_intervals) % << sztuczne dane
fclose(fileID);
%save r_data.out r_data -ASCII
RR = RR_intervals_from_data(r_data);
RRavg = mean(RR);
y = cumsum(RR-RRavg);
N = length(y);
lk = 5:floor(N/10);
E = zeros(1,length(lk));
tic;
for k = 1:length(lk)
window = lk(k);
Sq_sum = 0;
y_detrended = zeros(size(y));
if version == 1
for i = 1:window:(N-window+1)
y_in_window = y(i:i+window-1);
x_in_window = (i:i+window-1)';
linear_regression_coeffs = polyfit(x_in_window, y_in_window,1);
a = linear_regression_coeffs(1);
b = linear_regression_coeffs(2);
y_regression = a*x_in_window+b;
y_detrended(i:i+window-1) = y_in_window - y_regression;
end
elseif version == 2
for i = 1:N-window
x_in_window = (i:i+window-1)';
y_in_window = y(x_in_window);
linear_regression_coeffs = polyfit(x_in_window, y_in_window,1);
a = linear_regression_coeffs(1);
b = linear_regression_coeffs(2);
if (~(mod(window, 2)==0))
y_regression = a*(i+window/2 - 0.5)+b;
y_detrended(i) = y(i + window/2 - 0.5) - y_regression;% +window/2
else
y_regression1 = a*(i+window/2-1)+b;
y_regression2 = a*(i+window/2)+b;
y_detrended(i) = (y(i+window/2-1) - y_regression1 + y(i+window/2) - y_regression2)/2;
end
end
else
exit('unsupported window version');
end
if verbose == true
figure(99);
plot(y)
hold on;
plot(y_detrended)
end
Sq_sum = y_detrended'*y_detrended;
E(k) = sqrt(Sq_sum/N);
end
exec_time = toc;
x = log10(lk);
y = log10(E);
if verbose == true
figure(999);
hold off
plot(x, y, '.')
end
allRegression = polyfit(x,y,1);
alpha = allRegression(1);
beta = allRegression(2);
y_all_fitted = alpha*x+beta;
shortTermRegression = polyfit(x(1:12), y(1:12), 1);
alpha1 = shortTermRegression(1);
beta1 = shortTermRegression(2);
y_short_term_fitted = alpha1*x(1:12)+beta1;
longTermRegression = polyfit(x(12:end), y(12:end), 1);
alpha2 = longTermRegression(1);
beta2 = longTermRegression(2);
y_long_term_fitted = alpha2*x(12:end)+beta2;
if verbose == true
hold on;
h1 = plot(x,y_all_fitted, 'k-', 'LineWidth', 2.5);
h2 = plot(x(1:12), y_short_term_fitted, 'g-', 'LineWidth', 2.5);
h3 = plot(x(12:end), y_long_term_fitted, 'r-', 'LineWidth', 2.5);
legend([h1 h2 h3], {'prosta aproksymująca dla wszystkich lk', ...
'prosta aproksymująca dla log10(5) <= lk <=log10(16)', ...
'prosta paroksymująca dla log10(16) < lk'}, 'Location', 'northwest');
xlabel('log10(lk)');
ylabel('log10(E(lk))');
grid on;
hold off;
end
% helper - returns intervals
function [RR] = RR_intervals_from_data(data)
RR = zeros(size(data));
for t = 1:(size(data)-1)
RR(t) = data(t+1)-data(t);
end
end
end
Matlab测试代码(每个样本运行10次并保存到csv)
file_numbers = ['100'; '101'; '102'; '103'; '104'; '105'; '106'; '107'; ...
'108'; '109'; '111'; '112'; '113'; '114'; '115'; '116'; ...
'117'; '118'; '119'; '121'; '122'; '123'; '124'; '201'; ...
'202'; '203'; '205'; '207'; '208'; '209'; '210'; '212'; ...
'213'; '214'; '215'; '217'; '219'; '220'; '221'; '222'; ...
'223'; '228'; '230'; '231'; '232'; '233'; '234'];
prefix = '..\Data\RPeakData';
file_names = [];
for i = 1:size(file_numbers, 1)
file_names = [file_names; [prefix, file_numbers(i, :), '.txt']];
end
for file_number_idx = 1:size(file_numbers, 1)
for test_number = 1:10
[a, a1, a2, exec_time] = hrv_dfa(file_names(file_number_idx, :), 1, false);
toStore = [str2num(file_numbers(file_number_idx,:)), a, a1, a2, exec_time];
dlmwrite('fmwrite_sw.csv', toStore, '-append', 'delimiter', ';');
end
end
for file_number_idx = 1:length(file_numbers)
for test_number = 1:10
[a, a1, a2, exec_time] = hrv_dfa(file_names(file_number_idx, :), 2, false);
toStore = [str2num(file_numbers(file_number_idx,:)), a, a1, a2, exec_time];
dlmwrite('fmwrite_mw.csv', toStore, '-append', 'delimiter', ';');
end
end
display('Done!');