哪个函数允许我计算向量的累积方差?

Which function allow me to calculate cumulative variance over a vector?

我需要计算向量的累积方差。我已尝试构建和编写脚本,但此脚本需要花费太多时间来计算大小为 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

循环 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