Je pense avoir trouvé la solution. Il est basé sur cet article sur how to calculate covariance manually et celui-ci sur calculating running variance. Et puis j'ai adapté l'algorithme dans ce dernier pour calculer la covariance au lieu de la variance, étant donné ma compréhension du premier article.
public class CovarianceMatrix
{
private int _n;
private Vector _oldMean, _newMean,
_oldVarianceSum, _newVarianceSum,
_oldCovarianceSum, _newCovarianceSum;
public void Push(Vector x)
{
_n++;
if (_n == 1)
{
_oldMean = _newMean = x;
_oldVarianceSum = new Vector(0, 0, 0);
_oldCovarianceSum = new Vector(0, 0, 0);
}
else
{
//_newM = _oldM + (x - _oldM)/_n;
_newMean = new Vector(
_oldMean.X + (x.X - _oldMean.X)/_n,
_oldMean.Y + (x.Y - _oldMean.Y)/_n,
_oldMean.Z + (x.Z - _oldMean.Z)/_n);
//_newS = _oldS + (x - _oldM) * (x - _newM);
_newVarianceSum = new Vector(
_oldVarianceSum.X + (x.X - _oldMean.X) * (x.X - _newMean.X),
_oldVarianceSum.Y + (x.Y - _oldMean.Y) * (x.Y - _newMean.Y),
_oldVarianceSum.Z + (x.Z - _oldMean.Z) * (x.Z - _newMean.Z));
/* .X is X vs Y
* .Y is Y vs Z
* .Z is Z vs X
*/
_newCovarianceSum = new Vector(
_oldCovarianceSum.X + (x.X - _oldMean.X) * (x.Y - _newMean.Y),
_oldCovarianceSum.Y + (x.Y - _oldMean.Y) * (x.Z - _newMean.Z),
_oldCovarianceSum.Z + (x.Z - _oldMean.Z) * (x.X - _newMean.X));
// set up for next iteration
_oldMean = _newMean;
_oldVarianceSum = _newVarianceSum;
}
}
public int NumDataValues()
{
return _n;
}
public Vector Mean()
{
return (_n > 0) ? _newMean : new Vector(0, 0, 0);
}
public Vector Variance()
{
return _n <= 1 ? new Vector(0, 0, 0) : _newVarianceSum.DivideBy(_n - 1);
}
}
Oui, ça fonctionne! Si vous voulez déplacer votre fenêtre et supprimer les valeurs en quittant la fenêtre actuelle, vous devez simplement soustraire de l'ancienne somme de covariance, par ex. pour x, vous devez d'abord calculer "oldMean" comme tempMean.X = ((oldMean.x * n) - x)/(n-1), puis mettre à jour la somme de covariance avec oldCov.x - = (y - oldMean.y) * (x - tempMean.x) puis mettez à jour votre ancienMean vers tempMean. – optional