Ignore:
Timestamp:
03/31/17 14:49:21 (3 years ago)
Author:
mkommend
Message:

#2442: Merged r12807, r13039, r13139, r13140, r13141, r13222, r13247, r13248, r13251, r13254, r13255, r13256, r1326, r13288, r13313, r13314, r13315, r13318, r14282, r14809, r14810 into stable.

Location:
stable
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • stable

  • stable/HeuristicLab.Tests

  • stable/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs

    r14186 r14811  
    7070    }
    7171
     72    [TestMethod]
     73    [TestCategory("Problems.DataAnalysis.Symbolic")]
     74    [TestProperty("Time", "long")]
     75    public void CompiledInterpreterTestTypeCoherentGrammarPerformance() {
     76      TestTypeCoherentGrammarPerformance(new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(), 12.5e6);
     77    }
     78    [TestMethod]
     79    [TestCategory("Problems.DataAnalysis.Symbolic")]
     80    [TestProperty("Time", "long")]
     81    public void CompiledInterpreterTestFullGrammarPerformance() {
     82      TestFullGrammarPerformance(new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(), 12.5e6);
     83    }
     84    [TestMethod]
     85    [TestCategory("Problems.DataAnalysis.Symbolic")]
     86    [TestProperty("Time", "long")]
     87    public void CompiledInterpreterTestArithmeticGrammarPerformance() {
     88      TestArithmeticGrammarPerformance(new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(), 12.5e6);
     89    }
    7290
    7391    [TestMethod]
     
    8098    [TestCategory("Problems.DataAnalysis.Symbolic")]
    8199    [TestProperty("Time", "long")]
    82     public void ILEmittingInterpreterTestFullGrammarPerformance() {
    83       TestFullGrammarPerformance(new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(), 7.5e6);
    84     }
    85     [TestMethod]
    86     [TestCategory("Problems.DataAnalysis.Symbolic")]
    87     [TestProperty("Time", "long")]
    88100    public void ILEmittingInterpreterTestArithmeticGrammarPerformance() {
    89101      TestArithmeticGrammarPerformance(new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(), 7.5e6);
    90102    }
    91 
    92103
    93104    [TestMethod]
     
    113124      var twister = new MersenneTwister(31415);
    114125      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
     126
    115127      var grammar = new TypeCoherentExpressionGrammar();
    116128      grammar.ConfigureAsDefaultRegressionGrammar();
    117       grammar.MaximumFunctionArguments = 0;
    118       grammar.MaximumFunctionDefinitions = 0;
    119       grammar.MinimumFunctionArguments = 0;
    120       grammar.MinimumFunctionDefinitions = 0;
     129
    121130      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
    122131      foreach (ISymbolicExpressionTree tree in randomTrees) {
     
    131140      var twister = new MersenneTwister(31415);
    132141      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
     142
    133143      var grammar = new FullFunctionalExpressionGrammar();
    134       grammar.MaximumFunctionArguments = 0;
    135       grammar.MaximumFunctionDefinitions = 0;
    136       grammar.MinimumFunctionArguments = 0;
    137       grammar.MinimumFunctionDefinitions = 0;
    138144      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
    139145      foreach (ISymbolicExpressionTree tree in randomTrees) {
     
    148154      var twister = new MersenneTwister(31415);
    149155      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
     156
    150157      var grammar = new ArithmeticExpressionGrammar();
    151       //grammar.Symbols.OfType<Variable>().First().Enabled = false;
    152       grammar.MaximumFunctionArguments = 0;
    153       grammar.MaximumFunctionDefinitions = 0;
    154       grammar.MinimumFunctionArguments = 0;
    155       grammar.MinimumFunctionDefinitions = 0;
    156158      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
    157159      foreach (SymbolicExpressionTree tree in randomTrees) {
     
    175177      EvaluateTerminals(interpreter, ds);
    176178      EvaluateOperations(interpreter, ds);
     179      EvaluateLaggedOperations(interpreter, ds);
     180      EvaluateSpecialFunctions(interpreter, ds);
    177181      EvaluateAdf(interpreter, ds);
    178182    }
    179183
     184    /// <summary>
     185    ///A test for Evaluate
     186    ///</summary>
    180187    [TestMethod]
    181188    [TestCategory("Problems.DataAnalysis.Symbolic")]
     
    185192      EvaluateTerminals(interpreter, ds);
    186193      EvaluateOperations(interpreter, ds);
     194      EvaluateLaggedOperations(interpreter, ds);
     195      EvaluateSpecialFunctions(interpreter, ds);
     196    }
     197
     198    [TestMethod]
     199    [TestCategory("Problems.DataAnalysis.Symbolic")]
     200    [TestProperty("Time", "short")]
     201    public void CompiledInterpreterTestEvaluation() {
     202      var interpreter = new SymbolicDataAnalysisExpressionCompiledTreeInterpreter();
     203      EvaluateTerminals(interpreter, ds);
     204      EvaluateOperations(interpreter, ds);
     205      EvaluateSpecialFunctions(interpreter, ds);
    187206    }
    188207
     
    192211    public void LinearInterpreterTestEvaluation() {
    193212      var interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter();
    194 
    195213      //ADFs are not supported by the linear interpreter
    196214      EvaluateTerminals(interpreter, ds);
    197215      EvaluateOperations(interpreter, ds);
    198     }
    199 
    200     private void EvaluateTerminals(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
     216      EvaluateLaggedOperations(interpreter, ds);
     217      EvaluateSpecialFunctions(interpreter, ds);
     218    }
     219
     220    [TestMethod]
     221    [TestCategory("Problems.DataAnalysis.Symbolic")]
     222    [TestProperty("Time", "long")]
     223    public void TestInterpretersEstimatedValuesConsistency() {
     224      var twister = new MersenneTwister();
     225      int seed = twister.Next(0, int.MaxValue);
     226      twister.Seed((uint)seed);
     227      const int numRows = 100;
     228      var dataset = Util.CreateRandomDataset(twister, numRows, Columns);
     229
     230      var grammar = new TypeCoherentExpressionGrammar();
     231
     232      var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
     233        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
     234        new SymbolicDataAnalysisExpressionTreeInterpreter(),
     235      };
     236
     237      var rows = Enumerable.Range(0, numRows).ToList();
     238      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);
     239      foreach (ISymbolicExpressionTree tree in randomTrees) {
     240        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
     241      }
     242
     243      for (int i = 0; i < randomTrees.Length; ++i) {
     244        var tree = randomTrees[i];
     245        var valuesMatrix = interpreters.Select(x => x.GetSymbolicExpressionTreeValues(tree, dataset, rows)).ToList();
     246        for (int m = 0; m < interpreters.Length - 1; ++m) {
     247          var sum = valuesMatrix[m].Sum();
     248          for (int n = m + 1; n < interpreters.Length; ++n) {
     249            var s = valuesMatrix[n].Sum();
     250            if (double.IsNaN(sum) && double.IsNaN(s)) continue;
     251
     252            string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} (seed = {3}).", interpreters[m].Name, interpreters[n].Name, i, seed);
     253            Assert.AreEqual(sum, s, 1e-12, errorMessage);
     254          }
     255        }
     256      }
     257    }
     258
     259    [TestMethod]
     260    [TestCategory("Problems.DataAnalysis.Symbolic")]
     261    [TestProperty("Time", "long")]
     262    public void TestCompiledInterpreterEstimatedValuesConsistency() {
     263      const double delta = 1e-12;
     264
     265      var twister = new MersenneTwister();
     266      int seed = twister.Next(0, int.MaxValue);
     267      twister.Seed((uint)seed);
     268
     269      Console.WriteLine(seed);
     270
     271      const int numRows = 100;
     272      var dataset = Util.CreateRandomDataset(twister, numRows, Columns);
     273
     274      var grammar = new TypeCoherentExpressionGrammar();
     275      grammar.ConfigureAsDefaultRegressionGrammar();
     276      grammar.Symbols.First(x => x.Name == "Power Functions").Enabled = true;
     277
     278      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 10, 0, 0);
     279      foreach (ISymbolicExpressionTree tree in randomTrees) {
     280        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
     281      }
     282
     283      var interpreters = new ISymbolicDataAnalysisExpressionTreeInterpreter[] {
     284        new SymbolicDataAnalysisExpressionCompiledTreeInterpreter(),
     285        new SymbolicDataAnalysisExpressionTreeInterpreter(),
     286        new SymbolicDataAnalysisExpressionTreeLinearInterpreter(),
     287      };
     288      var rows = Enumerable.Range(0, numRows).ToList();
     289      var formatter = new SymbolicExpressionTreeHierarchicalFormatter();
     290
     291      for (int i = 0; i < randomTrees.Length; ++i) {
     292        var tree = randomTrees[i];
     293        var valuesMatrix = interpreters.Select(x => x.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToList()).ToList();
     294        for (int m = 0; m < interpreters.Length - 1; ++m) {
     295          for (int n = m + 1; n < interpreters.Length; ++n) {
     296            for (int row = 0; row < numRows; ++row) {
     297              var v1 = valuesMatrix[m][row];
     298              var v2 = valuesMatrix[n][row];
     299              if (double.IsNaN(v1) && double.IsNaN(v2)) continue;
     300              if (Math.Abs(v1 - v2) > delta) {
     301                Console.WriteLine(formatter.Format(tree));
     302                foreach (var node in tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPrefix().ToList()) {
     303                  var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
     304                  if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(twister);
     305                  rootNode.SetGrammar(grammar.CreateExpressionTreeGrammar());
     306
     307                  var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
     308                  if (startNode.HasLocalParameters) startNode.ResetLocalParameters(twister);
     309                  startNode.SetGrammar(grammar.CreateExpressionTreeGrammar());
     310
     311                  rootNode.AddSubtree(startNode);
     312                  var t = new SymbolicExpressionTree(rootNode);
     313                  var start = t.Root.GetSubtree(0);
     314                  var p = node.Parent;
     315                  start.AddSubtree(node);
     316                  Console.WriteLine(node);
     317
     318                  var y1 = interpreters[m].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();
     319                  var y2 = interpreters[n].GetSymbolicExpressionTreeValues(t, dataset, new[] { row }).First();
     320
     321                  if (double.IsNaN(y1) && double.IsNaN(y2)) continue;
     322                  string prefix = Math.Abs(y1 - y2) > delta ? "++" : "==";
     323                  Console.WriteLine("\t{0} Row {1}: {2} {3}, Deviation = {4}", prefix, row, y1, y2, Math.Abs(y1 - y2));
     324                  node.Parent = p;
     325                }
     326              }
     327              string errorMessage = string.Format("Interpreters {0} and {1} do not agree on tree {2} and row {3} (seed = {4}).", interpreters[m].Name, interpreters[n].Name, i, row, seed);
     328              Assert.AreEqual(v1, v2, delta, errorMessage);
     329            }
     330          }
     331        }
     332      }
     333    }
     334
     335    private void EvaluateTerminals(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds) {
    201336      // constants
    202337      Evaluate(interpreter, ds, "(+ 1.5 3.5)", 0, 5.0);
     
    207342    }
    208343
    209     private void EvaluateAdf(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
     344    private void EvaluateAdf(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds) {
    210345
    211346      // ADF     
     
    246381    }
    247382
    248     private void EvaluateOperations(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
     383    private void EvaluateSpecialFunctions(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds) {
     384      // special functions
     385      Action<double> checkAiry = (x) => {
     386        double ai, aip, bi, bip;
     387        alglib.airy(x, out ai, out aip, out bi, out bip);
     388        Evaluate(interpreter, ds, "(airya " + x + ")", 0, ai);
     389        Evaluate(interpreter, ds, "(airyb " + x + ")", 0, bi);
     390      };
     391
     392      Action<double> checkBessel = (x) => {
     393        Evaluate(interpreter, ds, "(bessel " + x + ")", 0, alglib.besseli0(x));
     394      };
     395
     396      Action<double> checkSinCosIntegrals = (x) => {
     397        double si, ci;
     398        alglib.sinecosineintegrals(x, out si, out ci);
     399        Evaluate(interpreter, ds, "(cosint " + x + ")", 0, ci);
     400        Evaluate(interpreter, ds, "(sinint " + x + ")", 0, si);
     401      };
     402      Action<double> checkHypSinCosIntegrals = (x) => {
     403        double shi, chi;
     404        alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
     405        Evaluate(interpreter, ds, "(hypcosint " + x + ")", 0, chi);
     406        Evaluate(interpreter, ds, "(hypsinint " + x + ")", 0, shi);
     407      };
     408      Action<double> checkFresnelSinCosIntegrals = (x) => {
     409        double c = 0, s = 0;
     410        alglib.fresnelintegral(x, ref c, ref s);
     411        Evaluate(interpreter, ds, "(fresnelcosint " + x + ")", 0, c);
     412        Evaluate(interpreter, ds, "(fresnelsinint " + x + ")", 0, s);
     413      };
     414      Action<double> checkNormErf = (x) => {
     415        Evaluate(interpreter, ds, "(norm " + x + ")", 0, alglib.normaldistribution(x));
     416        Evaluate(interpreter, ds, "(erf " + x + ")", 0, alglib.errorfunction(x));
     417      };
     418
     419      Action<double> checkGamma = (x) => {
     420        Evaluate(interpreter, ds, "(gamma " + x + ")", 0, alglib.gammafunction(x));
     421      };
     422      Action<double> checkPsi = (x) => {
     423        try {
     424          Evaluate(interpreter, ds, "(psi " + x + ")", 0, alglib.psi(x));
     425        } catch (alglib.alglibexception) { // ignore cases where alglib throws an exception
     426        }
     427      };
     428      Action<double> checkDawson = (x) => {
     429        Evaluate(interpreter, ds, "(dawson " + x + ")", 0, alglib.dawsonintegral(x));
     430      };
     431      Action<double> checkExpInt = (x) => {
     432        Evaluate(interpreter, ds, "(expint " + x + ")", 0, alglib.exponentialintegralei(x));
     433      };
     434
     435      foreach (var e in new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }) {
     436        checkAiry(e);
     437        checkBessel(e);
     438        checkSinCosIntegrals(e);
     439        checkGamma(e);
     440        checkExpInt(e);
     441        checkDawson(e);
     442        checkPsi(e);
     443        checkNormErf(e);
     444        checkFresnelSinCosIntegrals(e);
     445        checkHypSinCosIntegrals(e);
     446      }
     447    }
     448
     449    private void EvaluateLaggedOperations(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds) {
     450      // lag
     451      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0));
     452      Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1));
     453      Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2));
     454      Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1));
     455
     456      // integral
     457      Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));
     458      Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
     459      Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
     460      Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1));
     461      Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);
     462
     463      // derivative
     464      // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
     465      Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0);
     466      Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0);
     467      Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +
     468        (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +
     469        2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -
     470        2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -
     471        ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);
     472      Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);
     473
     474      // timelag
     475      Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));
     476      Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));
     477      Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2));
     478      Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);
     479    }
     480
     481    private void EvaluateOperations(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds) {
    249482      // addition
    250483      Evaluate(interpreter, ds, "(+ (variable 2.0 a ))", 1, 4.0);
     
    369602      // mean
    370603      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
    371 
    372       // lag
    373       Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 1, ds.GetDoubleValue("A", 0));
    374       Evaluate(interpreter, ds, "(lagVariable 1.0 a -1) ", 2, ds.GetDoubleValue("A", 1));
    375       Evaluate(interpreter, ds, "(lagVariable 1.0 a 0) ", 2, ds.GetDoubleValue("A", 2));
    376       Evaluate(interpreter, ds, "(lagVariable 1.0 a 1) ", 0, ds.GetDoubleValue("A", 1));
    377 
    378       // integral
    379       Evaluate(interpreter, ds, "(integral -1.0 (variable 1.0 a)) ", 1, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1));
    380       Evaluate(interpreter, ds, "(integral -1.0 (lagVariable 1.0 a 1)) ", 1, ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
    381       Evaluate(interpreter, ds, "(integral -2.0 (variable 1.0 a)) ", 2, ds.GetDoubleValue("A", 0) + ds.GetDoubleValue("A", 1) + ds.GetDoubleValue("A", 2));
    382       Evaluate(interpreter, ds, "(integral -1.0 (* (variable 1.0 a) (variable 1.0 b)))", 1, ds.GetDoubleValue("A", 0) * ds.GetDoubleValue("B", 0) + ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1));
    383       Evaluate(interpreter, ds, "(integral -2.0 3.0)", 1, 9.0);
    384 
    385       // derivative
    386       // (f_0 + 2 * f_1 - 2 * f_3 - f_4) / 8; // h = 1
    387       Evaluate(interpreter, ds, "(diff (variable 1.0 a)) ", 5, (ds.GetDoubleValue("A", 5) + 2 * ds.GetDoubleValue("A", 4) - 2 * ds.GetDoubleValue("A", 2) - ds.GetDoubleValue("A", 1)) / 8.0);
    388       Evaluate(interpreter, ds, "(diff (variable 1.0 b)) ", 5, (ds.GetDoubleValue("B", 5) + 2 * ds.GetDoubleValue("B", 4) - 2 * ds.GetDoubleValue("B", 2) - ds.GetDoubleValue("B", 1)) / 8.0);
    389       Evaluate(interpreter, ds, "(diff (* (variable 1.0 a) (variable 1.0 b)))", 5, +
    390         (ds.GetDoubleValue("A", 5) * ds.GetDoubleValue("B", 5) +
    391         2 * ds.GetDoubleValue("A", 4) * ds.GetDoubleValue("B", 4) -
    392         2 * ds.GetDoubleValue("A", 2) * ds.GetDoubleValue("B", 2) -
    393         ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 1)) / 8.0);
    394       Evaluate(interpreter, ds, "(diff -2.0 3.0)", 5, 0.0);
    395 
    396       // timelag
    397       Evaluate(interpreter, ds, "(lag -1.0 (lagVariable 1.0 a 2)) ", 1, ds.GetDoubleValue("A", 2));
    398       Evaluate(interpreter, ds, "(lag -2.0 (lagVariable 1.0 a 2)) ", 2, ds.GetDoubleValue("A", 2));
    399       Evaluate(interpreter, ds, "(lag -1.0 (* (lagVariable 1.0 a 1) (lagVariable 1.0 b 2)))", 1, ds.GetDoubleValue("A", 1) * ds.GetDoubleValue("B", 2));
    400       Evaluate(interpreter, ds, "(lag -2.0 3.0)", 1, 3.0);
    401 
    402       {
    403         // special functions
    404         Action<double> checkAiry = (x) => {
    405           double ai, aip, bi, bip;
    406           alglib.airy(x, out ai, out aip, out bi, out bip);
    407           Evaluate(interpreter, ds, "(airya " + x + ")", 0, ai);
    408           Evaluate(interpreter, ds, "(airyb " + x + ")", 0, bi);
    409         };
    410 
    411         Action<double> checkBessel = (x) => {
    412           Evaluate(interpreter, ds, "(bessel " + x + ")", 0, alglib.besseli0(x));
    413         };
    414 
    415         Action<double> checkSinCosIntegrals = (x) => {
    416           double si, ci;
    417           alglib.sinecosineintegrals(x, out si, out ci);
    418           Evaluate(interpreter, ds, "(cosint " + x + ")", 0, ci);
    419           Evaluate(interpreter, ds, "(sinint " + x + ")", 0, si);
    420         };
    421         Action<double> checkHypSinCosIntegrals = (x) => {
    422           double shi, chi;
    423           alglib.hyperbolicsinecosineintegrals(x, out shi, out chi);
    424           Evaluate(interpreter, ds, "(hypcosint " + x + ")", 0, chi);
    425           Evaluate(interpreter, ds, "(hypsinint " + x + ")", 0, shi);
    426         };
    427         Action<double> checkFresnelSinCosIntegrals = (x) => {
    428           double c = 0, s = 0;
    429           alglib.fresnelintegral(x, ref c, ref s);
    430           Evaluate(interpreter, ds, "(fresnelcosint " + x + ")", 0, c);
    431           Evaluate(interpreter, ds, "(fresnelsinint " + x + ")", 0, s);
    432         };
    433         Action<double> checkNormErf = (x) => {
    434           Evaluate(interpreter, ds, "(norm " + x + ")", 0, alglib.normaldistribution(x));
    435           Evaluate(interpreter, ds, "(erf " + x + ")", 0, alglib.errorfunction(x));
    436         };
    437 
    438         Action<double> checkGamma = (x) => {
    439           Evaluate(interpreter, ds, "(gamma " + x + ")", 0, alglib.gammafunction(x));
    440         };
    441         Action<double> checkPsi = (x) => {
    442           try {
    443             Evaluate(interpreter, ds, "(psi " + x + ")", 0, alglib.psi(x));
    444           }
    445           catch (alglib.alglibexception) { // ignore cases where alglib throws an exception
    446           }
    447         };
    448         Action<double> checkDawson = (x) => {
    449           Evaluate(interpreter, ds, "(dawson " + x + ")", 0, alglib.dawsonintegral(x));
    450         };
    451         Action<double> checkExpInt = (x) => {
    452           Evaluate(interpreter, ds, "(expint " + x + ")", 0, alglib.exponentialintegralei(x));
    453         };
    454 
    455 
    456 
    457         foreach (var e in new[] { -2.0, -1.0, 0.0, 1.0, 2.0 }) {
    458           checkAiry(e);
    459           checkBessel(e);
    460           checkSinCosIntegrals(e);
    461           checkGamma(e);
    462           checkExpInt(e);
    463           checkDawson(e);
    464           checkPsi(e);
    465           checkNormErf(e);
    466           checkFresnelSinCosIntegrals(e);
    467           checkHypSinCosIntegrals(e);
    468         }
    469       }
    470     }
    471 
    472     private void Evaluate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
     604    }
     605
     606    private void Evaluate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, IDataset ds, string expr, int index, double expected) {
    473607      var importer = new SymbolicExpressionImporter();
    474608      ISymbolicExpressionTree tree = importer.Import(expr);
Note: See TracChangeset for help on using the changeset viewer.