我想要一个非常快速的实现来计算我的时间序列上的移动窗口偏斜度,因为我必须为许多不同的窗口大小做这件事,并且应用程序是时间关键的(类似地,对于其他度量,如峰度,均方根,自相关等,也要这样做)。在这里,我专注于偏度。
我有一个时间序列数据数组state_timeseries
(~ 10,000,000)和相应的时间值。我想使用窗口大小(~ 300,000 - 4,000,000)和步长(=相应窗口大小的1%= 3000 - 40000)来查找此时间序列的移动窗口偏斜度。对于以下列表中的所有窗口尺寸,均应执行此操作:
window_size_list = floor(linspace(300000, 4000000, 200));
step_size_list = floor(window_size_list * (1 / 100));
对于并行计算,我有16个工作人员,拥有约130 GB RAM和GeForce RTX 2070 Super 8 GB大小。
如果我用C来做这些计算,有可能获得很好的速度增益吗?(我不知道C,但阅读在线让我想到这一点)。然后将生成的移动窗口偏度时间序列返回MATLAB进行进一步处理。
我的当前实现:
目前,我只是简单地循环(包括窗口大小和每个窗口的移动窗口),如下所示(但这相当慢):
% Dummy data of equal length
state_timeseries = randn(1, 10000000);
time = 1: length(state_timeseries);
total_window_count = 200; % 200 as used above
window_size_list = floor(linspace(300000, 4000000, total_window_count));
step_size_list = floor(window_size_list * (1 / 100));
for k = 1: total_window_count
% Set window size and step size to calculate the corresponding EWS timeseries
window_size = window_size_list(k);
window_step = step_size_list(k);
% Generate EWS timeseries for particular window size
Data_skewness_timeseries{k} = sk_timeseries_func(time, state_timeseries, window_size, window_step);
end
function Data = sk_timeseries_func(time, state_timeseries, window_size, window_step)
% Use GPU if available
gpu_available = canUseGPU();
if gpu_available == 1
time = gpuArray(time);
state_timeseries = gpuArray(state_timeseries);
end
% Get the indices where windows start and the corresponding times at which they end.
% This is to specify the skewness of a window at the time value at the end of the window.
window_idx = 1: window_step: (length(time) - window_size + 1);
time_window_ends_idx = window_idx + window_size - 1;
time_window_ends = time(time_window_ends_idx);
sk_timeseries = zeros(1, length(time_window_ends));
for i_window = 1: length(window_idx)
timeseries_window_data = state_timeseries(window_idx(i_window): window_idx(i_window) + window_size - 1);
sk_timeseries(i_window) = skewness(timeseries_window_data);
end
Data.time_window_ends = time_window_ends;
Data.sk_timeseries = sk_timeseries;
end
1条答案
按热度按时间lnxxn5zx1#
用C或其他编译语言重写不会给你给予20年前的100倍速度。根据具体的MATLAB代码,您可能会获得2倍的速度,也可能会获得更慢的代码。
你在使用GPU。我不知道它在这个程序中的效果(你没有比较吗?)),在C中,如果您知道如何做到这一点,您可能能够更精确地控制它,从而获得非常有效的代码。同样,我不知道你目前的GPU代码有多高效,我没有这方面的经验。
如果你有并行处理工具包,你应该使
total_window_count
上的循环并行(使用基于线程的并行池)。通常,大的速度改进总是来自更好的算法。Note that you can compute skewness on line.。这意味着当你移动窗口时,你可以在窗口的开始处删除样本,并在结尾处添加新的样本。这可能会节省99%的计算(假设1%的窗口长度偏移)。这确实需要实现您自己的在线偏度函数,而不是使用MATLAB的内置函数。