Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
03/24/16 14:03:06 (8 years ago)
Author:
bburlacu
Message:

#2288: Added directed graph chart and layout class for the visualization of knowledge network graphs. Added RunCollectionVariableInteractionNetworkView and removed the old view.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.cs

    r13726 r13727  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2525using System.Drawing;
    2626using System.Linq;
     27using System.Text;
    2728using System.Windows.Forms;
    2829using HeuristicLab.Common;
     30using HeuristicLab.Core;
     31using HeuristicLab.Core.Views;
    2932using HeuristicLab.Data;
    3033using HeuristicLab.MainForm;
    31 using HeuristicLab.MainForm.WindowsForms;
    3234using HeuristicLab.Optimization;
    3335using HeuristicLab.Problems.DataAnalysis;
    34 using HeuristicLab.Problems.DataAnalysis.Symbolic;
    35 using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    36 using System.Collections;
    37 
    38 namespace HeuristicLab.VariableInteractionNetworks.Views
    39 {
    40     [View("Variable Interaction Network")]
    41     [Content(typeof(RunCollection), IsDefaultView = false)]
    42 
    43     public sealed partial class VariableInteractionNetworkView : AsynchronousContentView
    44     {
    45         private const string variableImpactResultName = "Variable impacts";
    46         private const string TrainingBestSolutionParameterName = "Best training solution";
    47 
    48         public new RunCollection Content
    49         {
    50             get { return (RunCollection)base.Content; }
    51             set { base.Content = value; }
    52         }
    53 
    54         public VariableInteractionNetworkView()
    55         {
    56             InitializeComponent();
    57         }
    58 
    59         internal class NoFocusTrackBar : System.Windows.Forms.TrackBar
    60         {
    61             [System.Runtime.InteropServices.DllImport("user32.dll")]
    62             public extern static int SendMessage(IntPtr hWnd, uint msg, int wParam, int lParam);
    63 
    64             private static int MakeParam(int loWord, int hiWord)
    65             {
    66                 return (hiWord << 16) | (loWord & 0xffff);
     36using HeuristicLab.Visualization;
     37using Rectangle = HeuristicLab.Visualization.Rectangle;
     38
     39namespace HeuristicLab.VariableInteractionNetworks.Views {
     40  [View("Variable Interaction Network")]
     41  [Content(typeof(RunCollection), IsDefaultView = false)]
     42
     43  public sealed partial class RunCollectionVariableInteractionNetworkView : ItemView {
     44    public RunCollectionVariableInteractionNetworkView() {
     45      InitializeComponent();
     46      ConfigureNodeShapes();
     47    }
     48
     49    public new RunCollection Content {
     50      get { return (RunCollection)base.Content; }
     51      set {
     52        if (value != null && value != Content) {
     53          base.Content = value;
     54        }
     55      }
     56    }
     57
     58    private static VariableInteractionNetwork BuildNetworkFromSolutionQualities(RunCollection runs, double threshold, bool useBestRunsPerTarget = false) {
     59      var nodes = new Dictionary<string, IVertex>();
     60      var vn = new VariableInteractionNetwork();
     61      var targets = runs.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
     62      var targetQualities = new Dictionary<string, double>();
     63      var targetInputs = new Dictionary<string, List<string>>();
     64
     65      if (useBestRunsPerTarget) {
     66        foreach (var target in targets) {
     67          var bestRun = target.OrderBy(x => ((DoubleValue)x.Results["Best training solution quality"]).Value).First();
     68          var bestQuality = ((DoubleValue)bestRun.Results["Best training solution quality"]).Value;
     69          var pd = (IRegressionProblemData)bestRun.Parameters["ProblemData"];
     70          if (threshold > bestQuality) continue; // skip if quality is below the treshold
     71          targetQualities[target.Key] = bestQuality;
     72          targetInputs[target.Key] = pd.AllowedInputVariables.ToList();
     73        }
     74      } else {
     75        foreach (var target in targets) {
     76          var avgQuality = CalculateAverageQuality(new RunCollection(target));
     77          if (threshold > avgQuality) continue;
     78          targetQualities[target.Key] = avgQuality;
     79          var pd = (IRegressionProblemData)target.First().Parameters["ProblemData"];
     80          targetInputs[target.Key] = pd.AllowedInputVariables.ToList();
     81        }
     82      }
     83
     84      foreach (var ti in targetQualities) {
     85        var target = ti.Key;
     86        var variables = targetInputs[ti.Key];
     87        var quality = ti.Value;
     88        IVertex targetNode;
     89
     90        if (!nodes.TryGetValue(target, out targetNode)) {
     91          targetNode = new VariableNetworkNode { Label = target };
     92          vn.AddVertex(targetNode);
     93          nodes[target] = targetNode;
     94        }
     95
     96        IVertex variableNode;
     97        if (variables.Count > 0) {
     98          var variableList = new List<string>(variables);
     99          variableList.Add(target);
     100          var junctionLabel = Concatenate(variableList);
     101          IVertex junctionNode;
     102          if (!nodes.TryGetValue(junctionLabel, out junctionNode)) {
     103            junctionNode = new JunctionNetworkNode { Label = string.Empty };
     104            vn.AddVertex(junctionNode);
     105            nodes[junctionLabel] = junctionNode;
     106          }
     107          IArc arc;
     108          foreach (var v in variables) {
     109            var impact = quality;
     110            if (!nodes.TryGetValue(v, out variableNode)) {
     111              variableNode = new VariableNetworkNode { Label = v };
     112              vn.AddVertex(variableNode);
     113              nodes[v] = variableNode;
    67114            }
    68 
    69             protected override void OnGotFocus(EventArgs e)
    70             {
    71                 base.OnGotFocus(e);
    72                 SendMessage(this.Handle, 0x0128, MakeParam(1, 0x1), 0);
     115            arc = new Arc(variableNode, junctionNode) { Weight = impact };
     116            vn.AddArc(arc);
     117          }
     118          arc = new Arc(junctionNode, targetNode) { Weight = junctionNode.InArcs.Sum(x => x.Weight) };
     119          vn.AddArc(arc);
     120        } else {
     121          foreach (var v in variables) {
     122            var impact = quality;
     123            if (!nodes.TryGetValue(v, out variableNode)) {
     124              variableNode = new VariableNetworkNode { Label = v };
     125              vn.AddVertex(variableNode);
     126              nodes[v] = variableNode;
    73127            }
    74         }
    75 
    76         #region events
    77 
    78         //  #region Event Handlers (Content)
    79         protected override void OnContentChanged()
    80         {
    81             base.OnContentChanged();
    82             if (Content == null)
    83             {
    84                 // TODO: Add code when content has been changed and is null
     128            var arc = new Arc(variableNode, targetNode) { Weight = impact };
     129            vn.AddArc(arc);
     130          }
     131        }
     132      }
     133
     134      return vn;
     135    }
     136
     137    private static VariableInteractionNetwork BuildNetworkFromVariableImpacts(RunCollection runs, string qualityResultName, bool maximization, string impactsResultName, double threshold, bool useBestRunsPerTarget = false) {
     138      var nodes = new Dictionary<string, IVertex>();
     139      var vn = new VariableInteractionNetwork();
     140      var targets = runs.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
     141
     142      var targetImpacts = new Dictionary<string, Dictionary<string, double>>();
     143
     144      if (useBestRunsPerTarget) {
     145        var bestRunsPerTarget = maximization ?
     146          targets.Select(x => x.OrderBy(y => ((DoubleValue)y.Results[qualityResultName]).Value).Last()) :
     147          targets.Select(x => x.OrderBy(y => ((DoubleValue)y.Results[qualityResultName]).Value).First());
     148
     149        foreach (var run in bestRunsPerTarget) {
     150          var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
     151          var target = pd.TargetVariable;
     152          var impacts = (DoubleMatrix)run.Results[impactsResultName];
     153          targetImpacts[target] = impacts.RowNames.Select((x, i) => new { Name = x, Index = i }).ToDictionary(x => x.Name, x => impacts[x.Index, 0]);
     154        }
     155      } else {
     156        foreach (var target in targets) {
     157          var averageImpacts = CalculateAverageImpacts(new RunCollection(target), impactsResultName);
     158          targetImpacts[target.Key] = averageImpacts;
     159        }
     160      }
     161
     162      foreach (var ti in targetImpacts) {
     163        var target = ti.Key;
     164        var variableImpacts = ti.Value;
     165        IVertex targetNode;
     166
     167        var variables = variableImpacts.Keys.Where(x => variableImpacts[x] >= threshold).ToList();
     168        if (variables.Count == 0) continue;
     169
     170        if (!nodes.TryGetValue(target, out targetNode)) {
     171          targetNode = new VariableNetworkNode { Label = target };
     172          vn.AddVertex(targetNode);
     173          nodes[target] = targetNode;
     174        }
     175
     176        IVertex variableNode;
     177        if (variables.Count > 1) {
     178          var variableList = new List<string>(variables) { target };
     179          var junctionLabel = Concatenate(variableList);
     180          IVertex junctionNode;
     181          if (!nodes.TryGetValue(junctionLabel, out junctionNode)) {
     182            junctionNode = new JunctionNetworkNode { Label = string.Empty };
     183            vn.AddVertex(junctionNode);
     184            nodes[junctionLabel] = junctionNode;
     185          }
     186          IArc arc;
     187          foreach (var v in variables) {
     188            var impact = variableImpacts[v];
     189            if (!nodes.TryGetValue(v, out variableNode)) {
     190              variableNode = new VariableNetworkNode { Label = v };
     191              vn.AddVertex(variableNode);
     192              nodes[v] = variableNode;
    85193            }
    86             else
    87             {
    88                 // TODO: Add code when content has been changed and is not null
    89                 viewHost2.Content = CalculateNodeImportance(CalculateAdjacencyMatrix());
    90                 var adjMatrix = CalculateAdjacencyMatrix();
    91                 viewHost1.Content = adjMatrix;
    92                 viewHost3.Content = (DoubleMatrix)adjMatrix.Clone();
    93                 trackBar1.Minimum = (int)(1000 * GetMinNonNullElement(adjMatrix));
    94                 trackBar1.Maximum = (int)(1000 * (adjMatrix.Max()));
     194            arc = new Arc(variableNode, junctionNode) { Weight = impact };
     195            vn.AddArc(arc);
     196          }
     197          arc = new Arc(junctionNode, targetNode) { Weight = junctionNode.InArcs.Sum(x => x.Weight) };
     198          vn.AddArc(arc);
     199        } else {
     200          foreach (var v in variables) {
     201            var impact = variableImpacts[v];
     202            if (!nodes.TryGetValue(v, out variableNode)) {
     203              variableNode = new VariableNetworkNode { Label = v };
     204              vn.AddVertex(variableNode);
     205              nodes[v] = variableNode;
    95206            }
    96         }
    97         #endregion
    98 
    99         protected override void SetEnabledStateOfControls()
    100         {
    101             base.SetEnabledStateOfControls();
    102             // TODO: Enable or disable controls based on whether the content is null or the view is set readonly
    103         }
    104 
    105         #region Event Handlers (child controls)
    106         // TODO: Put event handlers of child controls here.
    107         #endregion
    108 
    109         private DoubleMatrix CalculateAdjacencyMatrix()
    110         {
    111             var runCollection = Content;
    112             var inputVariables = ((IRegressionProblemData)runCollection.First().Parameters["ProblemData"]).InputVariables.Select(x => x.Value).ToList();
    113             var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).OrderBy(x => inputVariables.IndexOf(x.Key)).ToList();
    114 
    115             var allVariableImpacts = runCollection.Select(run => (DoubleMatrix)run.Results[variableImpactResultName]);
    116             var variableNames = (from variableImpact in allVariableImpacts
    117                                  from variableName in variableImpact.RowNames
    118                                  select variableName).Distinct().ToArray();
    119            
    120             var vars = new List<Tuple<int, string>>();
    121            
    122             var allowedInputs = ((IRegressionProblemData)groupRunCollection[0].First().Parameters["ProblemData"]).AllowedInputVariables.ToList();
    123 
    124             var adjMatrix = new DoubleMatrix(variableNames.Length, variableNames.Length);
    125 
    126             for (int i = 0; i < adjMatrix.Rows; ++i)
    127             {
    128                 int inputIndex = allowedInputs.FindIndex(x => x == variableNames[i]);
    129                 vars.Add(new Tuple<int, string>(inputIndex, variableNames[i]));
    130             }
    131 
    132             vars.Sort((a, b) => a.Item1.CompareTo(b.Item1));
    133 
    134             for (int i = 0; i < adjMatrix.Rows; ++i)
    135             {
    136                 variableNames[i] = vars[i].Item2;
    137             }
    138             adjMatrix.RowNames = variableNames;
    139             adjMatrix.ColumnNames = adjMatrix.RowNames;
    140 
    141             for (int j = 0; j < groupRunCollection.Count; ++j)
    142             {
    143                 var g = groupRunCollection[j];
    144                
    145                 var matrix = CalculateAdjacencyRows(g);
    146                 var variables = new List<double>();
    147 
    148                 for (int i = 0; i < matrix.Columns; ++i)
    149                 {
    150                     variables.Add(matrix[0, i]);
    151                 }
    152                
    153                 for (int i = 0; i < variables.Count; ++i)
    154                 {
    155                     if (i == j)
    156                     {
    157                         adjMatrix[i, i] = 0;
    158                         variables.Insert(i, 0);
    159                     }
    160                     else
    161                         adjMatrix[j, i] = variables[i];
    162                 }
    163             }
    164             return adjMatrix;
    165         }
    166 
    167         private DoubleMatrix CalculateAdjacencyRows(IEnumerable<IRun> runs)
    168         {
    169             var runNames = runs.Select(x => x.Name).ToArray();
    170             var runsArray = runs.ToArray();
    171             DoubleMatrix varImpactMatrix = CalculateVariableImpactMatrix(runsArray, runNames);
    172          
    173             var targetMatrix = new DoubleMatrix(1, varImpactMatrix.Rows);
    174 
    175             for (int i = 0; i < varImpactMatrix.Rows; ++i)
    176             {
    177                 targetMatrix[0, i] = varImpactMatrix[i, runNames.Length];
    178             }
    179 
    180             targetMatrix.RowNames = new[] { "Impacts" };
    181             targetMatrix.ColumnNames = varImpactMatrix.RowNames;
    182             return targetMatrix;
    183         }
    184 
    185         private DoubleMatrix UpdateAdjacencyMatrixByThresholdAndTargetVariable(double threshold, string targetVariable, DoubleMatrix adjMatrix)
    186         {
    187             var originalMatrix = (DoubleMatrix)viewHost1.Content;
    188             var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
    189             string[] targets = adjMatrix.RowNames.ToArray();
    190             var targetIndex = Array.IndexOf(targets, targetVariable);
    191 
    192             for (int j = 0; j < groupRunCollection.Count; ++j)
    193             {
    194                 double originalValue = originalMatrix[targetIndex, j];
    195                 adjMatrix[targetIndex, j] = (originalValue <= Math.Max(threshold, Double.Parse(genThreshold.Text))) ? 0 : originalValue;
    196             }
    197             return adjMatrix;
    198         }
    199 
    200         private DoubleMatrix UpdateAdjacencyMatrixByThreshold(double threshold, DoubleMatrix adjMatrix)
    201         {
    202             var originalMatrix = (DoubleMatrix)viewHost1.Content;
    203             var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
    204 
    205             for (int i = 0; i < adjMatrix.Rows; ++i)
    206             {
    207                 for (int j = 0; j < adjMatrix.Columns; ++j)
    208                 {
    209                     double originalValue = originalMatrix[i, j];
    210                     adjMatrix[i, j] = originalValue <= threshold ? 0 : originalValue;
    211                 }
    212             }
    213             return adjMatrix;
    214         }
    215 
    216         private double GetMinNonNullElement(DoubleMatrix adjMatrix)
    217         {
    218             double min = adjMatrix.Max();
    219             for (int i = 0; i < adjMatrix.Rows; i++)
    220             {
    221                 for (int j = 0; j < adjMatrix.Columns; j++)
    222                 {                 
    223                     min = (min > adjMatrix[i, j] && adjMatrix[i, j] != 0) ? adjMatrix[i, j] : min;
    224                 }
    225             }
    226             return min;
    227         }
    228 
    229         private double GetMaxFromRow(int rowIndex, DoubleMatrix adjMatrix)
    230         {
    231             double max = adjMatrix.Min();
    232             for (int j = 0; j < adjMatrix.Columns; ++j)
    233             {
    234                 max = (max < adjMatrix[rowIndex, j] && adjMatrix[rowIndex, j] != 0) ? adjMatrix[rowIndex, j] : max;
    235             }
    236             return max;
    237         }
    238 
    239         private DoubleMatrix CalculateNodeImportance(DoubleMatrix adjMatrix)
    240         {
    241             DoubleMatrix nodeImportance = new DoubleMatrix(adjMatrix.Rows, 1);
    242             var variables = new List<Tuple<string, double>>();
    243             var rowNames = adjMatrix.RowNames.ToList();
    244             var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
    245             double[] meanQuality = new double[groupRunCollection.Count];
    246 
    247             for (int j = 0; j < groupRunCollection.Count; ++j)
    248             {
    249                 var g = groupRunCollection[j];
    250                 meanQuality[j] = g.Average(x => ((IRegressionSolution)x.Results[TrainingBestSolutionParameterName]).TrainingRSquared);
    251             }
    252 
    253             for (int i = 0; i < adjMatrix.Columns; ++i)
    254             {
    255                 for (int j = 0; j < adjMatrix.Rows; ++j)
    256                 {
    257                     nodeImportance[i, 0] += adjMatrix[j, i] * meanQuality[j];
    258                 }
    259                 nodeImportance[i, 0] /= (adjMatrix.Rows - 1);
    260                 variables.Add(new Tuple<string, double>(rowNames[i], nodeImportance[i, 0]));
    261             }
    262 
    263             variables.Sort((b, a) => a.Item2.CompareTo(b.Item2));
    264 
    265             for (int i = 0; i < nodeImportance.Rows; ++i)
    266             {
    267                 nodeImportance[i, 0] = variables[i].Item2;
    268                 rowNames[i] = variables[i].Item1;
    269             }
    270 
    271             nodeImportance.RowNames = rowNames;
    272             nodeImportance.ColumnNames = new[] { "Node Importance" };
    273             return nodeImportance;
    274         }
    275 
    276         //modified from RunCollectionVariableImpactView
    277         private DoubleMatrix CalculateVariableImpactMatrix(IRun[] runs, string[] runNames)
    278         {
    279             IEnumerable<DoubleMatrix> allVariableImpacts = (from run in runs
    280                                                             select run.Results[variableImpactResultName]).Cast<DoubleMatrix>();
    281             IEnumerable<string> variableNames = (from variableImpact in allVariableImpacts
    282                                                  from variableName in variableImpact.RowNames
    283                                                  select variableName).Distinct();
    284 
    285             // filter variableNames: only include names that have at least one non-zero value in a run
    286             List<string> variableNamesList = (from variableName in variableNames
    287                                               where GetVariableImpacts(variableName, allVariableImpacts).Any(x => !x.IsAlmost(0.0))
    288                                               select variableName).ToList();
    289 
    290             List<string> columnNames = new List<string>(runNames);
    291             columnNames.Add("Mean");
    292 
    293             int numberOfRuns = runs.Length;
    294 
    295             DoubleMatrix matrix = new DoubleMatrix(variableNamesList.Count, numberOfRuns + 1);
    296             matrix.SortableView = true;
    297             matrix.ColumnNames = columnNames;
    298 
    299             List<List<double>> variableImpactsOverRuns = (from variableName in variableNamesList
    300                                                           select GetVariableImpacts(variableName, allVariableImpacts).ToList()).ToList();
    301 
    302             for (int row = 0; row < variableImpactsOverRuns.Count; row++)
    303             {
    304                 matrix[row, numberOfRuns] = Math.Round(variableImpactsOverRuns[row].Average(), 3);
    305             }
    306 
    307             // fill matrix with impacts from runs
    308             for (int i = 0; i < runs.Length; i++)
    309             {
    310                 IRun run = runs[i];
    311                 DoubleMatrix runVariableImpacts = (DoubleMatrix)run.Results[variableImpactResultName];
    312                 for (int j = 0; j < runVariableImpacts.Rows; j++)
    313                 {
    314                     int rowIndex = variableNamesList.FindIndex(s => s == runVariableImpacts.RowNames.ElementAt(j));
    315                     if (rowIndex > -1)
    316                     {
    317                         matrix[rowIndex, i] = Math.Round(runVariableImpacts[j, 0], 3);
    318                     }
    319                 }
    320             }
    321 
    322             // sort by median
    323             var sortedMatrix = (DoubleMatrix)matrix.Clone();
    324             var sortedIndexes = from i in Enumerable.Range(0, sortedMatrix.Rows)
    325                                 orderby matrix[i, numberOfRuns]
    326                                 select i;
    327 
    328             int targetIndex = 0;
    329             foreach (var sourceIndex in sortedIndexes)
    330             {
    331                 for (int c = 0; c < matrix.Columns; c++)
    332                     sortedMatrix[targetIndex, c] = matrix[sourceIndex, c];
    333                 targetIndex++;
    334             }
    335             sortedMatrix.RowNames = sortedIndexes.Select(i => variableNamesList[i]);
    336 
    337             var vars = new List<Tuple<int, string, double>>();
    338             var rowNames = sortedMatrix.RowNames.ToList();
    339 
    340             var groupRunCollection = Content.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
    341             var inputs = ((IRegressionProblemData)groupRunCollection[0].First().Parameters["ProblemData"]).InputVariables.ToList();
    342             List<string> inp = (from input in inputs
    343                                 select (input.ToString())).ToList();
    344 
    345             for (int i = 0; i < sortedMatrix.Rows; ++i)
    346             {
    347                 int inputIndex = inp.FindIndex(x => x == rowNames[i]);
    348                 vars.Add(new Tuple<int, string, double>(inputIndex, rowNames[i], sortedMatrix[i, runNames.Length]));
    349             }
    350 
    351                 vars.Sort((a, b) => a.Item1.CompareTo(b.Item1));
    352                
    353             for (int i = 0; i < sortedMatrix.Rows; ++i)
    354             {
    355                 sortedMatrix[i, runNames.Length] = vars[i].Item3;
    356                 rowNames[i] = vars[i].Item2;
    357             }
    358             sortedMatrix.RowNames = rowNames;
    359 
    360             return sortedMatrix;
    361         }
    362 
    363         //taken from RunCollectionVariableImpactView
    364         private IEnumerable<double> GetVariableImpacts(string variableName, IEnumerable<DoubleMatrix> allVariableImpacts)
    365         {
    366             foreach (DoubleMatrix runVariableImpacts in allVariableImpacts)
    367             {
    368                 int row = 0;
    369                 foreach (string rowName in runVariableImpacts.RowNames)
    370                 {
    371                     if (rowName == variableName)
    372                         yield return runVariableImpacts[row, 0];
    373                     row++;
    374                 }
    375             }
    376         }
    377 
    378         private void trackBar1_ValueChanged(object sender, EventArgs e)
    379         {
    380             genThreshold.Text = (0.001 * trackBar1.Value).ToString();
    381             textBox1.Text = (0.001 * trackBar1.Minimum).ToString();
    382             textBox2.Text = (0.001 * trackBar1.Maximum).ToString();
    383             viewHost3.Content = UpdateAdjacencyMatrixByThreshold(0.001 * trackBar1.Value, (DoubleMatrix)viewHost3.Content);
    384         }
    385 
    386         private void mouseDownEvent(TrackBar tb, MouseEventArgs e)
    387         {
    388                 double percentage = (double)e.X / (double)(tb.Width - 6);
    389                 double clickPos = percentage * (tb.Maximum - tb.Minimum);
    390                 try
    391                 {
    392                     tb.Value = (int)clickPos + tb.Minimum;
    393                 }
    394                 catch
    395                 {
    396                     MessageBox.Show("Value outside range!");
    397                     return;
    398                 }
    399         }
    400 
    401         private void trackBar1_MouseDown(object sender, MouseEventArgs e)
    402         {
    403             mouseDownEvent(trackBar1, e);
    404         }
    405 
    406         private void trackBar2_MouseDown(object sender, MouseEventArgs e)
    407         {
    408             if (targetVariablesCombo.SelectedIndex < 0)
    409             {
    410                 return;
    411             }
    412             else
    413             {
    414                 mouseDownEvent(trackBar2, e);
    415             }
    416         }
    417 
    418         private void trackBar2_ValueChanged(object sender, EventArgs e)
    419         {
    420             targetThreshold.Text = (0.001 * trackBar2.Value).ToString();
    421 
    422             if (targetVariablesCombo.SelectedIndex < 0)
    423             {
    424                 MessageBox.Show("Please select target variable!");
    425                 return;
    426             }
    427             else
    428             {
    429                 string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
    430                 viewHost3.Content = UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
    431             }
    432         }
    433 
    434         private void genThresholdEvent()
    435         {
    436             this.errorProvider.SetError(genThreshold, "");
    437 
    438             if (genThreshold.Text != "")
    439             {
    440                 if (Double.Parse(genThreshold.Text) >= GetMinNonNullElement((DoubleMatrix)viewHost1.Content) && Double.Parse(genThreshold.Text) <= ((DoubleMatrix)viewHost1.Content).Max())
    441                 {
    442                     genThreshold.Select(genThreshold.Text.Length, 0);
    443                     trackBar1.Value = (int)(1000 * Double.Parse(genThreshold.Text));
    444                     viewHost3.Content = UpdateAdjacencyMatrixByThreshold(Double.Parse(genThreshold.Text), (DoubleMatrix)viewHost3.Content);
    445                 }
    446                 else
    447                 {
    448                     this.errorProvider.SetError(genThreshold, "Value out of range!");
    449                 }
    450             }
    451             else
    452             {
    453                 MessageBox.Show("Please select a threshold!");
    454                 this.errorProvider.SetError(genThreshold, "");
    455                 return;
    456             }
    457         }
    458 
    459         private void genThreshold_TextChanged(object sender, EventArgs e)
    460         {
    461             genThresholdEvent();
    462         }
    463 
    464         private void genThreshold_KeyDown(object sender, KeyEventArgs e)
    465         {
    466             if (e.KeyCode == Keys.Enter)
    467                 genThresholdEvent();       
    468         }
    469 
    470         private void targetThresholdEvent()
    471         {
    472             this.errorProvider2.SetError(targetThreshold, "");
    473 
    474             if (targetVariablesCombo.SelectedIndex < 0)
    475             {
    476                 return;
    477             }
    478             else
    479             {
    480                 string selectedItem = (string)targetVariablesCombo.Items[targetVariablesCombo.SelectedIndex];
    481                 if (Double.Parse(targetThreshold.Text) >= Double.Parse(textBox3.Text) && Double.Parse(targetThreshold.Text) <= Double.Parse(textBox4.Text))
    482                 {
    483                     trackBar2.Value = (int)(1000 * Double.Parse(targetThreshold.Text));
    484                 }
    485                 else
    486                 {
    487                     this.errorProvider2.SetError(targetThreshold, "Value out of range!");
    488                     return;
    489                 }
    490             }
    491         }
    492 
    493         private void targetThreshold_TextChanged(object sender, EventArgs e)
    494         {
    495             targetThresholdEvent();
    496         }
    497 
    498         private void targetThreshold_KeyDown(object sender, KeyEventArgs e)
    499         {
    500             if (e.KeyCode == Keys.Enter)
    501             {
    502                 targetThresholdEvent();
    503             }
    504         }
    505 
    506         private void targetVariablesCombo_Dropdown(object sender, System.EventArgs e)
    507         {
    508             targetVariablesCombo.Items.Clear();
    509             string[] targetVariables = ((DoubleMatrix)viewHost3.Content).RowNames.ToArray();
    510             targetVariablesCombo.Items.AddRange(targetVariables);
    511         }
    512 
    513         private void targetVariablesCombo_SelectedIndexChanged(object sender, System.EventArgs e)
    514         {
    515             var targetIndex = targetVariablesCombo.SelectedIndex;
    516             string selectedItem = (string)targetVariablesCombo.Items[targetIndex];
    517             trackBar2.Minimum = 0;
    518             trackBar2.Maximum = (int)(1000 * GetMaxFromRow(targetIndex, (DoubleMatrix)viewHost1.Content));
    519             textBox3.Text = trackBar2.Minimum.ToString();
    520             textBox4.Text = (0.001 * trackBar2.Maximum).ToString();
    521             UpdateAdjacencyMatrixByThresholdAndTargetVariable(0.001 * trackBar2.Value, selectedItem, (DoubleMatrix)viewHost3.Content);
    522         }
    523     }
     207            var arc = new Arc(variableNode, targetNode) { Weight = impact };
     208            vn.AddArc(arc);
     209          }
     210        }
     211      }
     212      return vn;
     213    }
     214
     215    private static double CalculateAverageQuality(RunCollection runs) {
     216      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
     217      var target = pd.TargetVariable;
     218      var inputs = pd.AllowedInputVariables;
     219
     220      if (!runs.All(x => {
     221        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
     222        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
     223      })) {
     224        throw new ArgumentException("All runs must have the same target and inputs.");
     225      }
     226      return runs.Average(x => ((DoubleValue)x.Results["Best training solution quality"]).Value);
     227    }
     228
     229    private static Dictionary<string, double> CalculateAverageImpacts(RunCollection runs, string resultName) {
     230      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
     231      var target = pd.TargetVariable;
     232      var inputs = pd.AllowedInputVariables.ToList();
     233
     234      var impacts = inputs.ToDictionary(x => x, x => 0d);
     235
     236      // check if all the runs have the same target and same inputs
     237      if (!runs.All(x => {
     238        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
     239        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
     240      })) {
     241        throw new ArgumentException("All runs must have the same target and inputs.");
     242      }
     243
     244      foreach (var run in runs) {
     245        var impactsMatrix = (DoubleMatrix)run.Results[resultName];
     246
     247        int i = 0;
     248        foreach (var v in impactsMatrix.RowNames) {
     249          impacts[v] += impactsMatrix[i, 0];
     250          ++i;
     251        }
     252      }
     253
     254      foreach (var v in inputs) {
     255        impacts[v] /= runs.Count;
     256      }
     257
     258      return impacts;
     259    }
     260
     261    private static string Concatenate(IEnumerable<string> strings) {
     262      var sb = new StringBuilder();
     263      foreach (var s in strings) {
     264        sb.Append(s);
     265      }
     266      return sb.ToString();
     267    }
     268
     269    private void ConfigureNodeShapes() {
     270      graphChart.ClearShapes();
     271      var font = new Font(FontFamily.GenericSansSerif, 12);
     272      graphChart.AddShape(typeof(VariableNetworkNode), new LabeledPrimitive(new Ellipse(graphChart.Chart, new PointD(0, 0), new PointD(30, 30), Pens.Black, Brushes.White), "", font));
     273      graphChart.AddShape(typeof(JunctionNetworkNode), new LabeledPrimitive(new Rectangle(graphChart.Chart, new PointD(0, 0), new PointD(15, 15), Pens.Black, Brushes.DarkGray), "", font));
     274    }
     275
     276    #region events
     277    protected override void OnContentChanged() {
     278      base.OnContentChanged();
     279      var run = Content.First();
     280      var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
     281      var variables = new HashSet<string>(new List<string>(pd.Dataset.DoubleVariables));
     282      impactResultNameComboBox.Items.Clear();
     283      foreach (var result in run.Results.Where(x => x.Value is DoubleMatrix)) {
     284        var m = (DoubleMatrix)result.Value;
     285        if (m.RowNames.All(x => variables.Contains(x)))
     286          impactResultNameComboBox.Items.Add(result.Key);
     287      }
     288      qualityResultNameComboBox.Items.Clear();
     289      foreach (var result in run.Results.Where(x => x.Value is DoubleValue)) {
     290        qualityResultNameComboBox.Items.Add(result.Key);
     291      }
     292      if (impactResultNameComboBox.Items.Count > 0) {
     293        impactResultNameComboBox.Text = (string)impactResultNameComboBox.Items[0];
     294      }
     295      if (qualityResultNameComboBox.Items.Count > 0) {
     296        qualityResultNameComboBox.Text = (string)qualityResultNameComboBox.Items[0];
     297      }
     298      if (impactResultNameComboBox.Items.Count > 0 && qualityResultNameComboBox.Items.Count > 0)
     299        NetworkConfigurationChanged(this, EventArgs.Empty);
     300    }
     301
     302    private void TextBoxValidating(object sender, CancelEventArgs e) {
     303      double v;
     304      string errorMsg = "Could not parse the entered value. Please input a real number.";
     305      var tb = (TextBox)sender;
     306      if (!double.TryParse(tb.Text, out v)) {
     307        e.Cancel = true;
     308        tb.Select(0, tb.Text.Length);
     309
     310        // Set the ErrorProvider error with the text to display.
     311        this.errorProvider.SetError(tb, errorMsg);
     312        errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
     313        errorProvider.SetIconPadding(tb, -20);
     314      }
     315    }
     316
     317    private void NetworkConfigurationBoxValidated(object sender, EventArgs e) {
     318      var tb = (TextBox)sender;
     319      errorProvider.SetError(tb, string.Empty);
     320      NetworkConfigurationChanged(sender, e);
     321    }
     322
     323    private void LayoutConfigurationBoxValidated(object sender, EventArgs e) {
     324      var tb = (TextBox)sender;
     325      errorProvider.SetError(tb, string.Empty);
     326      LayoutConfigurationChanged(sender, e);
     327    }
     328
     329    private void NetworkConfigurationChanged(object sender, EventArgs e) {
     330      var useBest = impactAggregationComboBox.SelectedIndex <= 0;
     331      var threshold = double.Parse(impactThresholdTextBox.Text);
     332      var qualityResultName = qualityResultNameComboBox.Text;
     333      var impactsResultName = impactResultNameComboBox.Text;
     334      if (string.IsNullOrEmpty(qualityResultName) || string.IsNullOrEmpty(impactsResultName))
     335        return;
     336      var maximization = maximizationCheckBox.Checked;
     337      var network = BuildNetworkFromVariableImpacts(Content, qualityResultName, maximization, impactsResultName, threshold, useBest);
     338      if (network.Vertices.Any())
     339        graphChart.Graph = network;
     340    }
     341
     342    private void LayoutConfigurationChanged(object sender, EventArgs e) {
     343      ConstrainedForceDirectedLayout.EdgeRouting routingMode;
     344      switch (edgeRoutingComboBox.SelectedIndex) {
     345        case 0:
     346          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.None;
     347          break;
     348        case 1:
     349          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Polyline;
     350          break;
     351        case 2:
     352          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Orthogonal;
     353          break;
     354        default:
     355          throw new ArgumentException("Invalid edge routing mode.");
     356      }
     357      var idealEdgeLength = double.Parse(idealEdgeLengthTextBox.Text);
     358      if (routingMode == graphChart.RoutingMode && idealEdgeLength.IsAlmost(graphChart.IdealEdgeLength)) return;
     359      graphChart.RoutingMode = routingMode;
     360      graphChart.PerformEdgeRouting = routingMode != ConstrainedForceDirectedLayout.EdgeRouting.None;
     361      graphChart.IdealEdgeLength = idealEdgeLength;
     362      graphChart.Draw();
     363    }
     364    #endregion
     365  }
    524366}
Note: See TracChangeset for help on using the changeset viewer.