Changeset 16215


Ignore:
Timestamp:
10/08/18 08:17:03 (14 months ago)
Author:
gkronber
Message:

#2925: added sin and cos functions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs

    r16214 r16215  
    4343
    4444    public static Vector operator +(Vector a, Vector b) {
    45       if(a == Zero) return b;
    46       if(b == Zero) return a;
     45      if (a == Zero) return b;
     46      if (b == Zero) return a;
    4747      Debug.Assert(a.arr.Length == b.arr.Length);
    4848      var res = new double[a.arr.Length];
    49       for(int i = 0; i < res.Length; i++)
     49      for (int i = 0; i < res.Length; i++)
    5050        res[i] = a.arr[i] + b.arr[i];
    5151      return new Vector(res);
    5252    }
    5353    public static Vector operator -(Vector a, Vector b) {
    54       if(b == Zero) return a;
    55       if(a == Zero) return -b;
     54      if (b == Zero) return a;
     55      if (a == Zero) return -b;
    5656      Debug.Assert(a.arr.Length == b.arr.Length);
    5757      var res = new double[a.arr.Length];
    58       for(int i = 0; i < res.Length; i++)
     58      for (int i = 0; i < res.Length; i++)
    5959        res[i] = a.arr[i] - b.arr[i];
    6060      return new Vector(res);
    6161    }
    6262    public static Vector operator -(Vector v) {
    63       if(v == Zero) return Zero;
    64       for(int i = 0; i < v.arr.Length; i++)
     63      if (v == Zero) return Zero;
     64      for (int i = 0; i < v.arr.Length; i++)
    6565        v.arr[i] = -v.arr[i];
    6666      return v;
     
    6868
    6969    public static Vector operator *(double s, Vector v) {
    70       if(v == Zero) return Zero;
    71       if(s == 0.0) return Zero;
     70      if (v == Zero) return Zero;
     71      if (s == 0.0) return Zero;
    7272      var res = new double[v.arr.Length];
    73       for(int i = 0; i < res.Length; i++)
     73      for (int i = 0; i < res.Length; i++)
    7474        res[i] = s * v.arr[i];
    7575      return new Vector(res);
    7676    }
     77
    7778    public static Vector operator *(Vector v, double s) {
    7879      return s * v;
    7980    }
     81    public static Vector operator *(Vector u, Vector v) {
     82      if (v == Zero) return Zero;
     83      if (u == Zero) return Zero;
     84      var res = new double[v.arr.Length];
     85      for (int i = 0; i < res.Length; i++)
     86        res[i] = u.arr[i] * v.arr[i];
     87      return new Vector(res);
     88    }
    8089    public static Vector operator /(double s, Vector v) {
    81       if(s == 0.0) return Zero;
    82       if(v == Zero) throw new ArgumentException("Division by zero vector");
     90      if (s == 0.0) return Zero;
     91      if (v == Zero) throw new ArgumentException("Division by zero vector");
    8392      var res = new double[v.arr.Length];
    84       for(int i = 0; i < res.Length; i++)
     93      for (int i = 0; i < res.Length; i++)
    8594        res[i] = 1.0 / v.arr[i];
    8695      return new Vector(res);
     
    9099    }
    91100
     101    public static Vector Sin(Vector s) {
     102      var res = new double[s.arr.Length];
     103      for (int i = 0; i < res.Length; i++) res[i] = Math.Sin(s.arr[i]);
     104      return new Vector(res);
     105    }
     106    public static Vector Cos(Vector s) {
     107      var res = new double[s.arr.Length];
     108      for (int i = 0; i < res.Length; i++) res[i] = Math.Cos(s.arr[i]);
     109      return new Vector(res);
     110    }
    92111
    93112    private readonly double[] arr; // backing array;
     
    200219    [StorableHook(HookType.AfterDeserialization)]
    201220    private void AfterDeserialization() {
    202       if(!Parameters.ContainsKey(OptimizeParametersForEpisodesParameterName)) {
     221      if (!Parameters.ContainsKey(OptimizeParametersForEpisodesParameterName)) {
    203222        Parameters.Add(new FixedValueParameter<BoolValue>(OptimizeParametersForEpisodesParameterName, "Flag to select if parameters should be optimized globally or for each episode individually.", new BoolValue(false)));
    204223      }
     
    232251      // TODO: do not clear selection of target variables when the input variables are changed (keep selected target variables)
    233252      // TODO: UI hangs when selecting / deselecting input variables because the encoding is updated on each item
     253      // TODO: use training range as default training episode
    234254
    235255    }
     
    238258      var trees = individual.Values.Select(v => v.Value).OfType<ISymbolicExpressionTree>().ToArray(); // extract all trees from individual
    239259
    240       if(OptimizeParametersForEpisodes) {
    241         int eIdx = 0; 
     260      if (OptimizeParametersForEpisodes) {
     261        int eIdx = 0;
    242262        double totalNMSE = 0.0;
    243263        int totalSize = 0;
    244         foreach(var episode in TrainingEpisodes) {
     264        foreach (var episode in TrainingEpisodes) {
    245265          double[] optTheta;
    246266          double nmse;
     
    270290      // collect values of all target variables
    271291      var colIdx = 0;
    272       foreach(var targetVar in targetVars) {
     292      foreach (var targetVar in targetVars) {
    273293        int rowIdx = 0;
    274         foreach(var value in problemData.Dataset.GetDoubleValues(targetVar, rows)) {
     294        foreach (var value in problemData.Dataset.GetDoubleValues(targetVar, rows)) {
    275295          targetValues[rowIdx, colIdx] = value;
    276296          rowIdx++;
     
    281301      var nodeIdx = new Dictionary<ISymbolicExpressionTreeNode, int>();
    282302
    283       foreach(var tree in trees) {
    284         foreach(var node in tree.Root.IterateNodesPrefix().Where(n => IsConstantNode(n))) {
     303      foreach (var tree in trees) {
     304        foreach (var node in tree.Root.IterateNodesPrefix().Where(n => IsConstantNode(n))) {
    285305          nodeIdx.Add(node, nodeIdx.Count);
    286306        }
     
    290310
    291311      optTheta = new double[0];
    292       if(theta.Length > 0) {
     312      if (theta.Length > 0) {
    293313        alglib.minlbfgsstate state;
    294314        alglib.minlbfgsreport report;
     
    325345                          * NFEV countains number of function calculations
    326346         */
    327         if(report.terminationtype < 0) { nmse = 10E6; return; }
     347        if (report.terminationtype < 0) { nmse = 10E6; return; }
    328348      }
    329349
     
    333353      EvaluateObjectiveAndGradient(optTheta, ref nmse, grad,
    334354        new object[] { trees, targetVars, problemData, nodeIdx, targetValues, episodes.ToArray(), NumericIntegrationSteps, latentVariables });
    335       if(double.IsNaN(nmse) || double.IsInfinity(nmse)) { nmse = 10E6; return; } // return a large value (TODO: be consistent by using NMSE)
     355      if (double.IsNaN(nmse) || double.IsInfinity(nmse)) { nmse = 10E6; return; } // return a large value (TODO: be consistent by using NMSE)
    336356    }
    337357
     
    371391      var g = Vector.Zero;
    372392      int r = 0;
    373       foreach(var y_pred in predicted) {
    374         for(int c = 0; c < y_pred.Length; c++) {
     393      foreach (var y_pred in predicted) {
     394        for (int c = 0; c < y_pred.Length; c++) {
    375395
    376396          var y_pred_f = y_pred[c].Item1;
     
    391411      base.Analyze(individuals, qualities, results, random);
    392412
    393       if(!results.ContainsKey("Prediction (training)")) {
     413      if (!results.ContainsKey("Prediction (training)")) {
    394414        results.Add(new Result("Prediction (training)", typeof(ReadOnlyItemList<DataTable>)));
    395415      }
    396       if(!results.ContainsKey("Prediction (test)")) {
     416      if (!results.ContainsKey("Prediction (test)")) {
    397417        results.Add(new Result("Prediction (test)", typeof(ReadOnlyItemList<DataTable>)));
    398418      }
    399       if(!results.ContainsKey("Models")) {
     419      if (!results.ContainsKey("Models")) {
    400420        results.Add(new Result("Models", typeof(VariableCollection)));
    401421      }
     
    406426      // TODO extract common functionality from Evaluate and Analyze
    407427      var nodeIdx = new Dictionary<ISymbolicExpressionTreeNode, int>();
    408       foreach(var tree in trees) {
    409         foreach(var node in tree.Root.IterateNodesPrefix().Where(n => IsConstantNode(n))) {
     428      foreach (var tree in trees) {
     429        foreach (var node in tree.Root.IterateNodesPrefix().Where(n => IsConstantNode(n))) {
    410430          nodeIdx.Add(node, nodeIdx.Count);
    411431        }
     
    417437      var trainingList = new ItemList<DataTable>();
    418438
    419       if(OptimizeParametersForEpisodes) {
     439      if (OptimizeParametersForEpisodes) {
    420440        var eIdx = 0;
    421441        var trainingPredictions = new List<Tuple<double, Vector>[][]>();
    422         foreach(var episode in TrainingEpisodes) {
     442        foreach (var episode in TrainingEpisodes) {
    423443          var episodes = new[] { episode };
    424444          var optTheta = ((DoubleArray)bestIndividualAndQuality.Item1["OptTheta_" + eIdx]).ToArray(); // see evaluate
     
    439459        // only for actual target values
    440460        var trainingRows = TrainingEpisodes.SelectMany(e => Enumerable.Range(e.Start, e.End - e.Start));
    441         for(int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
     461        for (int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
    442462          var targetVar = targetVars[colIdx];
    443463          var trainingDataTable = new DataTable(targetVar + " prediction (training)");
     
    453473        var models = new VariableCollection();
    454474
    455         foreach(var tup in targetVars.Zip(trees, Tuple.Create)) {
     475        foreach (var tup in targetVars.Zip(trees, Tuple.Create)) {
    456476          var targetVarName = tup.Item1;
    457477          var tree = tup.Item2;
     
    476496        // only for actual target values
    477497        var trainingRows = TrainingEpisodes.SelectMany(e => Enumerable.Range(e.Start, e.End - e.Start));
    478         for(int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
     498        for (int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
    479499          var targetVar = targetVars[colIdx];
    480500          var trainingDataTable = new DataTable(targetVar + " prediction (training)");
     
    499519         NumericIntegrationSteps).ToArray();
    500520
    501         for(int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
     521        for (int colIdx = 0; colIdx < targetVars.Length; colIdx++) {
    502522          var targetVar = targetVars[colIdx];
    503523          var testDataTable = new DataTable(targetVar + " prediction (test)");
     
    515535        var models = new VariableCollection();    // to store target var names and original version of tree
    516536
    517         foreach(var tup in targetVars.Zip(trees, Tuple.Create)) {
     537        foreach (var tup in targetVars.Zip(trees, Tuple.Create)) {
    518538          var targetVarName = tup.Item1;
    519539          var tree = tup.Item2;
     
    553573    private ISymbolicExpressionTreeNode TranslateTreeNode(ISymbolicExpressionTreeNode n, double[] parameterValues, ref int nextParIdx) {
    554574      ISymbolicExpressionTreeNode translatedNode = null;
    555       if(n.Symbol is StartSymbol) {
     575      if (n.Symbol is StartSymbol) {
    556576        translatedNode = new StartSymbol().CreateTreeNode();
    557       } else if(n.Symbol is ProgramRootSymbol) {
     577      } else if (n.Symbol is ProgramRootSymbol) {
    558578        translatedNode = new ProgramRootSymbol().CreateTreeNode();
    559       } else if(n.Symbol.Name == "+") {
     579      } else if (n.Symbol.Name == "+") {
    560580        translatedNode = new Addition().CreateTreeNode();
    561       } else if(n.Symbol.Name == "-") {
     581      } else if (n.Symbol.Name == "-") {
    562582        translatedNode = new Subtraction().CreateTreeNode();
    563       } else if(n.Symbol.Name == "*") {
     583      } else if (n.Symbol.Name == "*") {
    564584        translatedNode = new Multiplication().CreateTreeNode();
    565       } else if(n.Symbol.Name == "%") {
     585      } else if (n.Symbol.Name == "%") {
    566586        translatedNode = new Division().CreateTreeNode();
    567       } else if(IsConstantNode(n)) {
     587      } else if (n.Symbol.Name == "sin") {
     588        translatedNode = new Sine().CreateTreeNode();
     589      } else if (n.Symbol.Name == "cos") {
     590        translatedNode = new Cosine().CreateTreeNode();
     591      } else if (IsConstantNode(n)) {
    568592        var constNode = (ConstantTreeNode)new Constant().CreateTreeNode();
    569593        constNode.Value = parameterValues[nextParIdx];
     
    578602        translatedNode = varNode;
    579603      }
    580       foreach(var child in n.Subtrees) {
     604      foreach (var child in n.Subtrees) {
    581605        translatedNode.AddSubtree(TranslateTreeNode(child, parameterValues, ref nextParIdx));
    582606      }
     
    592616      double h = 1.0 / NUM_STEPS;
    593617
    594       foreach(var episode in episodes) {
     618      foreach (var episode in episodes) {
    595619        var rows = Enumerable.Range(episode.Start, episode.End - episode.Start);
    596620        // return first value as stored in the dataset
     
    603627        var variableValues = new Dictionary<string, Tuple<double, Vector>>();
    604628        var t0 = rows.First();
    605         foreach(var varName in inputVariables) {
     629        foreach (var varName in inputVariables) {
    606630          variableValues.Add(varName, Tuple.Create(dataset.GetDoubleValue(varName, t0), Vector.Zero));
    607631        }
    608         foreach(var varName in targetVariables) {
     632        foreach (var varName in targetVariables) {
    609633          variableValues.Add(varName, Tuple.Create(dataset.GetDoubleValue(varName, t0), Vector.Zero));
    610634        }
    611635        // add value entries for latent variables which are also integrated
    612         foreach(var latentVar in latentVariables) {
     636        foreach (var latentVar in latentVariables) {
    613637          variableValues.Add(latentVar, Tuple.Create(0.0, Vector.Zero)); // we don't have observations for latent variables -> assume zero as starting value
    614638        }
    615639        var calculatedVariables = targetVariables.Concat(latentVariables); // TODO: must conincide with the order of trees in the encoding
    616640
    617         foreach(var t in rows.Skip(1)) {
    618           for(int step = 0; step < NUM_STEPS; step++) {
     641        foreach (var t in rows.Skip(1)) {
     642          for (int step = 0; step < NUM_STEPS; step++) {
    619643            var deltaValues = new Dictionary<string, Tuple<double, Vector>>();
    620             foreach(var tup in trees.Zip(calculatedVariables, Tuple.Create)) {
     644            foreach (var tup in trees.Zip(calculatedVariables, Tuple.Create)) {
    621645              var tree = tup.Item1;
    622646              var targetVarName = tup.Item2;
     
    627651
    628652            // update variableValues for next step
    629             foreach(var kvp in deltaValues) {
     653            foreach (var kvp in deltaValues) {
    630654              var oldVal = variableValues[kvp.Key];
    631655              variableValues[kvp.Key] = Tuple.Create(
     
    642666
    643667          // update for next time step
    644           foreach(var varName in inputVariables) {
     668          foreach (var varName in inputVariables) {
    645669            variableValues[varName] = Tuple.Create(dataset.GetDoubleValue(varName, t), Vector.Zero);
    646670          }
     
    656680        ) {
    657681
    658       switch(node.Symbol.Name) {
     682      switch (node.Symbol.Name) {
    659683        case "+": {
    660684            var l = InterpretRec(node.GetSubtree(0), variableValues, nodeIdx, parameterValues); // TODO capture all parameters into a state type for interpretation
     
    681705
    682706            // protected division
    683             if(r.Item1.IsAlmost(0.0)) {
     707            if (r.Item1.IsAlmost(0.0)) {
    684708              return Tuple.Create(0.0, Vector.Zero);
    685709            } else {
     
    690714            }
    691715          }
     716        case "sin": {
     717            var x = InterpretRec(node.GetSubtree(0), variableValues, nodeIdx, parameterValues);
     718            return Tuple.Create(
     719              Math.Sin(x.Item1),
     720              Vector.Cos(x.Item2) * x.Item2
     721            );
     722          }
     723        case "cos": {
     724            var x = InterpretRec(node.GetSubtree(0), variableValues, nodeIdx, parameterValues);
     725            return Tuple.Create(
     726              Math.Cos(x.Item1),
     727              -Vector.Sin(x.Item2) * x.Item2
     728            );
     729          }
    692730        default: {
    693731            // distinguish other cases
    694             if(IsConstantNode(node)) {
     732            if (IsConstantNode(node)) {
    695733              var vArr = new double[parameterValues.Length]; // backing array for vector
    696734              vArr[nodeIdx[node]] = 1.0;
     
    724762    private void RegisterEventHandlers() {
    725763      ProblemDataParameter.ValueChanged += ProblemDataParameter_ValueChanged;
    726       if(ProblemDataParameter.Value != null) ProblemDataParameter.Value.Changed += ProblemData_Changed;
     764      if (ProblemDataParameter.Value != null) ProblemDataParameter.Value.Changed += ProblemData_Changed;
    727765
    728766      TargetVariablesParameter.ValueChanged += TargetVariablesParameter_ValueChanged;
    729       if(TargetVariablesParameter.Value != null) TargetVariablesParameter.Value.CheckedItemsChanged += CheckedTargetVariablesChanged;
     767      if (TargetVariablesParameter.Value != null) TargetVariablesParameter.Value.CheckedItemsChanged += CheckedTargetVariablesChanged;
    730768
    731769      FunctionSetParameter.ValueChanged += FunctionSetParameter_ValueChanged;
    732       if(FunctionSetParameter.Value != null) FunctionSetParameter.Value.CheckedItemsChanged += CheckedFunctionsChanged;
     770      if (FunctionSetParameter.Value != null) FunctionSetParameter.Value.CheckedItemsChanged += CheckedFunctionsChanged;
    733771
    734772      MaximumLengthParameter.Value.ValueChanged += MaximumLengthChanged;
     
    775813      UpdateTargetVariables();        // implicitly updates other dependent parameters
    776814      var handler = ProblemDataChanged;
    777       if(handler != null) handler(this, EventArgs.Empty);
     815      if (handler != null) handler(this, EventArgs.Empty);
    778816    }
    779817
     
    792830      l.Add(new StringValue("%").AsReadOnly());
    793831      l.Add(new StringValue("-").AsReadOnly());
     832      l.Add(new StringValue("sin").AsReadOnly());
     833      l.Add(new StringValue("cos").AsReadOnly());
    794834      return l.AsReadOnly();
    795835    }
     
    808848      var newVariablesList = new CheckedItemCollection<StringValue>(ProblemData.Dataset.VariableNames.Select(str => new StringValue(str).AsReadOnly()).ToArray()).AsReadOnly();
    809849      var matchingItems = newVariablesList.Where(item => currentlySelectedVariables.Contains(item.Value)).ToArray();
    810       foreach(var matchingItem in matchingItems) {
     850      foreach (var matchingItem in matchingItems) {
    811851        newVariablesList.SetItemCheckedState(matchingItem, true);
    812852      }
     
    817857      var encoding = new MultiEncoding();
    818858      var g = CreateGrammar();
    819       foreach(var targetVar in TargetVariables.CheckedItems) {
     859      foreach (var targetVar in TargetVariables.CheckedItems) {
    820860        encoding = encoding.Add(new SymbolicExpressionTreeEncoding(targetVar + "_tree", g, MaximumLength, MaximumLength)); // only limit by length
    821861      }
    822       for(int i = 1; i <= NumberOfLatentVariables; i++) {
     862      for (int i = 1; i <= NumberOfLatentVariables; i++) {
    823863        encoding = encoding.Add(new SymbolicExpressionTreeEncoding("λ" + i + "_tree", g, MaximumLength, MaximumLength));
    824864      }
     
    838878      //}, 1, 1);
    839879
    840       foreach(var variableName in ProblemData.AllowedInputVariables.Union(TargetVariables.CheckedItems.Select(i => i.Value)))
     880      foreach (var variableName in ProblemData.AllowedInputVariables.Union(TargetVariables.CheckedItems.Select(i => i.Value)))
    841881        g.AddTerminalSymbol(variableName);
    842882
     
    844884      // we generate multiple symbols to balance the probability for selecting a numeric parameter in the generation of random trees
    845885      var numericConstantsFactor = 2.0;
    846       for(int i = 0; i < numericConstantsFactor * (ProblemData.AllowedInputVariables.Count() + TargetVariables.CheckedItems.Count()); i++) {
     886      for (int i = 0; i < numericConstantsFactor * (ProblemData.AllowedInputVariables.Count() + TargetVariables.CheckedItems.Count()); i++) {
    847887        g.AddTerminalSymbol("θ" + i); // numeric parameter for which the value is optimized using AutoDiff
    848888      }
    849889
    850890      // generate symbols for latent variables
    851       for(int i = 1; i <= NumberOfLatentVariables; i++) {
     891      for (int i = 1; i <= NumberOfLatentVariables; i++) {
    852892        g.AddTerminalSymbol("λ" + i); // numeric parameter for which the value is optimized using AutoDiff
    853893      }
Note: See TracChangeset for help on using the changeset viewer.