using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Optimization; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Data; using HeuristicLab.Common.Resources; namespace HeuristicLab.Analysis.FitnessLandscape { [Item("Evolvability Aggregator", "Aggregates evolvability values into an evolvability portrait.")] [StorableClass] public class EvolvabilityAggregator : NamedItem, IAggregator { #region Fields [Storable] private List E_a; [Storable] private List E_b; [Storable] private List E_c; [Storable] private List E_d; [Storable] private List baseQualities; [Storable] private List expectedAbsoluteQualityDeltas; [Storable] private List expectedRelativeQualityDeltas; #endregion #region Properties public static new Image StaticItemImage { get { return VSImageLibrary.Database; } } public override bool CanChangeName { get { return false; } } #endregion #region Construction and Cloning [StorableConstructor] protected EvolvabilityAggregator(bool deserializing) : base(deserializing) { } protected EvolvabilityAggregator(EvolvabilityAggregator original, Cloner cloner) : base(original, cloner) { E_a = original.E_a.ToList(); E_b = original.E_b.ToList(); E_c = original.E_c.ToList(); E_d = original.E_d.ToList(); baseQualities = original.baseQualities.ToList(); expectedAbsoluteQualityDeltas = original.expectedAbsoluteQualityDeltas.ToList(); expectedRelativeQualityDeltas = original.expectedRelativeQualityDeltas.ToList(); } public EvolvabilityAggregator() { name = ItemName; description = ItemDescription; E_a = new List(); E_b = new List(); E_c = new List(); E_d = new List(); baseQualities = new List(); expectedAbsoluteQualityDeltas = new List(); expectedRelativeQualityDeltas = new List(); } public override IDeepCloneable Clone(Cloner cloner) { return new EvolvabilityAggregator(this, cloner); } #endregion #region IAggregator Members public void MaybeAddResult(IResult result) { if (result.DataType == typeof(DoubleValue)) { double value = ((DoubleValue)result.Value).Value; switch (result.Name) { case "E_a": E_a.Add(value); break; case "E_b": E_b.Add(value); break; case "E_c": E_c.Add(value); break; case "E_d": E_d.Add(value); break; case "Base Quality": baseQualities.Add(value); break; case "Expected Absolute Quality Delta": expectedAbsoluteQualityDeltas.Add(value); break; case "Expected Relative Quality Delta": expectedRelativeQualityDeltas.Add(value); break; } } } public void Reset() { E_a.Clear(); E_b.Clear(); E_c.Clear(); E_d.Clear(); baseQualities.Clear(); expectedAbsoluteQualityDeltas.Clear(); expectedRelativeQualityDeltas.Clear(); } private class PortraitEntry { public readonly double A, B, C, D, Q, AbsQDelta, RelQDelta; public PortraitEntry(double a, double b, double c, double d, double q, double absQDelta, double relQDelta) { A = a; B = b; C = c; D = d; Q = q; AbsQDelta = absQDelta; RelQDelta = relQDelta; } } public IResult CreateResult() { var portrait = new DataTable("Evolvability Portrait"); var E_a_row = new DataRow("E_a", "probability of non-deleterious mutation") {VisualProperties = {SecondYAxis = true}}; var E_b_row = new DataRow("E_b", "average expected offspring fitness"); var E_c_row = new DataRow("E_c", "90th percentile offspring fitness"); var E_d_row = new DataRow("E_d", "10th percentile offspring fitness"); var baseQualityRow = new DataRow("Q", "Base quality"); var absQDelta = new DataRow("abs Q delta", "expected absolute quality delta"); var relQDelta = new DataRow("rel Q delta", "expected relatve quality delta") {VisualProperties = {SecondYAxis = true}}; var entries = E_a.Select((t, i) => new PortraitEntry(t, E_b[i], E_c[i], E_d[i], baseQualities[i], expectedAbsoluteQualityDeltas[i], expectedRelativeQualityDeltas[i])) .ToList(); Action> addBinAverages = b => { if (b.Count > 0) { E_a_row.Values.Add(b.Average(e => e.A)); E_b_row.Values.Add(b.Average(e => e.B)); E_c_row.Values.Add(b.Average(e => e.C)); E_d_row.Values.Add(b.Average(e => e.D)); baseQualityRow.Values.Add(b.Average(e => e.Q)); absQDelta.Values.Add(b.Average(e => e.AbsQDelta)); relQDelta.Values.Add(b.Average(e => e.RelQDelta)); } }; var a = new DistributionAnalyzer(baseQualities); addBinAverages(entries.Where(e => e.Q <= a[0.1]).ToList()); for (double t = 0.1; t < 1; t += 0.1) addBinAverages(entries.Where(e => a[t] < e.Q && e.Q <= a[t+0.1]).ToList()); portrait.Rows.Add(E_a_row); portrait.Rows.Add(E_b_row); portrait.Rows.Add(E_c_row); portrait.Rows.Add(E_d_row); portrait.Rows.Add(baseQualityRow); portrait.Rows.Add(absQDelta); portrait.Rows.Add(relQDelta); return new Result("Evolvability Portrait", portrait); } #endregion } }