Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/06/21 13:13:32 (4 years ago)
Author:
dpiringe
Message:

#3026

  • merged trunk into branch
Location:
branches/3026_IntegrationIntoSymSpace
Files:
6 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/3026_IntegrationIntoSymSpace

  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs

    r17180 r17928  
    11#region License Information
     2
    23/* HeuristicLab
    34 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    1819 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
    1920 */
     21
    2022#endregion
    2123
     
    2325using System.Collections.Generic;
    2426using System.Linq;
     27using HEAL.Attic;
    2528using HeuristicLab.Common;
    2629using HeuristicLab.Core;
    2730using HeuristicLab.Data;
    2831using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    29 using HEAL.Attic;
    3032using HeuristicLab.Parameters;
    3133
    3234namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    3335  [StorableType("DE6C1E1E-D7C1-4070-847E-63B68562B10C")]
    34   [Item("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.")]
     36  [Item("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.")]
    3537  public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem {
    36 
    3738    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
    38 
    39     public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
    40       get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
    41     }
     39    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter =>
     40      (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName];
    4241
    4342    public int EvaluatedSolutions {
    44       get { return EvaluatedSolutionsParameter.Value.Value; }
    45       set { EvaluatedSolutionsParameter.Value.Value = value; }
     43      get => EvaluatedSolutionsParameter.Value.Value;
     44      set => EvaluatedSolutionsParameter.Value.Value = value;
    4645    }
    4746
    4847    [StorableConstructor]
    4948    private IntervalInterpreter(StorableConstructorFlag _) : base(_) { }
     49
    5050    private IntervalInterpreter(IntervalInterpreter original, Cloner cloner)
    51         : base(original, cloner) { }
     51      : base(original, cloner) { }
    5252
    5353    public IntervalInterpreter()
    54         : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") {
    55       Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     54      : base("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.") {
     55      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName,
     56        "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
    5657    }
    5758
     
    6364
    6465    #region IStatefulItem Members
     66
    6567    public void InitializeState() {
    6668      EvaluatedSolutions = 0;
    6769    }
     70
    6871    public void ClearState() { }
     72
    6973    #endregion
    7074
    71     public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) {
     75    public Interval GetSymbolicExpressionTreeInterval(
     76      ISymbolicExpressionTree tree, IDataset dataset,
     77      IEnumerable<int> rows = null) {
    7278      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    7379      return GetSymbolicExpressionTreeInterval(tree, variableRanges);
    7480    }
    7581
    76     public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset,
    77       out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) {
     82    public Interval GetSymbolicExpressionTreeIntervals(
     83      ISymbolicExpressionTree tree, IDataset dataset,
     84      out IDictionary<ISymbolicExpressionTreeNode, Interval>
     85        nodeIntervals, IEnumerable<int> rows = null) {
    7886      var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows);
    7987      return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals);
    8088    }
    8189
    82     public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
     90    public Interval GetSymbolicExpressionTreeInterval(
     91      ISymbolicExpressionTree tree,
     92      IReadOnlyDictionary<string, Interval> variableRanges) {
    8393      lock (syncRoot) {
    8494        EvaluatedSolutions++;
    8595      }
    86       int instructionCount = 0;
     96
     97      Interval outputInterval;
     98
     99      var instructionCount = 0;
    87100      var instructions = PrepareInterpreterState(tree, variableRanges);
    88       var outputInterval = Evaluate(instructions, ref instructionCount);
    89 
    90       // because of numerical errors the bounds might be incorrect
    91       if (outputInterval.LowerBound <= outputInterval.UpperBound)
    92         return outputInterval;
    93       else
    94         return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
    95     }
    96 
    97 
    98     public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree,
    99       IDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) {
     101      outputInterval = Evaluate(instructions, ref instructionCount);
     102
     103      return outputInterval.LowerBound <= outputInterval.UpperBound
     104        ? outputInterval
     105        : new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     106    }
     107
     108
     109    public Interval GetSymbolicExpressionTreeIntervals(
     110      ISymbolicExpressionTree tree,
     111      IReadOnlyDictionary<string, Interval> variableRanges,
     112      out IDictionary<ISymbolicExpressionTreeNode, Interval>
     113        nodeIntervals) {
    100114      lock (syncRoot) {
    101115        EvaluatedSolutions++;
    102116      }
    103       int instructionCount = 0;
     117
    104118      var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    105119      var instructions = PrepareInterpreterState(tree, variableRanges);
    106       var outputInterval = Evaluate(instructions, ref instructionCount, intervals);
    107 
    108       // fix incorrect intervals if necessary (could occur because of numerical errors)
     120
     121      Interval outputInterval;
     122      var instructionCount = 0;
     123      outputInterval = Evaluate(instructions, ref instructionCount, intervals);
     124
    109125      nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>();
    110126      foreach (var kvp in intervals) {
     
    119135      if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound)
    120136        return outputInterval;
    121       else
    122         return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
    123     }
    124 
    125 
    126     private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IDictionary<string, Interval> variableRanges) {
     137
     138      return new Interval(outputInterval.UpperBound, outputInterval.LowerBound);
     139    }
     140
     141
     142    private static Instruction[] PrepareInterpreterState(
     143      ISymbolicExpressionTree tree,
     144      IReadOnlyDictionary<string, Interval> variableRanges) {
    127145      if (variableRanges == null)
    128146        throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges));
    129147
    130       //Check if all variables used in the tree are present in the dataset
    131       foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) {
    132         if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present");
    133       }
    134 
    135       Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    136       foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) {
     148      // Check if all variables used in the tree are present in the dataset
     149      foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName)
     150                                   .Distinct())
     151        if (!variableRanges.ContainsKey(variable))
     152          throw new InvalidOperationException($"No ranges for variable {variable} is present");
     153
     154      var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
     155      foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) {
    137156        var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    138157        instr.data = variableRanges[variableTreeNode.VariableName];
    139158      }
     159
    140160      return code;
    141161    }
    142162
    143     private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) {
    144       Instruction currentInstr = instructions[instructionCounter];
    145       //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
    146       //Update instructionCounter, whenever Evaluate is called
     163    // Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side
     164    // Update instructionCounter, whenever Evaluate is called
     165    public static Interval Evaluate(
     166    Instruction[] instructions, ref int instructionCounter,
     167      IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null,
     168      IReadOnlyDictionary<string, Interval> variableIntervals = null) {
     169      var currentInstr = instructions[instructionCounter];
     170
    147171      instructionCounter++;
    148       Interval result = null;
     172      Interval result;
    149173
    150174      switch (currentInstr.opCode) {
    151         //Variables, Constants, ...
    152175        case OpCodes.Variable: {
    153176            var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
    154177            var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight);
    155             var variableInterval = (Interval)currentInstr.data;
     178
     179            Interval variableInterval;
     180            if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName))
     181              variableInterval = variableIntervals[variableTreeNode.VariableName];
     182            else
     183              variableInterval = (Interval)currentInstr.data;
    156184
    157185            result = Interval.Multiply(variableInterval, weightInterval);
     
    163191            break;
    164192          }
    165         //Elementary arithmetic rules
    166193        case OpCodes.Add: {
    167             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    168             for (int i = 1; i < currentInstr.nArguments; i++) {
    169               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     194            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     195            for (var i = 1; i < currentInstr.nArguments; i++) {
     196              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    170197              result = Interval.Add(result, argumentInterval);
    171198            }
     199
    172200            break;
    173201          }
    174202        case OpCodes.Sub: {
    175             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     203            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    176204            if (currentInstr.nArguments == 1)
    177205              result = Interval.Multiply(new Interval(-1, -1), result);
    178206
    179             for (int i = 1; i < currentInstr.nArguments; i++) {
    180               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     207            for (var i = 1; i < currentInstr.nArguments; i++) {
     208              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    181209              result = Interval.Subtract(result, argumentInterval);
    182210            }
     211
    183212            break;
    184213          }
    185214        case OpCodes.Mul: {
    186             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    187             for (int i = 1; i < currentInstr.nArguments; i++) {
    188               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     215            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     216            for (var i = 1; i < currentInstr.nArguments; i++) {
     217              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    189218              result = Interval.Multiply(result, argumentInterval);
    190219            }
     220
    191221            break;
    192222          }
    193223        case OpCodes.Div: {
    194             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     224            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    195225            if (currentInstr.nArguments == 1)
    196226              result = Interval.Divide(new Interval(1, 1), result);
    197227
    198             for (int i = 1; i < currentInstr.nArguments; i++) {
    199               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     228            for (var i = 1; i < currentInstr.nArguments; i++) {
     229              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    200230              result = Interval.Divide(result, argumentInterval);
    201231            }
    202             break;
    203           }
    204         //Trigonometric functions
     232
     233            break;
     234          }
    205235        case OpCodes.Sin: {
    206             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     236            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    207237            result = Interval.Sine(argumentInterval);
    208238            break;
    209239          }
    210240        case OpCodes.Cos: {
    211             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     241            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    212242            result = Interval.Cosine(argumentInterval);
    213243            break;
    214244          }
    215245        case OpCodes.Tan: {
    216             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     246            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    217247            result = Interval.Tangens(argumentInterval);
    218248            break;
    219249          }
    220250        case OpCodes.Tanh: {
    221             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     251            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    222252            result = Interval.HyperbolicTangent(argumentInterval);
    223253            break;
    224254          }
    225         //Exponential functions
    226255        case OpCodes.Log: {
    227             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     256            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    228257            result = Interval.Logarithm(argumentInterval);
    229258            break;
    230259          }
    231260        case OpCodes.Exp: {
    232             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     261            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    233262            result = Interval.Exponential(argumentInterval);
    234263            break;
    235264          }
    236         case OpCodes.Power: {
    237             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    238             for (int i = 1; i < currentInstr.nArguments; i++) {
    239               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    240               result = Interval.Power(result, argumentInterval);
    241             }
    242             break;
    243           }
    244265        case OpCodes.Square: {
    245             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     266            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    246267            result = Interval.Square(argumentInterval);
    247268            break;
    248269          }
    249         case OpCodes.Root: {
    250             result = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    251             for (int i = 1; i < currentInstr.nArguments; i++) {
    252               var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
    253               result = Interval.Root(result, argumentInterval);
    254             }
    255             break;
    256           }
    257270        case OpCodes.SquareRoot: {
    258             var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);
     271            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
    259272            result = Interval.SquareRoot(argumentInterval);
     273            break;
     274          }
     275        case OpCodes.Cube: {
     276            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     277            result = Interval.Cube(argumentInterval);
     278            break;
     279          }
     280        case OpCodes.CubeRoot: {
     281            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     282            result = Interval.CubicRoot(argumentInterval);
     283            break;
     284          }
     285        case OpCodes.Absolute: {
     286            var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     287            result = Interval.Absolute(argumentInterval);
     288            break;
     289          }
     290        case OpCodes.AnalyticQuotient: {
     291            result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     292            for (var i = 1; i < currentInstr.nArguments; i++) {
     293              var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals);
     294              result = Interval.AnalyticQuotient(result, argumentInterval);
     295            }
     296
    260297            break;
    261298          }
     
    264301      }
    265302
    266       if (nodeIntervals != null)
     303      if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode)))
    267304        nodeIntervals.Add(currentInstr.dynamicNode, result);
    268305
     
    270307    }
    271308
     309
    272310    public static bool IsCompatible(ISymbolicExpressionTree tree) {
    273       var containsUnknownSyumbol = (
     311      var containsUnknownSymbols = (
    274312        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
    275313        where
     314          !(n.Symbol is Variable) &&
     315          !(n.Symbol is Constant) &&
    276316          !(n.Symbol is StartSymbol) &&
    277317          !(n.Symbol is Addition) &&
     
    282322          !(n.Symbol is Cosine) &&
    283323          !(n.Symbol is Tangent) &&
     324          !(n.Symbol is HyperbolicTangent) &&
    284325          !(n.Symbol is Logarithm) &&
    285326          !(n.Symbol is Exponential) &&
    286           !(n.Symbol is Power) &&
    287327          !(n.Symbol is Square) &&
    288           !(n.Symbol is Root) &&
    289328          !(n.Symbol is SquareRoot) &&
    290           !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) &&
    291           !(n.Symbol is Constant)
     329          !(n.Symbol is Cube) &&
     330          !(n.Symbol is CubeRoot) &&
     331          !(n.Symbol is Absolute) &&
     332          !(n.Symbol is AnalyticQuotient)
    292333        select n).Any();
    293       return !containsUnknownSyumbol;
     334      return !containsUnknownSymbols;
    294335    }
    295336  }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r17180 r17928  
    5252    private static readonly MethodInfo Log = typeof(Math).GetMethod("Log", new[] { typeof(double) });
    5353    private static readonly MethodInfo IsNaN = typeof(double).GetMethod("IsNaN");
    54     private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost");
     54    private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost", new Type[] { typeof(double), typeof(double)});
    5555    private static readonly MethodInfo Gamma = typeof(alglib).GetMethod("gammafunction", new[] { typeof(double) });
    5656    private static readonly MethodInfo Psi = typeof(alglib).GetMethod("psi", new[] { typeof(double) });
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs

    r16768 r17928  
    1 using System;
     1#region License Information
     2/* HeuristicLab
     3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     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;
    223using System.Collections.Generic;
    324using System.Linq;
     
    181202
    182203    [ThreadStatic]
    183     private Dictionary<string, double[]> cachedData;
     204    private static Dictionary<string, double[]> cachedData;
    184205
    185206    [ThreadStatic]
    186     private IDataset dataset;
     207    private static IDataset cachedDataset;
    187208
    188209    private void InitCache(IDataset dataset) {
    189       this.dataset = dataset;
     210      cachedDataset = dataset;
    190211      cachedData = new Dictionary<string, double[]>();
    191212      foreach (var v in dataset.DoubleVariables) {
     
    196217    public void InitializeState() {
    197218      cachedData = null;
    198       dataset = null;
     219      cachedDataset = null;
    199220      EvaluatedSolutions = 0;
    200221    }
    201222
    202223    private double[] GetValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) {
    203       if (cachedData == null || this.dataset != dataset) {
     224      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    204225        InitCache(dataset);
    205226      }
  • branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs

    r17180 r17928  
    9999
    100100    [ThreadStatic]
    101     private IDataset dataset;
     101    private static IDataset cachedDataset;
    102102
    103103    private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() {
     
    127127      if (!rows.Any()) return Enumerable.Empty<double>();
    128128
    129       if (cachedData == null || this.dataset != dataset) {
     129      if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) {
    130130        InitCache(dataset);
    131131      }
     
    152152
    153153    private void InitCache(IDataset dataset) {
    154       this.dataset = dataset;
     154      cachedDataset = dataset;
    155155
    156156      // free handles to old data
     
    178178        cachedData = null;
    179179      }
    180       dataset = null;
     180      cachedDataset = null;
    181181      EvaluatedSolutions = 0;
    182182    }
Note: See TracChangeset for help on using the changeset viewer.