Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis.MultiVariate/3.3/Evaluators/OnlineMeanMahalanobisDistanceEvaluator.cs @ 4695

Last change on this file since 4695 was 4555, checked in by gkronber, 14 years ago

Improved time series evaluators. #1142

File size: 4.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Core;
6using HeuristicLab.Data;
7using HeuristicLab.Problems.DataAnalysis.Evaluators;
8using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
9using HeuristicLab.Parameters;
10
11namespace HeuristicLab.Problems.DataAnalysis.MultiVariate.Evaluators {
12  public class OnlineMeanMahalanobisDistanceEvaluator : IMultiVariateOnlineEvaluator {
13    private int n;
14    private double distance;
15    private double[,] covMatrix;
16    private double[] diff;
17    private double[] target;
18    public double MeanMahalanobisDistance {
19      get {
20        if (n == 0) throw new InvalidOperationException("no elements");
21        else
22          return Math.Sqrt(distance) / n;
23      }
24    }
25
26    public double MeanGeneralizedSquaredInterpointDistance {
27      get {
28        if (n == 0) throw new InvalidOperationException("no elements");
29        else
30          return distance / n;
31      }
32    }
33
34    public OnlineMeanMahalanobisDistanceEvaluator() {
35      Reset();
36    }
37
38    #region IMultiVariateOnlineEvaluator Members
39    public double Value {
40      get { return MeanMahalanobisDistance; }
41    }
42
43    public void Add(IEnumerable<double> original, IEnumerable<double> estimated) {
44      if (covMatrix == null) throw new InvalidOperationException("Covariance matrix must be initialized before values can be added.");
45
46      {
47        // calculate difference vector
48        var originalEnumerator = original.GetEnumerator();
49        var estimatedEnumerator = estimated.GetEnumerator();
50        int i = 0;
51        while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext() && i < diff.Length) {
52          diff[i++] = originalEnumerator.Current - estimatedEnumerator.Current;
53        }
54        if (originalEnumerator.MoveNext() | estimatedEnumerator.MoveNext() || i < diff.Length) {
55          throw new ArgumentException("Number of elements of original and estimated doesn't match or is not compatible with covariance matrix.");
56        }
57      }
58
59      {
60        // calculate mahalanobis distance using covariance matrix
61        // covMatrix^(-1) * diff => target
62        alglib.ablas.rmatrixmv(covMatrix.GetLength(0), covMatrix.GetLength(1), ref covMatrix, 0, 0, 0, ref diff, 0, ref target, 0);
63
64        // diff^T * (covMatrix^(-1) * diff) => sum
65        double sum = 0.0;
66        for (int i = 0; i < diff.Length; i++) {
67          sum += diff[i] * target[i];
68        }
69        distance += sum;
70        n++;
71      }
72    }
73
74    public void Reset() {
75      n = 0;
76      distance = 0.0;
77      covMatrix = null;
78      diff = null;
79      target = null;
80    }
81
82    #endregion
83
84    public void InitializeCovarianceMatrixFromSamples(params IEnumerable<double>[] samples) {
85      covMatrix = new double[samples.Length, samples.Length];
86      OnlineCovarianceEvaluator covEvaluator = new OnlineCovarianceEvaluator();
87      for (int i = 0; i < samples.Length; i++) {
88        for (int j = i; j < samples.Length; j++) {
89          var xEnumerator = samples[i].GetEnumerator();
90          var yEnumerator = samples[j].GetEnumerator();
91          covEvaluator.Reset();
92          while (xEnumerator.MoveNext() & yEnumerator.MoveNext()) {
93            covEvaluator.Add(xEnumerator.Current, yEnumerator.Current);
94          }
95          if (xEnumerator.MoveNext() | yEnumerator.MoveNext()) {
96            throw new ArgumentException("Number of elements must be the same in all enumerations.");
97          }
98          covMatrix[i, j] = covEvaluator.Covariance;
99          covMatrix[j, i] = covEvaluator.Covariance;
100        }
101      }
102      int info = 0;
103      alglib.matinv.matinvreport report = new alglib.matinv.matinvreport();
104      alglib.matinv.rmatrixinverse(ref covMatrix, covMatrix.GetLength(0), ref info, ref report);
105      if (info != 1) throw new InvalidOperationException("Can't invert covariance matrix.");
106      diff = new double[samples.Length];
107      target = new double[samples.Length];
108    }
109  }
110}
Note: See TracBrowser for help on using the repository browser.