Free cookie consent management tool by TermsFeed Policy Generator

source: branches/FitnessLandscapeAnalysis/HeuristicLab.Analysis.FitnessLandscape/Analysis/InformationAnalysis.cs @ 8694

Last change on this file since 8694 was 7128, checked in by epitzer, 13 years ago

#1696 Integrate fitness landscape analysis plugins from Heureka! repository.

File size: 5.0 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5namespace HeuristicLab.Analysis.FitnessLandscape.Analysis {
6
7  public class InformationAnalysis {
8
9    public class Peak {
10      public double QualityDelta { get; private set; }
11      public double Value { get; private set; }
12      public Peak(double qualityDelta, double value) {
13        QualityDelta = qualityDelta;
14        Value = value;
15      }
16    }
17
18    public List<double> InformationContent { get; private set; }
19    public List<double> PartialInformationContent { get; private set; }
20    public List<double> DensityBasinInformation { get; private set; }
21    public List<double> QualityDelta { get; private set; }
22    public double InformationStability { get; private set; }
23    public int Regularity { get; private set; }
24    public Peak PeakInformationContent { get; private set; }
25    public Peak PeakPartialInformationContent { get; private set; }
26    public Peak PeakDensityBasinInformation { get; private set; }
27
28    public InformationAnalysis(IEnumerable<double> qualities, int nQuantiles) {
29      InformationContent = new List<double>();
30      PartialInformationContent = new List<double>();
31      DensityBasinInformation = new List<double>();
32      QualityDelta = new List<double>();
33      PerformAnalysis(qualities, nQuantiles);
34    }
35
36    private void PerformAnalysis(IEnumerable<double> qualities, int nQuantiles) {
37      var differences = Differences(qualities).ToList();
38      InformationStability = differences.Select(d => Math.Abs(d)).Max();
39      Regularity = new HashSet<double>(differences).Count;
40      var thresholds = UniqueThresholdCalculator.DetermineThresholds(differences, nQuantiles).ToList();
41      foreach (var eps in thresholds) {
42        var shapes = Shapes(eps, differences).ToList();
43        int[] shape_counts = CountShapes(shapes);
44        QualityDelta.Add(eps);
45        InformationContent.Add(CalculateInformationContent(shape_counts, shapes.Count));
46        PartialInformationContent.Add(CalculatePartialInformationContent(eps, differences));
47        DensityBasinInformation.Add(CalculateDensityBasinInformation(shape_counts, shapes.Count));
48      }
49      PeakDensityBasinInformation = GetPeak(QualityDelta, InformationContent);
50      PeakPartialInformationContent = GetPeak(QualityDelta, PartialInformationContent);
51      PeakDensityBasinInformation = GetPeak(QualityDelta, DensityBasinInformation);
52    }
53
54    public static Peak GetPeak(IEnumerable<double> indexes, IEnumerable<double> values) {
55      var max = indexes.Zip(values, (i, v) => new { i, v }).OrderByDescending(p => p.v).First();
56      return new Peak(max.i, max.v);
57    }
58
59    public enum Shape {
60      DecDec = -4,
61      EquDec = -3,
62      IncDec = -2,
63      DecEqu = -1,
64      EquEqu = 0,
65      IncEqu = 1,
66      DecInc = 2,
67      EquInc = 3,
68      IncInc = 4
69    }
70
71    private static IEnumerable<Shape> Shapes(double eps, IEnumerable<double> differences) {
72      return Utils.Delta(differences, (x, y) =>
73        (Shape)
74          ((x >= eps ? 1 : (x <= -eps ? -1 : 0)) +
75           (y >= eps ? 3 : (y <= -eps ? -3 : 0))));
76    }
77
78    private static double CalculateInformationContent(int[] shape_counts, int total_n_shapes) {
79      return
80        -Entropy(shape_counts[(int)Shape.EquDec + 4], total_n_shapes, 6)
81        - Entropy(shape_counts[(int)Shape.IncDec + 4], total_n_shapes, 6)
82        - Entropy(shape_counts[(int)Shape.DecEqu + 4], total_n_shapes, 6)
83        - Entropy(shape_counts[(int)Shape.IncEqu + 4], total_n_shapes, 6)
84        - Entropy(shape_counts[(int)Shape.DecInc + 4], total_n_shapes, 6)
85        - Entropy(shape_counts[(int)Shape.EquInc + 4], total_n_shapes, 6);
86    }
87
88    private static double CalculateDensityBasinInformation(int[] shape_counts, int total_n_shapes) {
89      return
90        -Entropy(shape_counts[(int)Shape.DecDec + 4], total_n_shapes, 3)
91        - Entropy(shape_counts[(int)Shape.EquEqu + 4], total_n_shapes, 3)
92        - Entropy(shape_counts[(int)Shape.IncInc + 4], total_n_shapes, 3);
93    }
94
95    private static double CalculatePartialInformationContent(double eps, List<double> differences) {
96      int slope = 0;
97      int nPeaks = 0;
98      foreach (var d in differences) {
99        if (d >= eps) {
100          if (slope < 0) nPeaks++;
101          slope = +1;
102        } else if (d <= -eps) {
103          if (slope > 0) nPeaks++;
104          slope = -1;
105        }
106      }
107      return 1.0 * nPeaks / differences.Count;
108    }
109
110    private static int[] CountShapes(IEnumerable<Shape> shapes) {
111      int[] shape_counts = new int[9];
112      foreach (var s in shapes) {
113        shape_counts[(int)s + 4]++;
114      }
115      return shape_counts;
116    }
117
118    private static double Entropy(int count, int total, int n_cases) {
119      if (count == 0)
120        return 0;
121      double freq = 1.0 * count / total;
122      return freq * Math.Log(freq, n_cases);
123    }
124
125    private static IEnumerable<double> Differences(IEnumerable<double> values) {
126      return Utils.Delta(values, (x, y) => y - x);
127    }
128
129  }
130}
Note: See TracBrowser for help on using the repository browser.