Changeset 17216


Ignore:
Timestamp:
08/13/19 19:05:08 (10 days ago)
Author:
gkronber
Message:

#2994 bug fix for integer roots (in particular cbrt (same as in trunk)) added a unit test to compare outputs of new evaluators to LinearInterpreter

Location:
branches/2994-AutoDiffForIntervals
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/Interpreter.cs

    r17212 r17216  
    501501    public AlgebraicDouble AssignCos(AlgebraicDouble a) { Value = Math.Cos(a.Value); return this; }
    502502    public AlgebraicDouble AssignTanh(AlgebraicDouble a) { Value = Math.Tanh(a.Value); return this; }
    503     public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = Math.Log(a.Value); return this; } 
     503    public AlgebraicDouble AssignLog(AlgebraicDouble a) { Value = Math.Log(a.Value); return this; }
    504504    public AlgebraicDouble AssignExp(AlgebraicDouble a) { Value = Math.Exp(a.Value); return this; }
    505505    public AlgebraicDouble AssignIntPower(AlgebraicDouble a, int p) { Value = Math.Pow(a.Value, p); return this; }
    506     public AlgebraicDouble AssignIntRoot(AlgebraicDouble a, int r) { Value = Math.Pow(a.Value, 1.0 / r); return this; }
     506    public AlgebraicDouble AssignIntRoot(AlgebraicDouble a, int r) { Value = IntRoot(a.Value, r); return this; }
     507
     508    // helper
     509    private static double IntRoot(double value, int r) {
     510      if (r % 2 == 0) return Math.Pow(value, 1.0 / r);
     511      else return value < 0 ? -Math.Pow(-value, 1.0 / r) : Math.Pow(value, 1.0 / r);
     512    }
     513
    507514    public AlgebraicDouble AssignAbs(AlgebraicDouble a) { Value = Math.Abs(a.Value); return this; }
    508515    public AlgebraicDouble AssignSgn(AlgebraicDouble a) { Value = double.IsNaN(a.Value) ? double.NaN : Math.Sign(a.Value); return this; }
     
    549556    public AlgebraicDoubleVector AssignTanh(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Tanh(a.arr[i]); } return this; }
    550557    public AlgebraicDoubleVector AssignIntPower(AlgebraicDoubleVector a, int p) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], p); } return this; }
    551     public AlgebraicDoubleVector AssignIntRoot(AlgebraicDoubleVector a, int r) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Pow(a.arr[i], 1.0 / r); } return this; }
     558    public AlgebraicDoubleVector AssignIntRoot(AlgebraicDoubleVector a, int r) { for (int i = 0; i < arr.Length; ++i) { arr[i] = IntRoot(a.arr[i], r); } return this; }
     559
     560    // helper
     561    private double IntRoot(double v, int r) {
     562      if (r % 2 == 0) return Math.Pow(v, 1.0 / r);
     563      else return v < 0 ? -Math.Pow(-v, 1.0 / r) : Math.Pow(v, 1.0 / r);
     564    }
     565
    552566    public AlgebraicDoubleVector AssignAbs(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Abs(a.arr[i]); } return this; }
    553567    public AlgebraicDoubleVector AssignSgn(AlgebraicDoubleVector a) { for (int i = 0; i < arr.Length; ++i) { arr[i] = Math.Sign(a.arr[i]); } return this; }
     
    926940        return AssignInv(this);
    927941      } else {
    928         // root only defined for positive arguments
    929         if (a.LowerBound.Value.Value < 0) {
     942        // root only defined for positive arguments for even roots
     943        if (r % 2 == 0 && a.LowerBound.Value.Value < 0) {
    930944          low = new MultivariateDual<AlgebraicDouble>(double.NaN);
    931945          high = new MultivariateDual<AlgebraicDouble>(double.NaN);
  • branches/2994-AutoDiffForIntervals/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs

    r17209 r17216  
    266266            Assert.AreEqual(sum, s, 1e-12, errorMessage);
    267267          }
     268        }
     269      }
     270    }
     271
     272    [TestMethod]
     273    [TestCategory("Problems.DataAnalysis.Symbolic")]
     274    [TestProperty("Time", "long")]
     275    public void TestVectorInterpretersEstimatedValuesConsistency() {
     276      var twister = new MersenneTwister();
     277      twister.Seed(31415);
     278      const int numRows = 100;
     279      var dataset = Util.CreateRandomDataset(twister, numRows, Columns);
     280
     281      var grammar = new TypeCoherentExpressionGrammar();
     282      grammar.ConfigureAsDefaultRegressionGrammar();
     283      grammar.Symbols.First(s => s is Square).Enabled = true;
     284      grammar.Symbols.First(s => s is SquareRoot).Enabled = true;
     285      grammar.Symbols.First(s => s is Cube).Enabled = true;
     286      grammar.Symbols.First(s => s is CubeRoot).Enabled = true;
     287
     288      var refInterpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
     289      var newInterpreter = new VectorEvaluator();
     290      var newAutoDiffInterpreter = new VectorAutoDiffEvaluator();
     291
     292      var rows = Enumerable.Range(0, numRows).ToList();
     293      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);
     294      foreach (ISymbolicExpressionTree tree in randomTrees) {
     295        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
     296      }
     297
     298      for (int i = 0; i < randomTrees.Length; ++i) {
     299        var tree = randomTrees[i];
     300        var refValues = refInterpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToArray();
     301        var newValues = newInterpreter.Evaluate(tree, dataset, rows.ToArray()).ToArray();
     302        var newAutoDiffValues = new double[numRows];
     303        newAutoDiffInterpreter.Evaluate(tree, dataset, rows.ToArray(), new ISymbolicExpressionTreeNode[0], newAutoDiffValues, null);
     304
     305        for (int j = 0; j < rows.Count; j++) {
     306          if (double.IsNaN(refValues[j]) && double.IsNaN(newValues[j]) && double.IsNaN(newAutoDiffValues[j])) continue;
     307          string errorMessage = string.Format("Interpreters do not agree on tree {0} {1}.", i, (new InfixExpressionFormatter()).Format(tree));
     308
     309          var relDelta = Math.Abs(refValues[j]) * 1e-5;
     310          Assert.AreEqual(refValues[j], newValues[j], relDelta, errorMessage);
     311          Assert.AreEqual(newValues[j], newAutoDiffValues[j], relDelta, errorMessage);
    268312        }
    269313      }
Note: See TracChangeset for help on using the changeset viewer.