Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 10764 was 5275, checked in by gkronber, 14 years ago

Merged changes from trunk to data analysis exploration branch and added fractional distance metric evaluator. #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), covMatrix, 0, 0, 0, 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, 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.