Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
02/15/11 13:36:45 (13 years ago)
Author:
gkronber
Message:

#1227 implemented test cases and transformation rules for root and power symbols.

Location:
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3
Files:
3 edited

Legend:

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

    r5461 r5465  
    4242    private Logarithm logSymbol = new Logarithm();
    4343    private Exponential expSymbol = new Exponential();
     44    private Root rootSymbol = new Root();
     45    private Power powSymbol = new Power();
    4446    private Sine sineSymbol = new Sine();
    4547    private Cosine cosineSymbol = new Cosine();
     
    122124    private bool IsExp(SymbolicExpressionTreeNode node) {
    123125      return node.Symbol is Exponential;
     126    }
     127    private bool IsRoot(SymbolicExpressionTreeNode node) {
     128      return node.Symbol is Root;
     129    }
     130    private bool IsPower(SymbolicExpressionTreeNode node) {
     131      return node.Symbol is Power;
    124132    }
    125133    // trigonometric
     
    195203      } else if (IsExp(original)) {
    196204        return SimplifyExp(original);
     205      } else if (IsRoot(original)) {
     206        return SimplifyRoot(original);
     207      } else if (IsPower(original)) {
     208        return SimplifyPower(original);
    197209      } else if (IsSine(original)) {
    198210        return SimplifySine(original);
     
    347359      return MakeLog(GetSimplifiedTree(original.SubTrees[0]));
    348360    }
    349 
     361    private SymbolicExpressionTreeNode SimplifyRoot(SymbolicExpressionTreeNode original) {
     362      return MakeRoot(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]));
     363    }
     364
     365    private SymbolicExpressionTreeNode SimplifyPower(SymbolicExpressionTreeNode original) {
     366      return MakePower(GetSimplifiedTree(original.SubTrees[0]), GetSimplifiedTree(original.SubTrees[1]));
     367    }
    350368    #endregion
    351 
    352 
    353369
    354370    #region low level tree restructuring
     
    462478
    463479    private SymbolicExpressionTreeNode MakeSine(SymbolicExpressionTreeNode node) {
    464       // todo implement more transformation rules
    465480      if (IsConstant(node)) {
    466481        var constT = node as ConstantTreeNode;
     
    473488    }
    474489    private SymbolicExpressionTreeNode MakeTangent(SymbolicExpressionTreeNode node) {
    475       // todo implement more transformation rules
    476490      if (IsConstant(node)) {
    477491        var constT = node as ConstantTreeNode;
     
    484498    }
    485499    private SymbolicExpressionTreeNode MakeCosine(SymbolicExpressionTreeNode node) {
    486       // todo implement more transformation rules
    487500      if (IsConstant(node)) {
    488501        var constT = node as ConstantTreeNode;
     
    495508    }
    496509    private SymbolicExpressionTreeNode MakeExp(SymbolicExpressionTreeNode node) {
    497       // todo implement more transformation rules
    498510      if (IsConstant(node)) {
    499511        var constT = node as ConstantTreeNode;
     
    501513      } else if (IsLog(node)) {
    502514        return node.SubTrees[0];
     515      } else if (IsAddition(node)) {
     516        return node.SubTrees.Select(s => MakeExp(s)).Aggregate((s, t) => MakeProduct(s, t));
     517      } else if (IsSubtraction(node)) {
     518        return node.SubTrees.Select(s => MakeExp(s)).Aggregate((s, t) => MakeProduct(s, Negate(t)));
    503519      } else {
    504520        var expNode = expSymbol.CreateTreeNode();
     
    508524    }
    509525    private SymbolicExpressionTreeNode MakeLog(SymbolicExpressionTreeNode node) {
    510       // todo implement more transformation rules
    511526      if (IsConstant(node)) {
    512527        var constT = node as ConstantTreeNode;
     
    526541        logNode.AddSubTree(node);
    527542        return logNode;
     543      }
     544    }
     545    private SymbolicExpressionTreeNode MakeRoot(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
     546      if (IsConstant(a) && IsConstant(b)) {
     547        var constA = a as ConstantTreeNode;
     548        var constB = b as ConstantTreeNode;
     549        return MakeConstant(Math.Pow(constA.Value, 1.0 / Math.Round(constB.Value)));
     550      } else if (IsConstant(b)) {
     551        var constB = b as ConstantTreeNode;
     552        var constBValue = Math.Round(constB.Value);
     553        if (constBValue.IsAlmost(1.0)) {
     554          return a;
     555        } else if (constBValue.IsAlmost(0.0)) {
     556          return MakeConstant(1.0);
     557        } else if (constBValue.IsAlmost(-1.0)) {
     558          return MakeFraction(MakeConstant(1.0), a);
     559        } else if (constBValue < 0) {
     560          var rootNode = rootSymbol.CreateTreeNode();
     561          rootNode.AddSubTree(a);
     562          rootNode.AddSubTree(MakeConstant(-1.0 * constBValue));
     563          return MakeFraction(MakeConstant(1.0), rootNode);
     564        } else {
     565          var rootNode = rootSymbol.CreateTreeNode();
     566          rootNode.AddSubTree(a);
     567          rootNode.AddSubTree(MakeConstant(constBValue));
     568          return rootNode;
     569        }
     570      } else {
     571        var rootNode = rootSymbol.CreateTreeNode();
     572        rootNode.AddSubTree(a);
     573        rootNode.AddSubTree(b);
     574        return rootNode;
     575      }
     576    }
     577    private SymbolicExpressionTreeNode MakePower(SymbolicExpressionTreeNode a, SymbolicExpressionTreeNode b) {
     578      if (IsConstant(a) && IsConstant(b)) {
     579        var constA = a as ConstantTreeNode;
     580        var constB = b as ConstantTreeNode;
     581        return MakeConstant(Math.Pow(constA.Value, Math.Round(constB.Value)));
     582      } else if (IsConstant(b)) {
     583        var constB = b as ConstantTreeNode;
     584        double exponent = Math.Round(constB.Value);
     585        if (exponent.IsAlmost(0.0)) {
     586          return MakeConstant(1.0);
     587        } else if (exponent.IsAlmost(1.0)) {
     588          return a;
     589        } else if (exponent.IsAlmost(-1.0)) {
     590          return MakeFraction(MakeConstant(1.0), a);
     591        } else if (exponent < 0) {
     592          var powNode = powSymbol.CreateTreeNode();
     593          powNode.AddSubTree(a);
     594          powNode.AddSubTree(MakeConstant(-1.0 * exponent));
     595          return MakeFraction(MakeConstant(1.0), powNode);
     596        } else {
     597          var powNode = powSymbol.CreateTreeNode();
     598          powNode.AddSubTree(a);
     599          powNode.AddSubTree(MakeConstant(exponent));
     600          return powNode;
     601        }
     602      } else {
     603        var powNode = powSymbol.CreateTreeNode();
     604        powNode.AddSubTree(a);
     605        powNode.AddSubTree(b);
     606        return powNode;
    528607      }
    529608    }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs

    r5445 r5465  
    4242        {"EXP", new Exponential()},
    4343        {"LOG", new Logarithm()},
     44        {"POW", new Power()},
     45        {"ROOT", new Root()},
    4446        {"SIN",new Sine()},
    4547        {"COS", new Cosine()},
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicSimplifierTest.cs

    r5461 r5465  
    170170      {
    171171        // cancellation
    172         var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
    173         var expectedTree = importer.Import("(variable 2.0 a)");
    174         Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
    175       }
    176       {
    177         // cancellation
    178172        var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))"));
    179173        var expectedTree = importer.Import("(variable 2.0 a)");
     
    190184        var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 2.0 a) (variable 3.0 b)))"));
    191185        var expectedTree = importer.Import("(- (log (variable 2.0 a)) (log (variable 3.0 b)))");
     186        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     187      }
     188      #endregion
     189      #region exponentiation rules
     190      {
     191        // cancellation
     192        var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))"));
     193        var expectedTree = importer.Import("(variable 2.0 a)");
     194        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     195      }
     196      {
     197        // exp transformation
     198        var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))"));
     199        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))");
     200        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     201      }
     202      {
     203        // exp transformation
     204        var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))"));
     205        var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))");
     206        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     207      }
     208      #endregion
     209      #region power rules
     210      {
     211        // cancellation
     212        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)"));
     213        var expectedTree = importer.Import("1.0");
     214        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     215      }
     216      {
     217        // fixed point
     218        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)"));
     219        var expectedTree = importer.Import("(variable 2.0 a)");
     220        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     221      }
     222      {
     223        // inversion fixed point
     224        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)"));
     225        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
     226        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     227      }
     228      {
     229        // inversion
     230        var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)"));
     231        var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))");
     232        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     233      }
     234      {
     235        // constant folding
     236        var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)"));
     237        var expectedTree = importer.Import("9.0");
     238        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     239      }
     240      #endregion
     241      #region root rules
     242      {
     243        // cancellation
     244        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)"));
     245        var expectedTree = importer.Import("1.0");
     246        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     247      }
     248      {
     249        // fixed point
     250        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)"));
     251        var expectedTree = importer.Import("(variable 2.0 a)");
     252        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     253      }
     254      {
     255        // inversion fixed point
     256        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)"));
     257        var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))");
     258        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     259      }
     260      {
     261        // inversion
     262        var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)"));
     263        var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))");
     264        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
     265      }
     266      {
     267        // constant folding
     268        var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)"));
     269        var expectedTree = importer.Import("3.0");
    192270        Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree));
    193271      }
Note: See TracChangeset for help on using the changeset viewer.