Free cookie consent management tool by TermsFeed Policy Generator

Changeset 3841


Ignore:
Timestamp:
05/18/10 11:40:02 (14 years ago)
Author:
gkronber
Message:

Extended set of available functions for symbolic regression and added test cases for the extended function set. #1013

Location:
trunk/sources
Files:
15 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs

    r3817 r3841  
    189189      SymbolicExpressionTreeCreator creator = new ProbabilisticTreeCreator();
    190190      var evaluator = new SymbolicRegressionScaledMeanSquaredErrorEvaluator();
    191       var grammar = new ArithmeticExpressionGrammar();
     191      var grammar = new FullFunctionalExpressionGrammar();
    192192      var globalGrammar = new GlobalSymbolicExpressionGrammar(grammar);
    193193      var interpreter = new SimpleArithmeticExpressionInterpreter();
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj

    r3832 r3841  
    101101    <Compile Include="Properties\AssemblyInfo.cs" />
    102102    <Compile Include="Symbolic\ArithmeticExpressionGrammar.cs" />
     103    <Compile Include="Symbolic\FullFunctionalExpressionGrammar.cs" />
    103104    <Compile Include="Symbolic\ISymbolicExpressionTreeInterpreter.cs" />
    104105    <Compile Include="Symbolic\SimpleArithmeticExpressionInterpreter.cs" />
     
    107108    <Compile Include="Symbolic\Symbols\Constant.cs" />
    108109    <Compile Include="Symbolic\Symbols\ConstantTreeNode.cs" />
     110    <Compile Include="Symbolic\Symbols\LaggedVariable.cs" />
     111    <Compile Include="Symbolic\Symbols\LaggedVariableTreeNode.cs" />
     112    <Compile Include="Symbolic\Symbols\GreaterThan.cs" />
     113    <Compile Include="Symbolic\Symbols\LessThan.cs" />
     114    <Compile Include="Symbolic\Symbols\And.cs" />
     115    <Compile Include="Symbolic\Symbols\Or.cs" />
     116    <Compile Include="Symbolic\Symbols\Not.cs" />
     117    <Compile Include="Symbolic\Symbols\Logarithm.cs" />
     118    <Compile Include="Symbolic\Symbols\Exponential.cs" />
     119    <Compile Include="Symbolic\Symbols\Sine.cs" />
     120    <Compile Include="Symbolic\Symbols\Cosine.cs" />
     121    <Compile Include="Symbolic\Symbols\Tangent.cs" />
     122    <Compile Include="Symbolic\Symbols\Average.cs" />
     123    <Compile Include="Symbolic\Symbols\IfThenElse.cs" />
    109124    <Compile Include="Symbolic\Symbols\Division.cs" />
    110125    <Compile Include="Symbolic\Symbols\Multiplication.cs" />
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs

    r3747 r3841  
    4040      public const byte Mul = 3;
    4141      public const byte Div = 4;
    42       public const byte Variable = 5;
    43       public const byte Constant = 6;
    44       public const byte Call = 100;
    45       public const byte Arg = 101;
    46     }
    47 
     42
     43      public const byte Sin = 5;
     44      public const byte Cos = 6;
     45      public const byte Tan = 7;
     46
     47      public const byte Log = 8;
     48      public const byte Exp = 9;
     49
     50      public const byte IfThenElse = 10;
     51
     52      public const byte GT = 11;
     53      public const byte LT = 12;
     54
     55      public const byte AND = 13;
     56      public const byte OR = 14;
     57      public const byte NOT = 15;
     58
     59
     60      public const byte Average = 16;
     61
     62      public const byte Call = 17;
     63
     64      public const byte Variable = 18;
     65      public const byte LagVariable = 19;
     66      public const byte Constant = 20;
     67      public const byte Arg = 21;
     68    }
     69
     70    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
     71      { typeof(Addition), OpCodes.Add },
     72      { typeof(Subtraction), OpCodes.Sub },
     73      { typeof(Multiplication), OpCodes.Mul },
     74      { typeof(Division), OpCodes.Div },
     75      { typeof(Sine), OpCodes.Sin },
     76      { typeof(Cosine), OpCodes.Cos },
     77      { typeof(Tangent), OpCodes.Tan },
     78      { typeof(Logarithm), OpCodes.Log },
     79      { typeof(Exponential), OpCodes.Exp },
     80      { typeof(IfThenElse), OpCodes.IfThenElse },
     81      { typeof(GreaterThan), OpCodes.GT },
     82      { typeof(LessThan), OpCodes.LT },
     83      { typeof(And), OpCodes.AND },
     84      { typeof(Or), OpCodes.OR },
     85      { typeof(Not), OpCodes.NOT},
     86      { typeof(Average), OpCodes.Average},
     87      { typeof(InvokeFunction), OpCodes.Call },
     88      { typeof(HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable), OpCodes.Variable },
     89      { typeof(LaggedVariable), OpCodes.LagVariable },
     90      { typeof(Constant), OpCodes.Constant },
     91      { typeof(Argument), OpCodes.Arg },
     92    };
    4893    private const int ARGUMENT_STACK_SIZE = 1024;
    4994
     
    81126        var variableTreeNode = instr.dynamicNode as VariableTreeNode;
    82127        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
    83       }
     128      } else if (instr.opCode == OpCodes.LagVariable) {
     129        var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
     130        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
     131      }
    84132      return instr;
    85133    }
    86134
    87135    private byte MapSymbolToOpCode(SymbolicExpressionTreeNode treeNode) {
    88       if (treeNode.Symbol is Addition) return OpCodes.Add;
    89       if (treeNode.Symbol is Subtraction) return OpCodes.Sub;
    90       if (treeNode.Symbol is Multiplication) return OpCodes.Mul;
    91       if (treeNode.Symbol is Division) return OpCodes.Div;
    92       if (treeNode.Symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable) return OpCodes.Variable;
    93       if (treeNode.Symbol is Constant) return OpCodes.Constant;
    94       if (treeNode.Symbol is InvokeFunction) return OpCodes.Call;
    95       if (treeNode.Symbol is Argument) return OpCodes.Arg;
    96       throw new NotSupportedException("Symbol: " + treeNode.Symbol);
     136      if (symbolToOpcode.ContainsKey(treeNode.Symbol.GetType()))
     137        return symbolToOpcode[treeNode.Symbol.GetType()];
     138      else
     139        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
    97140    }
    98141
     
    133176            return p;
    134177          }
     178        case OpCodes.Average: {
     179            double sum = Evaluate();
     180            for (int i = 1; i < currentInstr.nArguments; i++) {
     181              sum += Evaluate();
     182            }
     183            return sum / currentInstr.nArguments;
     184          }
     185        case OpCodes.Cos: {
     186            return Math.Cos(Evaluate());
     187          }
     188        case OpCodes.Sin: {
     189            return Math.Sin(Evaluate());
     190          }
     191        case OpCodes.Tan: {
     192            return Math.Tan(Evaluate());
     193          }
     194        case OpCodes.Exp: {
     195            return Math.Exp(Evaluate());
     196          }
     197        case OpCodes.Log: {
     198            return Math.Log(Evaluate());
     199          }
     200        case OpCodes.IfThenElse: {
     201            double condition = Evaluate();
     202            double result;
     203            if (condition > 0.0) {
     204              result = Evaluate(); SkipBakedCode();
     205            } else {
     206              SkipBakedCode(); result = Evaluate();
     207            }
     208            return result;
     209          }
     210        case OpCodes.AND: {
     211            double result = Evaluate();
     212            for (int i = 1; i < currentInstr.nArguments; i++) {
     213              if (result <= 0.0) SkipBakedCode();
     214              else {
     215                result = Evaluate();
     216              }
     217            }
     218            return result <= 0.0 ? -1.0 : 1.0;
     219          }
     220        case OpCodes.OR: {
     221            double result = Evaluate();
     222            for (int i = 1; i < currentInstr.nArguments; i++) {
     223              if (result > 0.0) SkipBakedCode();
     224              else {
     225                result = Evaluate();
     226              }
     227            }
     228            return result > 0.0 ? 1.0 : -1.0;
     229          }
     230        case OpCodes.NOT: {
     231            return -Evaluate();
     232          }
     233        case OpCodes.GT: {
     234            double x = Evaluate();
     235            double y = Evaluate();
     236            if (x > y) return 1.0;
     237            else return -1.0;
     238          }
     239        case OpCodes.LT: {
     240            double x = Evaluate();
     241            double y = Evaluate();
     242            if (x < y) return 1.0;
     243            else return -1.0;
     244          }
    135245        case OpCodes.Call: {
    136246            // evaluate sub-trees
     
    163273            return dataset[row, currentInstr.iArg0] * variableTreeNode.Weight;
    164274          }
     275        case OpCodes.LagVariable: {
     276            var lagVariableTreeNode = currentInstr.dynamicNode as LaggedVariableTreeNode;
     277            int actualRow = row + lagVariableTreeNode.Lag;
     278            if (actualRow < 0 || actualRow >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);
     279            return dataset[actualRow, currentInstr.iArg0] * lagVariableTreeNode.Weight;
     280          }
    165281        case OpCodes.Constant: {
    166282            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
     
    170286      }
    171287    }
     288
     289    // skips a whole branch
     290    protected void SkipBakedCode() {
     291      int i = 1;
     292      while (i > 0) {
     293        i += code[pc++].nArguments;
     294        i--;
     295      }
     296    }
    172297  }
    173298}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/HeuristicLab.Problems.DataAnalysis.Tests-3.3.csproj

    r3733 r3841  
    8383    </ProjectReference>
    8484  </ItemGroup>
     85  <ItemGroup>
     86    <Folder Include="bin\" />
     87  </ItemGroup>
    8588  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    8689  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SimpleArithmeticExpressionInterpreterTest.cs

    r3746 r3841  
    2929using Microsoft.VisualStudio.TestTools.UnitTesting;
    3030using System.Linq;
     31using System.Globalization;
    3132namespace HeuristicLab.Problems.DataAnalysis.Tests {
    3233
     
    6364      twister = new MersenneTwister();
    6465      dataset = Util.CreateRandomDataset(twister, Rows, Columns);
    65       var grammar = new GlobalSymbolicExpressionGrammar(new ArithmeticExpressionGrammar());
     66      var grammar = new GlobalSymbolicExpressionGrammar(new FullFunctionalExpressionGrammar());
    6667      grammar.MaxFunctionArguments = 0;
    6768      grammar.MaxFunctionDefinitions = 0;
     
    133134      Evaluate(interpreter, ds, "(/ 8.0 2.0 2.0)", 0, 2.0);
    134135
     136      // gt
     137      Evaluate(interpreter, ds, "(> (variable 2.0 a) 2.0)", 0, -1.0);
     138      Evaluate(interpreter, ds, "(> 2.0 (variable 2.0 a))", 0, -1.0);
     139      Evaluate(interpreter, ds, "(> (variable 2.0 a) 1.9)", 0, 1.0);
     140      Evaluate(interpreter, ds, "(> 1.9 (variable 2.0 a))", 0, -1.0);
     141      //Evaluate(interpreter, ds, "(> (sqrt -1.0) (log -1.0))", 0, -1.0); // (> nan nan) should be false
     142
     143      // lt
     144      Evaluate(interpreter, ds, "(< (variable 2.0 a) 2.0)", 0, -1.0);
     145      Evaluate(interpreter, ds, "(< 2.0 (variable 2.0 a))", 0, -1.0);
     146      Evaluate(interpreter, ds, "(< (variable 2.0 a) 1.9)", 0, -1.0);
     147      Evaluate(interpreter, ds, "(< 1.9 (variable 2.0 a))", 0, 1.0);
     148      //Evaluate(interpreter, ds, "(< (sqrt -1,0) (log -1,0))", 0, -1.0); // (< nan nan) should be false
     149
     150      // If
     151      Evaluate(interpreter, ds, "(if -10.0 2.0 3.0)", 0, 3.0);
     152      Evaluate(interpreter, ds, "(if -1.0 2.0 3.0)", 0, 3.0);
     153      Evaluate(interpreter, ds, "(if 0.0 2.0 3.0)", 0, 3.0);
     154      Evaluate(interpreter, ds, "(if 1.0 2.0 3.0)", 0, 2.0);
     155      Evaluate(interpreter, ds, "(if 10.0 2.0 3.0)", 0, 2.0);
     156      // Evaluate(interpreter, ds, "(if (sqrt -1.0) 2.0 3.0)", 0, 3.0); // if(nan) should return the else branch
     157
     158      // NOT
     159      Evaluate(interpreter, ds, "(not -1.0)", 0, 1.0);
     160      Evaluate(interpreter, ds, "(not -2.0)", 0, 2.0);
     161      Evaluate(interpreter, ds, "(not 1.0)", 0, -1.0);
     162      Evaluate(interpreter, ds, "(not 2.0)", 0, -2.0);
     163      Evaluate(interpreter, ds, "(not 0.0)", 0, 0.0);
     164
     165      // AND
     166      Evaluate(interpreter, ds, "(and -1.0 -2.0)", 0, -1.0);
     167      Evaluate(interpreter, ds, "(and -1.0 2.0)", 0, -1.0);
     168      Evaluate(interpreter, ds, "(and 1.0 -2.0)", 0, -1.0);
     169      Evaluate(interpreter, ds, "(and 1.0 0.0)", 0, -1.0);
     170      Evaluate(interpreter, ds, "(and 0.0 0.0)", 0, -1.0);
     171      Evaluate(interpreter, ds, "(and 1.0 2.0)", 0, 1.0);
     172      Evaluate(interpreter, ds, "(and 1.0 2.0 3.0)", 0, 1.0);
     173      Evaluate(interpreter, ds, "(and 1.0 -2.0 3.0)", 0, -1.0);
     174
     175      // OR
     176      Evaluate(interpreter, ds, "(or -1.0 -2.0)", 0, -1.0);
     177      Evaluate(interpreter, ds, "(or -1.0 2.0)", 0, 1.0);
     178      Evaluate(interpreter, ds, "(or 1.0 -2.0)", 0, 1.0);
     179      Evaluate(interpreter, ds, "(or 1.0 2.0)", 0, 1.0);
     180      Evaluate(interpreter, ds, "(or 0.0 0.0)", 0, -1.0);
     181      Evaluate(interpreter, ds, "(or -1.0 -2.0 -3.0)", 0, -1.0);
     182      Evaluate(interpreter, ds, "(or -1.0 -2.0 3.0)", 0, 1.0);
     183
     184      // sin, cos, tan
     185      Evaluate(interpreter, ds, "(sin " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, 0.0);
     186      Evaluate(interpreter, ds, "(sin 0.0)", 0, 0.0);
     187      Evaluate(interpreter, ds, "(cos " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, -1.0);
     188      Evaluate(interpreter, ds, "(cos 0.0)", 0, 1.0);
     189      Evaluate(interpreter, ds, "(tan " + Math.PI.ToString(NumberFormatInfo.InvariantInfo) + ")", 0, Math.Tan(Math.PI));
     190      Evaluate(interpreter, ds, "(tan 0.0)", 0, Math.Tan(Math.PI));
     191
     192      // exp, log
     193      Evaluate(interpreter, ds, "(log (exp 7.0))", 0, Math.Log(Math.Exp(7)));
     194      Evaluate(interpreter, ds, "(exp (log 7.0))", 0, Math.Exp(Math.Log(7)));
     195      Evaluate(interpreter, ds, "(log -3.0)", 0, Math.Log(-3));
     196
     197      // mean
     198      Evaluate(interpreter, ds, "(mean -1.0 1.0 -1.0)", 0, -1.0 / 3.0);
     199
    135200      // ADF     
    136201      Evaluate(interpreter, ds, @"(PROG
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs

    r3746 r3841  
    4242        {"*", new Multiplication()},
    4343        {"-", new Subtraction()},
     44        {"EXP", new Exponential()},
     45        {"LOG", new Logarithm()},
     46        {"SIN",new Sine()},
     47        {"COS", new Cosine()},
     48        {"TAN", new Tangent()},
     49        {"MEAN", new Average()},
     50        {"IF", new IfThenElse()},
     51        {">", new GreaterThan()},
     52        {"<", new LessThan()},
     53        {"AND", new And()},
     54        {"OR", new Or()},
     55        {"NOT", new Not()},
    4456        {"PROG", new ProgramRootSymbol()},
    45         {"MAIN", new StartSymbol()}
     57        {"MAIN", new StartSymbol()},
    4658      };
    4759
Note: See TracChangeset for help on using the changeset viewer.