Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/26/13 13:15:05 (11 years ago)
Author:
bburlacu
Message:

#2021: Added support for lagged symbols: TimeLag, Derivative, Integral.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs

    r9758 r9776  
    3737    private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
    3838
     39    private SymbolicDataAnalysisExpressionTreeInterpreter interpreter;
     40
    3941    public override bool CanChangeName {
    4042      get { return false; }
     
    7476      SymbolicDataAnalysisExpressionTreeLinearInterpreter original, Cloner cloner)
    7577      : base(original, cloner) {
     78      interpreter = original.interpreter;
    7679    }
    7780
     
    8487      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)));
    8588      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     89      interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
    8690    }
    8791
     
    9094      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)));
    9195      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     96      interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
    9297    }
    9398
     
    96101      if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
    97102        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     103      if (interpreter == null) interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
    98104    }
    99105
     
    122128    }
    123129
     130    private static LinearInstruction[] GetPrefixSequence(LinearInstruction[] code, int startIndex) {
     131      var instr = code[startIndex];
     132      var list = new List<LinearInstruction> { instr };
     133      for (int i = 0; i != instr.nArguments; ++i) {
     134        list.AddRange(GetPrefixSequence(code, instr.childIndex + i));
     135      }
     136      return list.ToArray();
     137    }
     138
    124139    private static void PrepareInstructions(LinearInstruction[] code, Dataset dataset) {
    125       for (int i = code.Length - 1; i >= 0; --i) {
     140      Action<LinearInstruction> setSkip = null;
     141      setSkip = instruction => {
     142        instruction.skip = true;
     143        for (int j = 0; j != instruction.nArguments; ++j) {
     144          setSkip(code[instruction.childIndex + j]);
     145        }
     146      };
     147
     148      for (int i = 0; i != code.Length; ++i) {
    126149        var instr = code[i];
    127150        #region opcode switch
     
    130153              var constTreeNode = (ConstantTreeNode)instr.dynamicNode;
    131154              instr.value = constTreeNode.Value;
     155              instr.skip = true; // the value is already set so this instruction should be skipped in the evaluation phase
    132156            }
    133157            break;
     
    147171            }
    148172            break;
     173          case OpCodes.TimeLag:
     174          case OpCodes.Integral:
     175          case OpCodes.Derivative: {
     176              for (int j = 0; j != instr.nArguments; ++j) {
     177                setSkip(code[instr.childIndex + j]);
     178              }
     179            }
     180            break;
    149181        }
    150182        #endregion
     
    152184    }
    153185
    154     private static double Evaluate(Dataset dataset, ref int row, LinearInstruction[] code) {
     186    private double Evaluate(Dataset dataset, ref int row, LinearInstruction[] code) {
    155187      for (int i = code.Length - 1; i >= 0; --i) {
    156         if (code[i].opCode == OpCodes.Constant) continue;
     188        if (code[i].skip) continue;
    157189        #region opcode switch
    158190        var instr = code[i];
     
    304336              else {
    305337                alglib.sinecosineintegrals(x, out si, out ci);
    306                 instr.value = si;
     338                instr.value = ci;
    307339              }
    308340            }
     
    431463            }
    432464            break;
     465          case OpCodes.TimeLag:
     466          case OpCodes.Integral:
     467          case OpCodes.Derivative: {
     468              if (instr.iArg0 == null) {
     469                instr.iArg0 = GetPrefixSequence(code, i); ;
     470              }
     471              var interpreterState = new InterpreterState((LinearInstruction[])instr.iArg0, 0);
     472              instr.value = interpreter.Evaluate(dataset, ref row, interpreterState);
     473            }
     474            break;
    433475          default:
    434476            var errorText = string.Format("The {0} symbol is not supported by the linear interpreter. To support this symbol, please use another interpreter.", instr.dynamicNode.Symbol.Name);
Note: See TracChangeset for help on using the changeset viewer.