Changeset 15796


Ignore:
Timestamp:
02/21/18 12:01:54 (12 months ago)
Author:
fholzing
Message:

#2871: Added additional logic for progress

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs

    r15752 r15796  
    2222using System;
    2323using System.Collections.Generic;
     24using System.ComponentModel;
    2425using System.Linq;
    25 using System.Threading;
    26 using System.Threading.Tasks;
    2726using HeuristicLab.Common;
    2827using HeuristicLab.Data;
     
    3332  [Content(typeof(IRegressionSolution))]
    3433  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
    35     #region Nested Types
     34    private class BackgroundworkerArguments {
     35      internal MainForm.WindowsForms.MainForm mainForm;
     36      internal RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum replMethod;
     37      internal RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum factorReplMethod;
     38      internal RegressionSolutionVariableImpactsCalculator.DataPartitionEnum dataPartition;
     39    }
    3640    private enum SortingCriteria {
    3741      ImpactValue,
     
    3943      VariableName
    4044    }
    41     #endregion
    42 
    43     #region Fields
     45    private IProgress progress;
    4446    private Dictionary<string, double> rawVariableImpacts = new Dictionary<string, double>();
    45     private Thread thread;
    46     #endregion
    47 
    48     #region Getter/Setter
     47    private BackgroundWorker worker = new BackgroundWorker();
     48
    4949    public new IRegressionSolution Content {
    5050      get { return (IRegressionSolution)base.Content; }
     
    5353      }
    5454    }
    55     #endregion
    56 
    57     #region Ctor
     55
    5856    public RegressionSolutionVariableImpactsView()
    5957      : base() {
     
    6866      this.replacementComboBox.SelectedIndex = 0;
    6967      this.factorVarReplComboBox.SelectedIndex = 0;
    70     }
    71     #endregion
    72 
    73     #region Events
     68
     69      //Worker magic
     70      worker.WorkerSupportsCancellation = true;
     71      worker.WorkerReportsProgress = true;
     72      worker.DoWork += Worker_DoWork;
     73      worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
     74      worker.ProgressChanged += Worker_ProgressChanged;
     75    }
     76
     77
     78    private void Worker_DoWork(object sender, DoWorkEventArgs e) {
     79      var args = e.Argument as BackgroundworkerArguments;
     80
     81      //Remember the original ordering of the variables
     82      var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, args.dataPartition, args.replMethod, args.factorReplMethod,
     83        (i) => {
     84          var worker = (sender as BackgroundWorker);
     85          worker.ReportProgress(0, i);
     86          return worker.CancellationPending;
     87        });
     88
     89      if ((sender as BackgroundWorker).CancellationPending) { return; }
     90      var problemData = Content.ProblemData;
     91      var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
     92      var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
     93
     94      rawVariableImpacts.Clear();
     95      originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
     96    }
     97    private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
     98      progress.ProgressValue = (double)e.UserState;
     99    }
     100    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
     101      if (e.Error != null) { throw e.Error; }
     102      if (e.Error == null && !e.Cancelled) { UpdateDataOrdering(); }
     103      ((MainForm.WindowsForms.MainForm)MainFormManager.MainForm).RemoveOperationProgressFromView(this);
     104    }
     105
    74106    protected override void RegisterContentEvents() {
    75107      base.RegisterContentEvents();
     
    102134
    103135    private void RegressionSolutionVariableImpactsView_VisibleChanged(object sender, EventArgs e) {
    104       if (thread == null) { return; }
    105 
    106       if (thread.IsAlive) { thread.Abort(); }
    107       thread = null;
     136      if (!worker.IsBusy) { return; }
     137      worker.CancelAsync();
    108138    }
    109139
     
    142172    }
    143173
    144     #endregion
    145 
    146     #region Helper Methods   
     174
    147175    private void UpdateVariableImpact() {
    148176      //Check if the selection is valid
     
    159187
    160188      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
    161 
    162       mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
    163 
    164       Task.Factory.StartNew(() => {
    165         thread = Thread.CurrentThread;
    166         //Remember the original ordering of the variables
    167         var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
    168         var problemData = Content.ProblemData;
    169         var inputvariables = new HashSet<string>(problemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
    170         var originalVariableOrdering = problemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).Where(problemData.Dataset.VariableHasType<double>).ToList();
    171 
    172         rawVariableImpacts.Clear();
    173         originalVariableOrdering.ForEach(v => rawVariableImpacts.Add(v, impacts.First(vv => vv.Item1 == v).Item2));
    174       }).ContinueWith((o) => {
    175         UpdateDataOrdering();
    176         mainForm.RemoveOperationProgressFromView(this);
    177         thread = null;
    178       }, TaskScheduler.FromCurrentSynchronizationContext());
     189      progress = mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
     190      progress.ProgressValue = 0;
     191
     192      if (!worker.IsBusy) {
     193        worker.RunWorkerAsync(new BackgroundworkerArguments() {
     194          mainForm = mainForm,
     195          dataPartition = dataPartition,
     196          factorReplMethod = factorReplMethod,
     197          replMethod = replMethod
     198        });
     199      }
    179200    }
    180201
     
    221242      }
    222243    }
    223     #endregion
    224244  }
    225245}
  • trunk/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs

    r15673 r15796  
    5252      All
    5353    }
    54    
     54
    5555    private const string ReplacementParameterName = "Replacement Method";
    5656    private const string DataPartitionParameterName = "DataPartition";
     
    9696      DataPartitionEnum data = DataPartitionEnum.Training,
    9797      ReplacementMethodEnum replacementMethod = ReplacementMethodEnum.Median,
    98       FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best) {
     98      FactorReplacementMethodEnum factorReplacementMethod = FactorReplacementMethodEnum.Best, Func<double, bool> progressCallback = null) {
    9999
    100100      var problemData = solution.ProblemData;
     
    134134      var allowedInputVariables = dataset.VariableNames.Where(v => inputvariables.Contains(v)).ToList();
    135135
     136      int curIdx = 1;
     137      int count = allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>).Count();
    136138      // calculate impacts for double variables
    137139      foreach (var inputVariable in allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>)) {
     140        //Report the current progress in percent. If the callback returns true, it means the execution shall be stopped
     141        if (progressCallback != null) {
     142          if (progressCallback((double)curIdx++ / count)) { return null; }
     143        }
    138144        var newEstimates = EvaluateModelWithReplacedVariable(solution.Model, inputVariable, modifiableDataset, rows, replacementMethod);
    139145        var newR2 = OnlinePearsonsRCalculator.Calculate(targetValues, newEstimates, out error);
     
    180186    }
    181187
     188
    182189    private static IEnumerable<double> EvaluateModelWithReplacedVariable(IRegressionModel model, string variable, ModifiableDataset dataset, IEnumerable<int> rows, ReplacementMethodEnum replacement = ReplacementMethodEnum.Median) {
    183190      var originalValues = dataset.GetReadOnlyDoubleValues(variable).ToList();
Note: See TracChangeset for help on using the changeset viewer.