Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/19/20 19:07:40 (4 years ago)
Author:
fbaching
Message:

#1837: merged changes from trunk

  • apply changes from Attic release to all SlidingWindow specific code files (replace StorableClass with StorableType)
Location:
branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/1837_Sliding Window GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r9870 r17687  
    11#region License Information
    22/* HeuristicLab
    3  * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
    44 *
    55 * This file is part of HeuristicLab.
     
    2727using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2828using HeuristicLab.Parameters;
    29 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     29using HEAL.Attic;
    3030
    3131namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
    32   [StorableClass]
     32  [StorableType("FB94F333-B32A-44FB-A561-CBDE76693D20")]
    3333  [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
    34   public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
     34  public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem,
     35    ISymbolicDataAnalysisExpressionTreeInterpreter {
    3536    private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     37    private const string CheckExpressionsWithIntervalArithmeticParameterDescription = "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.";
    3638    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
    3739
    38     public override bool CanChangeName { get { return false; } }
    39     public override bool CanChangeDescription { get { return false; } }
     40    public override bool CanChangeName {
     41      get { return false; }
     42    }
     43
     44    public override bool CanChangeDescription {
     45      get { return false; }
     46    }
    4047
    4148    #region parameter properties
    42     public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
    43       get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
    44     }
    45 
    46     public IValueParameter<IntValue> EvaluatedSolutionsParameter {
    47       get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
     49    public IFixedValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter {
     50      get { return (IFixedValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
     51    }
     52
     53    public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter {
     54      get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
    4855    }
    4956    #endregion
    5057
    5158    #region properties
    52     public BoolValue CheckExpressionsWithIntervalArithmetic {
    53       get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
    54       set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
    55     }
    56 
    57     public IntValue EvaluatedSolutions {
    58       get { return EvaluatedSolutionsParameter.Value; }
    59       set { EvaluatedSolutionsParameter.Value = value; }
     59    public bool CheckExpressionsWithIntervalArithmetic {
     60      get { return CheckExpressionsWithIntervalArithmeticParameter.Value.Value; }
     61      set { CheckExpressionsWithIntervalArithmeticParameter.Value.Value = value; }
     62    }
     63
     64    public int EvaluatedSolutions {
     65      get { return EvaluatedSolutionsParameter.Value.Value; }
     66      set { EvaluatedSolutionsParameter.Value.Value = value; }
    6067    }
    6168    #endregion
    6269
    6370    [StorableConstructor]
    64     protected SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
    65     protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
     71    protected SymbolicDataAnalysisExpressionTreeInterpreter(StorableConstructorFlag _) : base(_) { }
     72
     73    protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original,
     74      Cloner cloner)
     75      : base(original, cloner) { }
     76
    6677    public override IDeepCloneable Clone(Cloner cloner) {
    6778      return new SymbolicDataAnalysisExpressionTreeInterpreter(this, cloner);
     
    7081    public SymbolicDataAnalysisExpressionTreeInterpreter()
    7182      : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") {
    72       Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
    73       Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     83      Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
     84      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
    7485    }
    7586
    7687    protected SymbolicDataAnalysisExpressionTreeInterpreter(string name, string description)
    7788      : base(name, description) {
    78       Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
    79       Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     89      Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
     90      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
    8091    }
    8192
    8293    [StorableHook(HookType.AfterDeserialization)]
    8394    private void AfterDeserialization() {
    84       if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
    85         Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     95      var evaluatedSolutions = new IntValue(0);
     96      var checkExpressionsWithIntervalArithmetic = new BoolValue(false);
     97      if (Parameters.ContainsKey(EvaluatedSolutionsParameterName)) {
     98        var evaluatedSolutionsParameter = (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName];
     99        evaluatedSolutions = evaluatedSolutionsParameter.Value;
     100        Parameters.Remove(EvaluatedSolutionsParameterName);
     101      }
     102      Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", evaluatedSolutions));
     103      if (Parameters.ContainsKey(CheckExpressionsWithIntervalArithmeticParameterName)) {
     104        var checkExpressionsWithIntervalArithmeticParameter = (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName];
     105        Parameters.Remove(CheckExpressionsWithIntervalArithmeticParameterName);
     106        checkExpressionsWithIntervalArithmetic = checkExpressionsWithIntervalArithmeticParameter.Value;
     107      }
     108      Parameters.Add(new FixedValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, CheckExpressionsWithIntervalArithmeticParameterDescription, checkExpressionsWithIntervalArithmetic));
    86109    }
    87110
    88111    #region IStatefulItem
    89112    public void InitializeState() {
    90       EvaluatedSolutions.Value = 0;
    91     }
    92 
    93     public void ClearState() {
    94     }
     113      EvaluatedSolutions = 0;
     114    }
     115
     116    public void ClearState() { }
    95117    #endregion
    96118
    97     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
    98       if (CheckExpressionsWithIntervalArithmetic.Value)
     119    private readonly object syncRoot = new object();
     120    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset,
     121      IEnumerable<int> rows) {
     122      if (CheckExpressionsWithIntervalArithmetic) {
    99123        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
    100 
    101       lock (EvaluatedSolutions) {
    102         EvaluatedSolutions.Value++; // increment the evaluated solutions counter
     124      }
     125
     126      lock (syncRoot) {
     127        EvaluatedSolutions++; // increment the evaluated solutions counter
    103128      }
    104129      var state = PrepareInterpreterState(tree, dataset);
     
    111136    }
    112137
    113     private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
     138    private static InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, IDataset dataset) {
    114139      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
    115140      int necessaryArgStackSize = 0;
     
    118143          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
    119144          instr.data = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
     145        } else if (instr.opCode == OpCodes.FactorVariable) {
     146          var factorTreeNode = instr.dynamicNode as FactorVariableTreeNode;
     147          instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName);
     148        } else if (instr.opCode == OpCodes.BinaryFactorVariable) {
     149          var factorTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode;
     150          instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName);
    120151        } else if (instr.opCode == OpCodes.LagVariable) {
    121152          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
     
    131162    }
    132163
    133 
    134     public virtual double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
     164    public virtual double Evaluate(IDataset dataset, ref int row, InterpreterState state) {
    135165      Instruction currentInstr = state.NextInstruction();
    136166      switch (currentInstr.opCode) {
     
    147177              s -= Evaluate(dataset, ref row, state);
    148178            }
    149             if (currentInstr.nArguments == 1) s = -s;
     179            if (currentInstr.nArguments == 1) { s = -s; }
    150180            return s;
    151181          }
     
    162192              p /= Evaluate(dataset, ref row, state);
    163193            }
    164             if (currentInstr.nArguments == 1) p = 1.0 / p;
     194            if (currentInstr.nArguments == 1) { p = 1.0 / p; }
    165195            return p;
    166196          }
     
    172202            return sum / currentInstr.nArguments;
    173203          }
     204        case OpCodes.Absolute: {
     205            return Math.Abs(Evaluate(dataset, ref row, state));
     206          }
     207        case OpCodes.Tanh: {
     208            return Math.Tanh(Evaluate(dataset, ref row, state));
     209          }
    174210        case OpCodes.Cos: {
    175211            return Math.Cos(Evaluate(dataset, ref row, state));
     
    183219        case OpCodes.Square: {
    184220            return Math.Pow(Evaluate(dataset, ref row, state), 2);
     221          }
     222        case OpCodes.Cube: {
     223            return Math.Pow(Evaluate(dataset, ref row, state), 3);
    185224          }
    186225        case OpCodes.Power: {
     
    192231            return Math.Sqrt(Evaluate(dataset, ref row, state));
    193232          }
     233        case OpCodes.CubeRoot: {
     234            var arg = Evaluate(dataset, ref row, state);
     235            return arg < 0 ? -Math.Pow(-arg, 1.0 / 3.0) : Math.Pow(arg, 1.0 / 3.0);
     236          }
    194237        case OpCodes.Root: {
    195238            double x = Evaluate(dataset, ref row, state);
     
    205248        case OpCodes.Gamma: {
    206249            var x = Evaluate(dataset, ref row, state);
    207             if (double.IsNaN(x)) return double.NaN;
    208             else return alglib.gammafunction(x);
     250            if (double.IsNaN(x)) { return double.NaN; } else { return alglib.gammafunction(x); }
    209251          }
    210252        case OpCodes.Psi: {
     
    216258        case OpCodes.Dawson: {
    217259            var x = Evaluate(dataset, ref row, state);
    218             if (double.IsNaN(x)) return double.NaN;
     260            if (double.IsNaN(x)) { return double.NaN; }
    219261            return alglib.dawsonintegral(x);
    220262          }
    221263        case OpCodes.ExponentialIntegralEi: {
    222264            var x = Evaluate(dataset, ref row, state);
    223             if (double.IsNaN(x)) return double.NaN;
     265            if (double.IsNaN(x)) { return double.NaN; }
    224266            return alglib.exponentialintegralei(x);
    225267          }
     
    310352            if (double.IsNaN(x)) return double.NaN;
    311353            else return alglib.besseli0(x);
     354          }
     355
     356        case OpCodes.AnalyticQuotient: {
     357            var x1 = Evaluate(dataset, ref row, state);
     358            var x2 = Evaluate(dataset, ref row, state);
     359            return x1 / Math.Pow(1 + x2 * x2, 0.5);
    312360          }
    313361        case OpCodes.IfThenElse: {
     
    344392            return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
    345393          }
     394        case OpCodes.XOR: {
     395            //mkommend: XOR on multiple inputs is defined as true if the number of positive signals is odd
     396            // this is equal to a consecutive execution of binary XOR operations.
     397            int positiveSignals = 0;
     398            for (int i = 0; i < currentInstr.nArguments; i++) {
     399              if (Evaluate(dataset, ref row, state) > 0.0) { positiveSignals++; }
     400            }
     401            return positiveSignals % 2 != 0 ? 1.0 : -1.0;
     402          }
    346403        case OpCodes.GT: {
    347404            double x = Evaluate(dataset, ref row, state);
    348405            double y = Evaluate(dataset, ref row, state);
    349             if (x > y) return 1.0;
    350             else return -1.0;
     406            if (x > y) { return 1.0; } else { return -1.0; }
    351407          }
    352408        case OpCodes.LT: {
    353409            double x = Evaluate(dataset, ref row, state);
    354410            double y = Evaluate(dataset, ref row, state);
    355             if (x < y) return 1.0;
    356             else return -1.0;
     411            if (x < y) { return 1.0; } else { return -1.0; }
    357412          }
    358413        case OpCodes.TimeLag: {
     
    425480            return ((IList<double>)currentInstr.data)[row] * variableTreeNode.Weight;
    426481          }
     482        case OpCodes.BinaryFactorVariable: {
     483            if (row < 0 || row >= dataset.Rows) return double.NaN;
     484            var factorVarTreeNode = currentInstr.dynamicNode as BinaryFactorVariableTreeNode;
     485            return ((IList<string>)currentInstr.data)[row] == factorVarTreeNode.VariableValue ? factorVarTreeNode.Weight : 0;
     486          }
     487        case OpCodes.FactorVariable: {
     488            if (row < 0 || row >= dataset.Rows) return double.NaN;
     489            var factorVarTreeNode = currentInstr.dynamicNode as FactorVariableTreeNode;
     490            return factorVarTreeNode.GetValue(((IList<string>)currentInstr.data)[row]);
     491          }
    427492        case OpCodes.LagVariable: {
    428493            var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
    429494            int actualRow = row + laggedVariableTreeNode.Lag;
    430             if (actualRow < 0 || actualRow >= dataset.Rows) return double.NaN;
     495            if (actualRow < 0 || actualRow >= dataset.Rows) { return double.NaN; }
    431496            return ((IList<double>)currentInstr.data)[actualRow] * laggedVariableTreeNode.Weight;
    432497          }
     
    441506            if (row < 0 || row >= dataset.Rows) return double.NaN;
    442507            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
    443             double variableValue = ((IList<double>)currentInstr.data)[row];
    444             double x = variableValue - variableConditionTreeNode.Threshold;
    445             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    446 
    447             double trueBranch = Evaluate(dataset, ref row, state);
    448             double falseBranch = Evaluate(dataset, ref row, state);
    449 
    450             return trueBranch * p + falseBranch * (1 - p);
    451           }
    452         default: throw new NotSupportedException();
     508            if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     509              double variableValue = ((IList<double>)currentInstr.data)[row];
     510              double x = variableValue - variableConditionTreeNode.Threshold;
     511              double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     512
     513              double trueBranch = Evaluate(dataset, ref row, state);
     514              double falseBranch = Evaluate(dataset, ref row, state);
     515
     516              return trueBranch * p + falseBranch * (1 - p);
     517            } else {
     518              // strict threshold
     519              double variableValue = ((IList<double>)currentInstr.data)[row];
     520              if (variableValue <= variableConditionTreeNode.Threshold) {
     521                var left = Evaluate(dataset, ref row, state);
     522                state.SkipInstructions();
     523                return left;
     524              } else {
     525                state.SkipInstructions();
     526                return Evaluate(dataset, ref row, state);
     527              }
     528            }
     529          }
     530        default:
     531          throw new NotSupportedException();
    453532      }
    454533    }
Note: See TracChangeset for help on using the changeset viewer.