【问题标题】:Which function allow me to calculate cumulative variance over a vector?哪个函数允许我计算向量的累积方差?
【发布时间】:2020-02-09 02:31:23
【问题描述】:

我需要计算一个向量的累积方差。我尝试构建和编写脚本,但是这个脚本需要太多时间来计算我的大小为 1*100000 的向量的累积方差。你知道是否有更快的方法来找到这个累积方差?

这是我正在使用的代码

%%Creation of the rand vectors. ans calculation of the variances

d=100000; %dimension of the vectors
nv=6 %quantity of vectors
for j=1:nv;
VItimeseries(:,j)=rand(d,1); % Final matrix with vectors
end

%% script to calculate the cumulative variance in the columns of my matrix
VectorVarianza=0;
VectoFinalVar=0;
VectorFinalTotalVAriances=zeros(d,nv);
    for k=1:nv %number of columns
    for j=1:numel(VItimeseries(:,k)) %size of the rows
        Vector=VItimeseries(:,k);       
        VectorVarianza(1:j)= Vector(1:j); % Vector to calculate the variance...
        ...Independently
        VectorFinalVar(j,k)= var(VectorVarianza);%Calculation of variances

    end
    VectorFinalTotalVAriances(:,k)=VectorFinalVar(:,k)% construction of the...
    ...Final Vector with the cumulative variances
end

【问题讨论】:

  • VectorFinalVar(j,k)= 很昂贵,因为数组没有预先分配。为什么不直接写到VectorFinalTotalVAriancesVector=VItimeseries(:,k); 应该从 j 的循环中移出,这是不必要的重复。这些更改将大大加快代码速度。但最后你使用的是 O(n^2) 算法,其中 O(n) 是可能的:不要在每个子数组上使用 var,而是在移动时累积 sum(x) 和 sum(x^2)通过数组,然后使用它们来计算方差。您可以使用cumsum 来计算没有显式循环的那些。
  • @CrisLuengo 你是绝对正确的。我想知道,Matlab 没有这个计算方差的命令。我正在尝试使用命令 movvar(A, 100000) 检查,其中 100000 是计算方差的滑动窗口。但它没有给我预期的结果。:)

标签: matlab for-loop variance cumulative-sum


【解决方案1】:

循环遍历xn 元素,并在循环内使用var(x(1:i)) 计算直到i 的所有元素的方差等于算法 O(n2) .这本身就是昂贵的。

样本方差(var 计算的内容)定义为sum((x-mean(x)).^2) / (n-1),与n = length(x)。这可以是 rewritten(sum(x.^2) - sum(x).^2 / n) / (n-1)。这个公式允许我们在一个循环中累积sum(x)sum(x.^2),然后再计算方差。它还允许我们计算 O(n) 中的累积方差。

对于向量x,我们有以下循环:

x = randn(100,1); % some data

v = zeros(size(x)); % cumulative variance
s = x(1);           % running sum of x
s2 = x(1).^2;       % running sum of square of x
for ii = 2:numel(x) % loop starts at 2, for ii=1 we cannot compute variance
   s = s + x(ii);
   s2 = s2 + x(ii).^2;
   v(ii) = (s2 - s.^2 / ii) / (ii-1);
end

我们可以通过使用cumsum来避免显式循环:

s = cumsum(x);
s2 = cumsum(x.^2);
n = (1:numel(x)).';
v = (s2 - s.^2 ./ n) ./ (n-1); % v(1) will be NaN, rather than 0 as in the first version
v(1) = 0;                      % so we set it to 0 explicitly here

OP 中的代码计算矩阵每一列的累积方差。上面的代码可以很容易地做同样的事情:

s = cumsum(VItimeseries,1);     % cumulative sum explicitly along columns
s2 = cumsum(VItimeseries.^2,1);
n = (1:size(VItimeseries,1)).'; % use number of rows, rather than `numel`.
v = (s2 - s.^2 ./ n) ./ (n-1);
v(1,:) = 0;                     % fill first row with zeros, not just first element

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多