我正试图从布朗利斯& amp; Gallo 2006(如果您可能感兴趣的话)。
代码工作正常,但考虑到我正在处理非常长的向量(最大的有20米的观测值,20小时之后它没有完成计算)我想知道如何加快它。
到目前为止,我所做的是:
我将时间和日期格式更改为数字双,我看到它在处理和大量内存中节省了相当多的时间。
我为矢量分配了内存:
[n] = size(price);
x = price;
score = nan(n,'double'); %using tic and toc I saw that nan requires less time than zeros
trimmed_mean = nan(n,'double');
sd = nan(n,'double');
out_mat = nan(n,'double');
这是我想删除的循环。我读到矢量化会加速很多,特别是使用长矢量。
for i = k+1:n
trimmed_mean(i) = trimmean(x(i-k:i-1 & i+1:i+k),10,'round'); %trimmed mean computed on the 'k' closest observations to 'i' (i is excluded)
score(i) = x(i) - trimmed_mean(i);
sd(i) = std(x(i-k:i-1 & i+1:i+k)); %same as the mean
tmp = abs(score(i)) > (alpha .* sd(i) + gamma);
out_mat(i) = tmp*1;
end
这是我想要做的事情
trimmed_mean=trimmean(regroup_matrix,10,'round',2);
score=bsxfun(@minus,x,trimmed_mean);
sd=std(regroup_matrix,2);
temp = abs(score) > (alpha .* sd + gamma);
out_mat = temp*1;
但鉴于我对Matlab完全不熟悉,我不知道如何正确构建相邻观测的矩阵。我认为它的形状应该是:regroup_matrix= nan (n,2*k)
。
编辑:具体而言,我想做的事情(我无法做到)是:
给定“x”中的每个观察“i”的列向量“x”(n,1),我想将“k”相邻观察值变为“i”(从ik到i-1,从i + 1到i) + k)并将这些观察结果作为矩阵的行(n,2 * k)。
我现在要做的是:
[n] = size(price,1);
x = price;
[j1]=find(x);
matrix_left=zeros(n, k,'double');
matrix_right=zeros(n, k,'double');
toc
matrix_left(j1(k+1:end),:)=x(j1-k:j1-1);
matrix_right(j1(1:end-k),:)=x(j1+1:j1+k);
matrix_group=[matrix_left matrix_right];
trimmed_mean=trimmean(matrix_group,10,'round',2);
score=bsxfun(@minus,x,trimmed_mean);
sd=std(matrix_group,2);
temp = abs(score) > (alpha .* sd + gamma);
outmat = temp*1;
我在创建matrix_left和matrix_right时遇到问题。 j1,我用于索引是一个列向量,其中包含价格观察的指数。输出只是
j1=[1:1:n]
price是double的列向量,大小为(n,1)
答案 0 :(得分:2)
对于您的重塑,您可以执行以下操作:
idxArray = bsxfun(@plus,(k:n)',[-k:-1,1:k]);
reshapedArray = x(idxArray);
答案 1 :(得分:0)
感谢Jonas告诉我要走的路,我想出了这个:
idxArray_left=bsxfun(@plus,(k+1:n)',[-k:-1]); %matrix with index of left neighbours observations
idxArray_fill_left=bsxfun(@plus,(1:k)',[1:k]); %for observations from 1:k I take the right neighbouring observations, this way when computing mean and standard deviations there will be no problems.
matrix_left=[idxArray_fill_left; idxArray_left]; %Just join the two matrices and I have the complete matrix of left neighbours
idxArray_right=bsxfun(@plus,(1:n-k)',[1:k]); %same thing as left but opposite.
idxArray_fill_right=bsxfun(@plus,(n-k+1:n)',[-k:-1]);
matrix_right=[idxArray_right; idxArray_fill_right];
idx_matrix=[matrix_left matrix_right]; %complete index matrix, joining left and right indices
neigh_matrix=x(idx_matrix); %exactly as proposed by Jonas, I fill up a matrix of observations from 'x', following idx_matrix indexing
trimmed_mean=trimmean(neigh_matrix,10,'round',2);
score=bsxfun(@minus,x,trimmed_mean);
sd=std(neigh_matrix,2);
temp = abs(score) > (alpha .* sd + gamma);
outmat = temp*1;
再次,非常感谢Jonas。你真的很开心!
还要感谢所有关注这个问题并试图提供帮助的人!