Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.VariableInteractionNetworks/HeuristicLab.VariableInteractionNetworks.Views/3.3/RunCollectionVariableInteractionNetworkView.cs @ 15529

Last change on this file since 15529 was 15421, checked in by bburlacu, 7 years ago

#2288: Sync with trunk + Minor refactor.

File size: 22.5 KB
RevLine 
[12198]1#region License Information
2/* HeuristicLab
[13727]3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[12198]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.ComponentModel;
25using System.Drawing;
[13821]26using System.Globalization;
[12198]27using System.Linq;
[13727]28using System.Text;
[12198]29using System.Windows.Forms;
30using HeuristicLab.Common;
[13727]31using HeuristicLab.Core;
32using HeuristicLab.Core.Views;
[12198]33using HeuristicLab.Data;
34using HeuristicLab.MainForm;
35using HeuristicLab.Optimization;
36using HeuristicLab.Problems.DataAnalysis;
[13727]37using HeuristicLab.Visualization;
[13773]38using Ellipse = HeuristicLab.Visualization.Ellipse;
[13727]39using Rectangle = HeuristicLab.Visualization.Rectangle;
[12198]40
[13727]41namespace HeuristicLab.VariableInteractionNetworks.Views {
42  [View("Variable Interaction Network")]
43  [Content(typeof(RunCollection), IsDefaultView = false)]
[12198]44
[13727]45  public sealed partial class RunCollectionVariableInteractionNetworkView : ItemView {
46    public RunCollectionVariableInteractionNetworkView() {
47      InitializeComponent();
48      ConfigureNodeShapes();
49    }
[12229]50
[13727]51    public new RunCollection Content {
52      get { return (RunCollection)base.Content; }
53      set {
54        if (value != null && value != Content) {
55          base.Content = value;
[12320]56        }
[13727]57      }
58    }
[12229]59
[13773]60    private VariableInteractionNetwork variableInteractionNetwork;
[12229]61
[13773]62    private static void AssertSameProblemData(RunCollection runs) {
63      IDataset dataset = null;
64      IRegressionProblemData problemData = null;
65      foreach (var run in runs) {
66        var solution = (IRegressionSolution)run.Results.Values.Single(x => x is IRegressionSolution);
67        var ds = solution.ProblemData.Dataset;
68
69        if (solution.ProblemData == problemData) continue;
70        if (ds == dataset) continue;
71        if (problemData == null) {
72          problemData = solution.ProblemData;
73          continue;
[12320]74        }
[13773]75        if (dataset == null) {
76          dataset = ds;
77          continue;
[13727]78        }
[12198]79
[13773]80        if (problemData.TrainingPartition.Start != solution.ProblemData.TrainingPartition.Start || problemData.TrainingPartition.End != solution.ProblemData.TrainingPartition.End)
81          throw new InvalidOperationException("The runs must share the same data.");
[12198]82
[13773]83        if (!ds.DoubleVariables.SequenceEqual(dataset.DoubleVariables))
84          throw new InvalidOperationException("The runs must share the same data.");
85
86        foreach (var v in ds.DoubleVariables) {
87          var values1 = (IList<double>)ds.GetReadOnlyDoubleValues(v);
88          var values2 = (IList<double>)dataset.GetReadOnlyDoubleValues(v);
89
90          if (values1.Count != values2.Count)
91            throw new InvalidOperationException("The runs must share the same data.");
92
93          if (!values1.SequenceEqual(values2))
94            throw new InvalidOperationException("The runs must share the same data.");
[12320]95        }
[13773]96      }
97    }
[12198]98
[14275]99    public static RegressionEnsembleSolution CreateEnsembleSolution(IEnumerable<IRun> runs) {
[13773]100      var solutions = runs.Select(x => x.Results.Values.Single(v => v is IRegressionSolution)).Cast<IRegressionSolution>();
101      return new RegressionEnsembleSolution(new RegressionEnsembleModel(solutions.Select(x => x.Model)), solutions.First().ProblemData);
102    }
103
104    public static Dictionary<string, Tuple<IEnumerable<IRun>, Dictionary<string, double>>> CalculateVariableImpactsOnline(RunCollection runs, bool useBest) {
105      AssertSameProblemData(runs);
106      var solution = (IRegressionSolution)runs.First().Results.Values.Single(x => x is IRegressionSolution);
107      var dataset = (Dataset)solution.ProblemData.Dataset;
108      var originalValues = dataset.DoubleVariables.ToDictionary(x => x, x => dataset.GetReadOnlyDoubleValues(x).ToList());
[15421]109      var medians = dataset.DoubleVariables.ToDictionary(x => x, x => Enumerable.Repeat(originalValues[x].Median(), originalValues[x].Count).ToList());
[13773]110
111      var targetImpacts = new Dictionary<string, Tuple<IEnumerable<IRun>, Dictionary<string, double>>>();
112
113      if (useBest) {
114        // build network using only the best run for each target
115      } else {
116        var groups = runs.GroupBy(run => {
117          var sol = (IRegressionSolution)run.Results.Values.Single(x => x is IRegressionSolution);
118          return Concatenate(sol.ProblemData.AllowedInputVariables) + sol.ProblemData.TargetVariable;
119        });
120
121        foreach (var group in groups) {
122          // calculate average impacts
123          var averageImpacts = new Dictionary<string, double>();
124          solution = (IRegressionSolution)group.First().Results.Values.Single(x => x is IRegressionSolution);
125          foreach (var run in group) {
126            var sol = (IRegressionSolution)run.Results.Values.Single(v => v is IRegressionSolution);
127
128            DoubleLimit estimationLimits = null;
129            if (run.Parameters.ContainsKey("EstimationLimits")) {
130              estimationLimits = (DoubleLimit)run.Parameters["EstimationLimits"];
[12568]131            }
[15421]132            var md = dataset.ToModifiable();
[13773]133            var impacts = CalculateImpacts(sol, md, originalValues, medians, estimationLimits);
134            foreach (var pair in impacts) {
135              if (averageImpacts.ContainsKey(pair.Key))
136                averageImpacts[pair.Key] += pair.Value;
137              else {
138                averageImpacts[pair.Key] = pair.Value;
139              }
[12568]140            }
[13727]141          }
[13773]142          var count = group.Count();
143          var keys = averageImpacts.Keys.ToList();
144          foreach (var v in keys) {
145            averageImpacts[v] /= count;
146          }
147
148          targetImpacts[solution.ProblemData.TargetVariable] = new Tuple<IEnumerable<IRun>, Dictionary<string, double>>(group, averageImpacts);
[12320]149        }
[13727]150      }
[13773]151      return targetImpacts;
152    }
[12320]153
[13773]154    private static Dictionary<string, double> CalculateImpacts(IRegressionSolution solution, ModifiableDataset dataset,
155      Dictionary<string, List<double>> originalValues, Dictionary<string, List<double>> medianValues, DoubleLimit estimationLimits = null) {
156      var impacts = new Dictionary<string, double>();
157
158      var model = solution.Model;
159      var pd = solution.ProblemData;
160
161      var rows = pd.TrainingIndices.ToList();
162      var targetValues = pd.Dataset.GetDoubleValues(pd.TargetVariable, rows).ToList();
163
164
165      foreach (var v in pd.AllowedInputVariables) {
166        dataset.ReplaceVariable(v, medianValues[v]);
167
168        var estimatedValues = model.GetEstimatedValues(dataset, rows);
169        if (estimationLimits != null)
170          estimatedValues = estimatedValues.LimitToRange(estimationLimits.Lower, estimationLimits.Upper);
171
172        OnlineCalculatorError error;
173        var r = OnlinePearsonsRCalculator.Calculate(targetValues, estimatedValues, out error);
174        var newQuality = error == OnlineCalculatorError.None ? r * r : double.NaN;
175        var originalQuality = solution.TrainingRSquared;
176        impacts[v] = originalQuality - newQuality;
177
178        dataset.ReplaceVariable(v, originalValues[v]);
179      }
180      return impacts;
[13727]181    }
[12320]182
[14275]183    public static Dictionary<string, Tuple<IEnumerable<IRun>, Dictionary<string, double>>> CalculateVariableImpactsFromRunResults(RunCollection runs,
[13773]184      string qualityResultName, bool maximization, string impactsResultName, bool useBestRunsPerTarget = false) {
[13727]185      var targets = runs.GroupBy(x => ((IRegressionProblemData)x.Parameters["ProblemData"]).TargetVariable).ToList();
[13773]186      var targetImpacts = new Dictionary<string, Tuple<IEnumerable<IRun>, Dictionary<string, double>>>();
[15421]187
188      Func<IRun, double> getQualityValue = run => ((DoubleValue)run.Results[qualityResultName]).Value;
189
[13727]190      if (useBestRunsPerTarget) {
[13773]191        var bestRunsPerTarget = maximization
[15421]192          ? targets.Select(x => x.OrderBy(getQualityValue).Last())
193          : targets.Select(x => x.OrderBy(getQualityValue).First());
[12229]194
[13727]195        foreach (var run in bestRunsPerTarget) {
196          var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
197          var target = pd.TargetVariable;
198          var impacts = (DoubleMatrix)run.Results[impactsResultName];
[13773]199          targetImpacts[target] = new Tuple<IEnumerable<IRun>, Dictionary<string, double>>(new[] { run }, impacts.RowNames.Select((x, i) => new { Name = x, Index = i }).ToDictionary(x => x.Name, x => impacts[x.Index, 0]));
[12320]200        }
[13727]201      } else {
202        foreach (var target in targets) {
203          var averageImpacts = CalculateAverageImpacts(new RunCollection(target), impactsResultName);
[13773]204          targetImpacts[target.Key] = new Tuple<IEnumerable<IRun>, Dictionary<string, double>>(target, averageImpacts);
[12198]205        }
[13727]206      }
[13773]207      return targetImpacts;
208    }
[12198]209
[14275]210    public static VariableInteractionNetwork CreateNetwork(Dictionary<string, Tuple<IEnumerable<IRun>, Dictionary<string, double>>> targetImpacts) {
[13773]211      var nodes = new Dictionary<string, IVertex>();
212      var vn = new VariableInteractionNetwork();
[13727]213      foreach (var ti in targetImpacts) {
214        var target = ti.Key;
[13773]215        var variableImpacts = ti.Value.Item2;
216        var targetRuns = ti.Value.Item1;
[13727]217        IVertex targetNode;
[12198]218
[13773]219        var variables = variableImpacts.Keys.ToList();
[13727]220        if (variables.Count == 0) continue;
[12198]221
[13727]222        if (!nodes.TryGetValue(target, out targetNode)) {
223          targetNode = new VariableNetworkNode { Label = target };
224          vn.AddVertex(targetNode);
225          nodes[target] = targetNode;
[12320]226        }
[12229]227
[13727]228        IVertex variableNode;
229        if (variables.Count > 1) {
230          var variableList = new List<string>(variables) { target };
231          var junctionLabel = Concatenate(variableList);
232          IVertex junctionNode;
[13874]233          var sb = new StringBuilder();
[13727]234          if (!nodes.TryGetValue(junctionLabel, out junctionNode)) {
[13789]235            var solutionsEnsemble = CreateEnsembleSolution(targetRuns);
[13874]236            junctionNode = new JunctionNetworkNode { Label = solutionsEnsemble.TrainingRSquared.ToString("N3", CultureInfo.CurrentCulture), Data = solutionsEnsemble };
[13727]237            vn.AddVertex(junctionNode);
238            nodes[junctionLabel] = junctionNode;
[13874]239            sb.AppendLine(junctionNode.Label);
[13727]240          }
241          IArc arc;
242          foreach (var v in variables) {
243            var impact = variableImpacts[v];
244            if (!nodes.TryGetValue(v, out variableNode)) {
245              variableNode = new VariableNetworkNode { Label = v };
246              vn.AddVertex(variableNode);
247              nodes[v] = variableNode;
[12320]248            }
[13821]249            arc = new Arc(variableNode, junctionNode) { Weight = impact, Label = impact.ToString("N3", CultureInfo.CurrentCulture) };
[13874]250            sb.AppendLine(v + ": " + arc.Label);
[13727]251            vn.AddArc(arc);
252          }
[13874]253          var jcnNode = (JunctionNetworkNode)junctionNode;
254          var trainingR2 = ((IRegressionSolution)jcnNode.Data).TrainingRSquared;
[13821]255          arc = new Arc(junctionNode, targetNode) { Weight = junctionNode.InArcs.Sum(x => x.Weight), Label = trainingR2.ToString("N3", CultureInfo.CurrentCulture) };
[13727]256          vn.AddArc(arc);
257        } else {
258          foreach (var v in variables) {
259            var impact = variableImpacts[v];
260            if (!nodes.TryGetValue(v, out variableNode)) {
261              variableNode = new VariableNetworkNode { Label = v };
262              vn.AddVertex(variableNode);
263              nodes[v] = variableNode;
[12320]264            }
[13821]265            var arc = new Arc(variableNode, targetNode) {
[15421]266              Weight = impact,
267              Label = impact.ToString("N3", CultureInfo.CurrentCulture)
[13821]268            };
[13727]269            vn.AddArc(arc);
270          }
[12320]271        }
[13727]272      }
273      return vn;
274    }
[12320]275
[14275]276    public static VariableInteractionNetwork ApplyThreshold(VariableInteractionNetwork originalNetwork, double threshold) {
[13806]277      var arcs = originalNetwork.Arcs.Where(x => x.Weight >= threshold).ToList();
278      if (!arcs.Any()) return originalNetwork;
279      var filteredNetwork = new VariableInteractionNetwork();
280      var cloner = new Cloner();
281      var vertices = arcs.SelectMany(x => new[] { x.Source, x.Target }).Select(cloner.Clone).Distinct(); // arcs are not cloned
282      filteredNetwork.AddVertices(vertices);
283      filteredNetwork.AddArcs(arcs.Select(x => (IArc)x.Clone(cloner)));
284
285      var unusedJunctions = filteredNetwork.Vertices.Where(x => x.InDegree == 0 && x is JunctionNetworkNode).ToList();
286      filteredNetwork.RemoveVertices(unusedJunctions);
287      var orphanedNodes = filteredNetwork.Vertices.Where(x => x.Degree == 0).ToList();
288      filteredNetwork.RemoveVertices(orphanedNodes);
289      return filteredNetwork.Vertices.Any() ? filteredNetwork : originalNetwork;
290    }
291
[13727]292    private static double CalculateAverageQuality(RunCollection runs) {
293      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
294      var target = pd.TargetVariable;
295      var inputs = pd.AllowedInputVariables;
[12198]296
[13727]297      if (!runs.All(x => {
298        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
299        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
300      })) {
301        throw new ArgumentException("All runs must have the same target and inputs.");
302      }
303      return runs.Average(x => ((DoubleValue)x.Results["Best training solution quality"]).Value);
304    }
[12320]305
[14275]306    public static Dictionary<string, double> CalculateAverageImpacts(RunCollection runs, string resultName) {
[13727]307      var pd = (IRegressionProblemData)runs.First().Parameters["ProblemData"];
308      var target = pd.TargetVariable;
309      var inputs = pd.AllowedInputVariables.ToList();
[12320]310
[13727]311      var impacts = inputs.ToDictionary(x => x, x => 0d);
[12320]312
[13727]313      // check if all the runs have the same target and same inputs
314      if (!runs.All(x => {
315        var problemData = (IRegressionProblemData)x.Parameters["ProblemData"];
316        return target == problemData.TargetVariable && inputs.SequenceEqual(problemData.AllowedInputVariables);
317      })) {
318        throw new ArgumentException("All runs must have the same target and inputs.");
319      }
[12320]320
[13727]321      foreach (var run in runs) {
322        var impactsMatrix = (DoubleMatrix)run.Results[resultName];
323        int i = 0;
324        foreach (var v in impactsMatrix.RowNames) {
325          impacts[v] += impactsMatrix[i, 0];
326          ++i;
[12320]327        }
[13727]328      }
[12320]329
[13727]330      foreach (var v in inputs) {
331        impacts[v] /= runs.Count;
332      }
[12320]333
[13727]334      return impacts;
335    }
[12263]336
[13727]337    private static string Concatenate(IEnumerable<string> strings) {
338      var sb = new StringBuilder();
339      foreach (var s in strings) {
340        sb.Append(s);
341      }
342      return sb.ToString();
343    }
[12320]344
[13727]345    private void ConfigureNodeShapes() {
346      graphChart.ClearShapes();
347      var font = new Font(FontFamily.GenericSansSerif, 12);
348      graphChart.AddShape(typeof(VariableNetworkNode), new LabeledPrimitive(new Ellipse(graphChart.Chart, new PointD(0, 0), new PointD(30, 30), Pens.Black, Brushes.White), "", font));
349      graphChart.AddShape(typeof(JunctionNetworkNode), new LabeledPrimitive(new Rectangle(graphChart.Chart, new PointD(0, 0), new PointD(15, 15), Pens.Black, Brushes.DarkGray), "", font));
350    }
[12320]351
[13727]352    #region events
353    protected override void OnContentChanged() {
354      base.OnContentChanged();
355      var run = Content.First();
356      var pd = (IRegressionProblemData)run.Parameters["ProblemData"];
357      var variables = new HashSet<string>(new List<string>(pd.Dataset.DoubleVariables));
358      impactResultNameComboBox.Items.Clear();
359      foreach (var result in run.Results.Where(x => x.Value is DoubleMatrix)) {
360        var m = (DoubleMatrix)result.Value;
361        if (m.RowNames.All(x => variables.Contains(x)))
362          impactResultNameComboBox.Items.Add(result.Key);
363      }
364      qualityResultNameComboBox.Items.Clear();
365      foreach (var result in run.Results.Where(x => x.Value is DoubleValue)) {
366        qualityResultNameComboBox.Items.Add(result.Key);
367      }
368      if (impactResultNameComboBox.Items.Count > 0) {
369        impactResultNameComboBox.Text = (string)impactResultNameComboBox.Items[0];
370      }
371      if (qualityResultNameComboBox.Items.Count > 0) {
372        qualityResultNameComboBox.Text = (string)qualityResultNameComboBox.Items[0];
373      }
374      if (impactResultNameComboBox.Items.Count > 0 && qualityResultNameComboBox.Items.Count > 0)
375        NetworkConfigurationChanged(this, EventArgs.Empty);
376    }
[12320]377
[13727]378    private void TextBoxValidating(object sender, CancelEventArgs e) {
379      double v;
380      string errorMsg = "Could not parse the entered value. Please input a real number.";
381      var tb = (TextBox)sender;
382      if (!double.TryParse(tb.Text, out v)) {
383        e.Cancel = true;
384        tb.Select(0, tb.Text.Length);
[12320]385
[13727]386        // Set the ErrorProvider error with the text to display.
387        this.errorProvider.SetError(tb, errorMsg);
388        errorProvider.BlinkStyle = ErrorBlinkStyle.NeverBlink;
389        errorProvider.SetIconPadding(tb, -20);
390      }
391    }
[12320]392
[13773]393    private void ImpactThresholdTextBoxValidated(object sender, EventArgs e) {
[13727]394      var tb = (TextBox)sender;
395      errorProvider.SetError(tb, string.Empty);
[13806]396      double impact;
[13874]397      if (!double.TryParse(tb.Text, out impact)) {
[13821]398        impact = 0.2;
[13874]399      }
[13806]400      var network = ApplyThreshold(variableInteractionNetwork, impact);
[13773]401      graphChart.Graph = network;
[13727]402    }
[12320]403
[13727]404    private void LayoutConfigurationBoxValidated(object sender, EventArgs e) {
405      var tb = (TextBox)sender;
406      errorProvider.SetError(tb, string.Empty);
407      LayoutConfigurationChanged(sender, e);
408    }
[12320]409
[13727]410    private void NetworkConfigurationChanged(object sender, EventArgs e) {
411      var useBest = impactAggregationComboBox.SelectedIndex <= 0;
[13893]412      var threshold = impactThresholdTrackBar.Value / 100.0;
[13727]413      var qualityResultName = qualityResultNameComboBox.Text;
414      var impactsResultName = impactResultNameComboBox.Text;
415      if (string.IsNullOrEmpty(qualityResultName) || string.IsNullOrEmpty(impactsResultName))
416        return;
417      var maximization = maximizationCheckBox.Checked;
[13773]418      var impacts = CalculateVariableImpactsFromRunResults(Content, qualityResultName, maximization, impactsResultName, useBest);
419      variableInteractionNetwork = CreateNetwork(impacts);
420      var network = ApplyThreshold(variableInteractionNetwork, threshold);
421      graphChart.Graph = network;
[12263]422    }
[13727]423
424    private void LayoutConfigurationChanged(object sender, EventArgs e) {
425      ConstrainedForceDirectedLayout.EdgeRouting routingMode;
426      switch (edgeRoutingComboBox.SelectedIndex) {
427        case 0:
428          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.None;
429          break;
430        case 1:
431          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Polyline;
432          break;
433        case 2:
434          routingMode = ConstrainedForceDirectedLayout.EdgeRouting.Orthogonal;
435          break;
436        default:
437          throw new ArgumentException("Invalid edge routing mode.");
438      }
439      var idealEdgeLength = double.Parse(idealEdgeLengthTextBox.Text);
[14275]440      if (routingMode == graphChart.RoutingMode && idealEdgeLength.IsAlmost(graphChart.DefaultEdgeLength)) return;
[13727]441      graphChart.RoutingMode = routingMode;
442      graphChart.PerformEdgeRouting = routingMode != ConstrainedForceDirectedLayout.EdgeRouting.None;
[14275]443      graphChart.DefaultEdgeLength = idealEdgeLength;
[13727]444      graphChart.Draw();
445    }
[13773]446
[13874]447    private void ControlsEnable(bool enabled) {
448      qualityResultNameComboBox.Enabled
449        = impactResultNameComboBox.Enabled
450        = impactAggregationComboBox.Enabled
[13893]451        = impactThresholdTrackBar.Enabled
[13874]452        = onlineImpactCalculationButton.Enabled
453        = edgeRoutingComboBox.Enabled
[13893]454        = idealEdgeLengthTextBox.Enabled
455        = maximizationCheckBox.Enabled = enabled;
[13874]456    }
457
[13773]458    private void onlineImpactCalculationButton_Click(object sender, EventArgs args) {
459      var worker = new BackgroundWorker();
460      worker.DoWork += (o, e) => {
[13874]461        ControlsEnable(false);
[13773]462        var impacts = CalculateVariableImpactsOnline(Content, false);
[13789]463        variableInteractionNetwork = CreateNetwork(impacts);
[13893]464        var threshold = impactThresholdTrackBar.Minimum + (double)impactThresholdTrackBar.Value / impactThresholdTrackBar.Maximum;
[13789]465        graphChart.Graph = ApplyThreshold(variableInteractionNetwork, threshold);
[13773]466      };
[13874]467      worker.RunWorkerCompleted += (o, e) => ControlsEnable(true);
[13773]468      worker.RunWorkerAsync();
469    }
[13893]470
471    private void relayoutGraphButton_Click(object sender, EventArgs e) {
472      graphChart.Draw();
473    }
[13727]474    #endregion
[13893]475
476    private void exportImpactsMatrixButton_Click(object sender, EventArgs e) {
477      var graph = graphChart.Graph;
478      var labels = graph.Vertices.OfType<VariableNetworkNode>().Select(x => x.Label).ToList();
479      labels.Sort(); // sort variables alphabetically
480      var matrix = new DoubleMatrix(labels.Count, labels.Count) { RowNames = labels, ColumnNames = labels };
481      var indexes = labels.Select((x, i) => new { Label = x, Index = i }).ToDictionary(x => x.Label, x => x.Index);
482      var junctions = graph.Vertices.OfType<JunctionNetworkNode>().ToList();
483      foreach (var jn in junctions) {
484        var target = jn.OutArcs.First().Target.Label;
485        var targetIndex = indexes[target];
486        foreach (var input in jn.InArcs) {
487          var inputIndex = indexes[input.Source.Label];
488          var inputImpact = input.Weight;
489          matrix[targetIndex, inputIndex] = inputImpact;
490        }
491      }
492      for (int i = 0; i < labels.Count; ++i) matrix[i, i] = 1;
493      MainFormManager.MainForm.ShowContent(matrix);
494    }
495
496    private void impactThresholdTrackBar_ValueChanged(object sender, EventArgs e) {
497      var impact = impactThresholdTrackBar.Minimum + (double)impactThresholdTrackBar.Value / impactThresholdTrackBar.Maximum;
498      impactThresholdLabel.Text = impact.ToString("N3", CultureInfo.CurrentCulture);
499      var network = ApplyThreshold(variableInteractionNetwork, impact);
500      graphChart.Graph = network;
501    }
502
503
[13727]504  }
505}
Note: See TracBrowser for help on using the repository browser.