Free cookie consent management tool by TermsFeed Policy Generator

Changeset 6732


Ignore:
Timestamp:
09/10/11 15:34:19 (11 years ago)
Author:
gkronber
Message:

#1480 added IL emitting tree interpreter for symbolic data analysis and test case. Found and fixed a bug in the existing interpreter for boolean operators OR and AND with NaN arguments. However, this means that the output of previously stored solutions changes. We Probably we should keep the incorrect behavior now and document this accordingly, as changing this would need a version increment of all data analysis plugins.

Location:
trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj

    r6135 r6732  
    121121    <Compile Include="Analyzers\SymbolicDataAnalysisVariableFrequencyAnalyzer.cs" />
    122122    <Compile Include="Analyzers\SymbolicDataAnalysisAlleleFrequencyAnalyzer.cs" />
     123    <Compile Include="SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
    123124    <Compile Include="Formatters\SymbolicDataAnalysisExpressionLatexFormatter.cs" />
    124125    <Compile Include="Formatters\SymbolicDataAnalysisExpressionMATLABFormatter.cs" />
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r5987 r6732  
    308308            double result = Evaluate(dataset, ref row, state);
    309309            for (int i = 1; i < currentInstr.nArguments; i++) {
    310               if (result <= 0.0) SkipInstructions(state);
     310              if (result > 0.0) result = Evaluate(dataset, ref row, state);
    311311              else {
    312                 result = Evaluate(dataset, ref row, state);
     312                SkipInstructions(state);
    313313              }
    314314            }
    315             return result <= 0.0 ? -1.0 : 1.0;
     315            return result > 0.0 ? 1.0 : -1.0;
    316316          }
    317317        case OpCodes.OR: {
    318318            double result = Evaluate(dataset, ref row, state);
    319319            for (int i = 1; i < currentInstr.nArguments; i++) {
    320               if (result > 0.0) SkipInstructions(state);
     320              if (result <= 0.0) result = Evaluate(dataset, ref row, state);
    321321              else {
    322                 result = Evaluate(dataset, ref row, state);
     322                SkipInstructions(state);
    323323              }
    324324            }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs

    r5809 r6732  
    3030
    3131
    32   /// <summary>
    33   ///This is a test class for SimpleArithmeticExpressionInterpreter and is intended
    34   ///to contain all SimpleArithmeticExpressionInterpreter Unit Tests
    35   ///</summary>
    3632  [TestClass()]
    3733  public class SymbolicDataAnalysisExpressionTreeInterpreterTest {
     
    5551
    5652    [TestMethod]
    57     public void FullGrammarSimpleArithmeticExpressionInterpreterPerformanceTest() {
     53    public void SymbolicDataAnalysisExpressionTreeInterpreterFullGrammarPerformanceTest() {
     54      FullGrammarPerformanceTest(new SymbolicDataAnalysisExpressionTreeInterpreter(), 12.5e6);
     55    }
     56    [TestMethod]
     57    public void SymbolicDataAnalysisExpressionTreeInterpreterArithmeticGrammarPerformanceTest() {
     58      FullGrammarPerformanceTest(new SymbolicDataAnalysisExpressionTreeInterpreter(), 12.5e6);
     59    }
     60
     61    [TestMethod]
     62    public void SymbolicDataAnalysisExpressionTreeILEmittingInterpreterFullGrammarPerformanceTest() {
     63      FullGrammarPerformanceTest(new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(), 25e6);
     64    }
     65    [TestMethod]
     66    public void SymbolicDataAnalysisExpressionTreeILEmittingInterpreterArithmeticGrammarPerformanceTest() {
     67      FullGrammarPerformanceTest(new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(), 25e6);
     68    }
     69
     70    private void FullGrammarPerformanceTest(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double nodesPerSecThreshold) {
    5871      var twister = new MersenneTwister(31415);
    5972      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
     
    6477      grammar.MinimumFunctionDefinitions = 0;
    6578      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
    66       double[] estimation = new double[Rows];
    6779      foreach (ISymbolicExpressionTree tree in randomTrees) {
    6880        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
    6981      }
    70       SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
    7182      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
    72       Assert.IsTrue(nodesPerSec > 12.5e6); // evaluated nodes per seconds must be larger than 15mNodes/sec
    73     }
    74 
    75     [TestMethod]
    76     public void ArithmeticGrammarSimpleArithmeticExpressionInterpreterPerformanceTest() {
     83      Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
     84    }
     85
     86    private void ArithmeticGrammarPerformanceTest(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, double nodesPerSecThreshold) {
    7787      var twister = new MersenneTwister(31415);
    7888      var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
     
    8393      grammar.MinimumFunctionDefinitions = 0;
    8494      var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
    85       double[] estimation = new double[Rows];
    8695      foreach (SymbolicExpressionTree tree in randomTrees) {
    8796        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
    8897      }
    89       SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
     98
    9099      double nodesPerSec = Util.CalculateEvaluatedNodesPerSec(randomTrees, interpreter, dataset, 3);
    91       Assert.IsTrue(nodesPerSec > 12.5e6); // evaluated nodes per seconds must be larger than 15mNodes/sec
     100      Assert.IsTrue(nodesPerSec > nodesPerSecThreshold); // evaluated nodes per seconds must be larger than 15mNodes/sec
    92101    }
    93102
     
    97106    ///</summary>
    98107    [TestMethod]
    99     public void SimpleArithmeticExpressionInterpreterEvaluateTest() {
    100 
     108    public void SymbolicDataAnalysisExpressionTreeInterpreterEvaluateTest() {
    101109      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
    102110        { 1.0, 1.0, 1.0 },
     
    105113      });
    106114
    107       SymbolicDataAnalysisExpressionTreeInterpreter interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
    108 
     115      var interpreter = new SymbolicDataAnalysisExpressionTreeInterpreter();
     116      EvaluateTerminals(interpreter, ds);
     117      EvaluateOperations(interpreter, ds);
     118      EvaluateAdf(interpreter, ds);
     119    }
     120
     121    [TestMethod]
     122    public void SymbolicDataAnalysisExpressionILEmittingTreeInterpreterEvaluateTest() {
     123      Dataset ds = new Dataset(new string[] { "Y", "A", "B" }, new double[,] {
     124        { 1.0, 1.0, 1.0 },
     125        { 2.0, 2.0, 2.0 },
     126        { 3.0, 1.0, 2.0 }
     127      });
     128
     129      var interpreter = new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter();
     130      EvaluateTerminals(interpreter, ds);
     131      EvaluateOperations(interpreter, ds);
     132    }
     133
     134    private void EvaluateTerminals(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
    109135      // constants
    110136      Evaluate(interpreter, ds, "(+ 1.5 3.5)", 0, 5.0);
     
    113139      Evaluate(interpreter, ds, "(variable 2.0 a)", 0, 2.0);
    114140      Evaluate(interpreter, ds, "(variable 2.0 a)", 1, 4.0);
    115 
    116 
     141    }
     142
     143    private void EvaluateAdf(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
     144
     145      // ADF     
     146      Evaluate(interpreter, ds, @"(PROG
     147                                    (MAIN
     148                                      (CALL ADF0))
     149                                    (defun ADF0 1.0))", 1, 1.0);
     150      Evaluate(interpreter, ds, @"(PROG
     151                                    (MAIN
     152                                      (* (CALL ADF0) (CALL ADF0)))
     153                                    (defun ADF0 2.0))", 1, 4.0);
     154      Evaluate(interpreter, ds, @"(PROG
     155                                    (MAIN
     156                                      (CALL ADF0 2.0 3.0))
     157                                    (defun ADF0
     158                                      (+ (ARG 0) (ARG 1))))", 1, 5.0);
     159      Evaluate(interpreter, ds, @"(PROG
     160                                    (MAIN (CALL ADF1 2.0 3.0))
     161                                    (defun ADF0
     162                                      (- (ARG 1) (ARG 0)))
     163                                    (defun ADF1
     164                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
     165                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
     166      Evaluate(interpreter, ds, @"(PROG
     167                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
     168                                    (defun ADF0
     169                                      (- (ARG 1) (ARG 0)))
     170                                    (defun ADF1                                                                             
     171                                      (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
     172      Evaluate(interpreter, ds,
     173               @"(PROG
     174                                    (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
     175                                    (defun ADF0
     176                                      (- (ARG 1) (ARG 0)))
     177                                    (defun ADF1                                                                             
     178                                      (+ (CALL ADF0 (ARG 1) (ARG 0))
     179                                         (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
     180    }
     181
     182    private void EvaluateOperations(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds) {
    117183      // addition
    118184      Evaluate(interpreter, ds, "(+ (variable 2.0 a ))", 1, 4.0);
     
    148214      Evaluate(interpreter, ds, "(> (variable 2.0 a) 1.9)", 0, 1.0);
    149215      Evaluate(interpreter, ds, "(> 1.9 (variable 2.0 a))", 0, -1.0);
    150       //Evaluate(interpreter, ds, "(> (sqrt -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
     216      Evaluate(interpreter, ds, "(> (log -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
    151217
    152218      // lt
     
    155221      Evaluate(interpreter, ds, "(< (variable 2.0 a) 1.9)", 0, -1.0);
    156222      Evaluate(interpreter, ds, "(< 1.9 (variable 2.0 a))", 0, 1.0);
    157       //Evaluate(interpreter, ds, "(< (sqrt -1,0) (log -1,0))", 0, -1.0); // (< nan nan) should be false
     223      Evaluate(interpreter, ds, "(< (log -1.0) (log -1.0))", 0, -1.0); // (< nan nan) should be false
    158224
    159225      // If
     
    163229      Evaluate(interpreter, ds, "(if 1.0 2.0 3.0)", 0, 2.0);
    164230      Evaluate(interpreter, ds, "(if 10.0 2.0 3.0)", 0, 2.0);
    165       // Evaluate(interpreter, ds, "(if (sqrt -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
     231      Evaluate(interpreter, ds, "(if (log -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
    166232
    167233      // NOT
     
    171237      Evaluate(interpreter, ds, "(not 2.0)", 0, -1.0);
    172238      Evaluate(interpreter, ds, "(not 0.0)", 0, 1.0);
     239      Evaluate(interpreter, ds, "(not (log -1.0))", 0, 1.0);
    173240
    174241      // AND
     
    181248      Evaluate(interpreter, ds, "(and 1.0 2.0 3.0)", 0, 1.0);
    182249      Evaluate(interpreter, ds, "(and 1.0 -2.0 3.0)", 0, -1.0);
     250      Evaluate(interpreter, ds, "(and (log -1.0))", 0, -1.0); // (and NaN)
     251      Evaluate(interpreter, ds, "(and (log -1.0)  1.0)", 0, -1.0); // (and NaN 1.0)
     252
    183253
    184254      // OR
     
    190260      Evaluate(interpreter, ds, "(or -1.0 -2.0 -3.0)", 0, -1.0);
    191261      Evaluate(interpreter, ds, "(or -1.0 -2.0 3.0)", 0, 1.0);
     262      Evaluate(interpreter, ds, "(or (log -1.0))", 0, -1.0); // (or NaN)
     263      Evaluate(interpreter, ds, "(or (log -1.0)  1.0)", 0, -1.0); // (or NaN 1.0)
    192264
    193265      // sin, cos, tan
     
    207279      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
    208280
    209       // ADF     
    210       Evaluate(interpreter, ds, @"(PROG
    211                                     (MAIN
    212                                       (CALL ADF0))
    213                                     (defun ADF0 1.0))", 1, 1.0);
    214       Evaluate(interpreter, ds, @"(PROG
    215                                     (MAIN
    216                                       (* (CALL ADF0) (CALL ADF0)))
    217                                     (defun ADF0 2.0))", 1, 4.0);
    218       Evaluate(interpreter, ds, @"(PROG
    219                                     (MAIN
    220                                       (CALL ADF0 2.0 3.0))
    221                                     (defun ADF0
    222                                       (+ (ARG 0) (ARG 1))))", 1, 5.0);
    223       Evaluate(interpreter, ds, @"(PROG
    224                                     (MAIN (CALL ADF1 2.0 3.0))
    225                                     (defun ADF0
    226                                       (- (ARG 1) (ARG 0)))
    227                                     (defun ADF1
    228                                       (+ (CALL ADF0 (ARG 1) (ARG 0))
    229                                          (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
    230       Evaluate(interpreter, ds, @"(PROG
    231                                     (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
    232                                     (defun ADF0
    233                                       (- (ARG 1) (ARG 0)))
    234                                     (defun ADF1                                                                             
    235                                       (CALL ADF0 (ARG 1) (ARG 0))))", 1, 1.0);
    236       Evaluate(interpreter, ds, @"(PROG
    237                                     (MAIN (CALL ADF1 (variable 2.0 a) 3.0))
    238                                     (defun ADF0
    239                                       (- (ARG 1) (ARG 0)))
    240                                     (defun ADF1                                                                             
    241                                       (+ (CALL ADF0 (ARG 1) (ARG 0))
    242                                          (CALL ADF0 (ARG 0) (ARG 1)))))", 1, 0.0);
    243     }
    244 
    245     private void Evaluate(SymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
     281    }
     282
     283    private void Evaluate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, Dataset ds, string expr, int index, double expected) {
    246284      var importer = new SymbolicExpressionImporter();
    247285      ISymbolicExpressionTree tree = importer.Import(expr);
Note: See TracChangeset for help on using the changeset viewer.