Index: /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
===================================================================
--- /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 16238)
+++ /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs	(revision 16239)
@@ -37,4 +37,5 @@
     private static readonly Division divSymbol = new Division();
     private static readonly Constant constSymbol = new Constant();
+    private static readonly Absolute absSymbol = new Absolute();
     private static readonly Logarithm logSymbol = new Logarithm();
     private static readonly Exponential expSymbol = new Exponential();
@@ -42,4 +43,7 @@
     private static readonly Square sqrSymbol = new Square();
     private static readonly SquareRoot sqrtSymbol = new SquareRoot();
+    private static readonly AnalyticalQuotient aqSymbol = new AnalyticalQuotient();
+    private static readonly Cube cubeSymbol = new Cube();
+    private static readonly CubeRoot cubeRootSymbol = new CubeRoot();
     private static readonly Power powSymbol = new Power();
     private static readonly Sine sineSymbol = new Sine();
@@ -131,4 +135,8 @@
     }
 
+    private static bool IsAbsolute(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Absolute;
+    }
+
     // exponential
     private static bool IsLog(ISymbolicExpressionTreeNode node) {
@@ -152,4 +160,12 @@
     }
 
+    private static bool IsCube(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is Cube;
+    }
+
+    private static bool IsCubeRoot(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is CubeRoot;
+    }
+
     private static bool IsPower(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Power;
@@ -167,4 +183,8 @@
     private static bool IsTangent(ISymbolicExpressionTreeNode node) {
       return node.Symbol is Tangent;
+    }
+
+    private static bool IsAnalyticalQuotient(ISymbolicExpressionTreeNode node) {
+      return node.Symbol is AnalyticalQuotient;
     }
 
@@ -261,4 +281,8 @@
       } else if (IsSquareRoot(original)) {
         return SimplifySquareRoot(original);
+      } else if (IsCube(original)) {
+        return SimplifyCube(original);
+      } else if (IsCubeRoot(original)) {
+        return SimplifyCubeRoot(original);
       } else if (IsPower(original)) {
         return SimplifyPower(original);
@@ -271,4 +295,6 @@
       } else if (IsTangent(original)) {
         return SimplifyTangent(original);
+      } else if (IsAnalyticalQuotient(original)) {
+        return SimplifyAnalyticalQuotient(original);
       } else if (IsIfThenElse(original)) {
         return SimplifyIfThenElse(original);
@@ -380,4 +406,8 @@
     }
 
+    private static ISymbolicExpressionTreeNode SimplifyAbsolute(ISymbolicExpressionTreeNode original) {
+      return MakeAbs(GetSimplifiedTree(original.GetSubtree(0)));
+    }
+
     private static ISymbolicExpressionTreeNode SimplifyNot(ISymbolicExpressionTreeNode original) {
       return MakeNot(GetSimplifiedTree(original.GetSubtree(0)));
@@ -432,4 +462,11 @@
       return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0)));
     }
+    private static ISymbolicExpressionTreeNode SimplifyCube(ISymbolicExpressionTreeNode original) {
+      return MakeCube(GetSimplifiedTree(original.GetSubtree(0)));
+    }
+
+    private static ISymbolicExpressionTreeNode SimplifyCubeRoot(ISymbolicExpressionTreeNode original) {
+      return MakeCubeRoot(GetSimplifiedTree(original.GetSubtree(0)));
+    }
 
     private static ISymbolicExpressionTreeNode SimplifyLog(ISymbolicExpressionTreeNode original) {
@@ -443,4 +480,8 @@
     private static ISymbolicExpressionTreeNode SimplifyPower(ISymbolicExpressionTreeNode original) {
       return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
+    }
+
+    private static ISymbolicExpressionTreeNode SimplifyAnalyticalQuotient(ISymbolicExpressionTreeNode original) {
+      return MakeAnalyticalQuotient(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)));
     }
 
@@ -737,4 +778,59 @@
     }
 
+    private static ISymbolicExpressionTreeNode MakeCube(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(constT.Value * constT.Value * constT.Value);
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w * w * w));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, binFactor.Weight * binFactor.Weight * binFactor.Weight);
+      } else if (IsCubeRoot(node)) {
+        return node.GetSubtree(0); // NOTE: not really accurate because cuberoot(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
+      } else {
+        var cubeNode = cubeSymbol.CreateTreeNode();
+        cubeNode.AddSubtree(node);
+        return cubeNode;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeAbs(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(Math.Abs(constT.Value));
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Abs(w)));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Abs(binFactor.Weight));
+      } else {
+        var absNode = absSymbol.CreateTreeNode();
+        absNode.AddSubtree(node);
+        return absNode;
+      }
+    }
+
+    // constant folding only
+    private static ISymbolicExpressionTreeNode MakeAnalyticalQuotient(ISymbolicExpressionTreeNode x1, ISymbolicExpressionTreeNode x2) {
+      if (IsConstant(x2)) {
+        var c = x2 as ConstantTreeNode;
+        return MakeFraction(x1, MakeConstant(Math.Sqrt(1.0 + c.Value*c.Value)));
+      } else if (IsFactor(x2)) {
+        var factNode = x2 as FactorVariableTreeNode;
+        return MakeFraction(x1, MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(1.0 + w * w))));
+      } else if (IsBinFactor(x2)) {
+        var binFactor = x2 as BinaryFactorVariableTreeNode;
+        return MakeFraction(x1, MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(1.0 + binFactor.Weight * binFactor.Weight)));
+      } else {
+        var aqNode = aqSymbol.CreateTreeNode();
+        aqNode.AddSubtree(x1);
+        aqNode.AddSubtree(x2);
+        return aqNode;
+      }
+    }
+
     private static ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) {
       if (IsConstant(node)) {
@@ -748,9 +844,28 @@
         return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(binFactor.Weight));
       } else if (IsSquare(node)) {
-        return node.GetSubtree(0);
+        return node.GetSubtree(0); // NOTE: not really accurate because sqrt(x) with negative x is evaluated to NaN and after this simplification we evaluate as x
       } else {
         var sqrtNode = sqrtSymbol.CreateTreeNode();
         sqrtNode.AddSubtree(node);
         return sqrtNode;
+      }
+    }
+
+    private static ISymbolicExpressionTreeNode MakeCubeRoot(ISymbolicExpressionTreeNode node) {
+      if (IsConstant(node)) {
+        var constT = node as ConstantTreeNode;
+        return MakeConstant(Math.Pow(constT.Value, 1.0 / 3.0));
+      } else if (IsFactor(node)) {
+        var factNode = node as FactorVariableTreeNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, 1.0 / 3.0)));
+      } else if (IsBinFactor(node)) {
+        var binFactor = node as BinaryFactorVariableTreeNode;
+        return MakeBinFactor(binFactor.Symbol, binFactor.VariableName, binFactor.VariableValue, Math.Sqrt(Math.Pow(binFactor.Weight, 1.0 / 3.0)));
+      } else if (IsCube(node)) {
+        return node.GetSubtree(0);
+      } else {
+        var cubeRootNode = cubeRootSymbol.CreateTreeNode();
+        cubeRootNode.AddSubtree(node);
+        return cubeRootNode;
       }
     }
Index: /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
===================================================================
--- /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16238)
+++ /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs	(revision 16239)
@@ -85,4 +85,9 @@
       diff: x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI));
 
+    private static readonly Func<Term, UnaryFunc> abs = UnaryFunc.Factory(
+      eval: Math.Abs,
+      diff: x => Math.Sign(x)
+      );
+
     #endregion
 
@@ -213,5 +218,9 @@
         else return terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
       }
-      if(node.Symbol is AnalyticalQuotient) {
+      if (node.Symbol is Absolute) {
+        var x1 = ConvertToAutoDiff(node.GetSubtree(0));
+        return abs(x1);
+      }
+      if (node.Symbol is AnalyticalQuotient) {
         var x1 = ConvertToAutoDiff(node.GetSubtree(0));
         var x2 = ConvertToAutoDiff(node.GetSubtree(1));
@@ -233,4 +242,12 @@
         return AutoDiff.TermBuilder.Power(
           ConvertToAutoDiff(node.GetSubtree(0)), 0.5);
+      }
+      if (node.Symbol is Cube) {
+        return AutoDiff.TermBuilder.Power(
+          ConvertToAutoDiff(node.GetSubtree(0)), 3.0);
+      }
+      if (node.Symbol is CubeRoot) {
+        return AutoDiff.TermBuilder.Power(
+          ConvertToAutoDiff(node.GetSubtree(0)), 1.0/3.0);
       }
       if (node.Symbol is Sine) {
@@ -306,5 +323,9 @@
           !(n.Symbol is Erf) &&
           !(n.Symbol is Norm) &&
-          !(n.Symbol is StartSymbol)
+          !(n.Symbol is StartSymbol) &&
+          !(n.Symbol is Absolute) &&
+          !(n.Symbol is AnalyticalQuotient) &&
+          !(n.Symbol is Cube) &&
+          !(n.Symbol is CubeRoot)
         select n).Any();
       return !containsUnknownSymbol;
Index: /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
===================================================================
--- /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 16238)
+++ /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs	(revision 16239)
@@ -102,4 +102,6 @@
         { "SQR", new Square() },
         { "SQRT", new SquareRoot() },
+        { "CUBE", new Cube() },
+        { "CUBEROOT", new CubeRoot() },
         { "SIN",new Sine()},
         { "COS", new Cosine()},
@@ -120,4 +122,5 @@
         { "DAWSON", new Dawson()},
         { "EXPINT", new ExponentialIntegralEi()},
+        { "AQ", new AnalyticalQuotient() },
         { "MEAN", new Average()},
         { "IF", new IfThenElse()},
Index: /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs
===================================================================
--- /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs	(revision 16238)
+++ /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs	(revision 16239)
@@ -41,4 +41,5 @@
         {"*", new Multiplication()},
         {"-", new Subtraction()},
+        {"ABS", new Absolute() },
         {"EXP", new Exponential()},
         {"LOG", new Logarithm()},
@@ -47,4 +48,6 @@
         {"SQR", new Square()},
         {"SQRT", new SquareRoot()},
+        {"CUBE", new Cube()},
+        {"CUBEROOT", new CubeRoot()},
         {"SIN",new Sine()},
         {"COS", new Cosine()},
@@ -65,4 +68,5 @@
         {"DAWSON", new Dawson()},
         {"EXPINT", new ExponentialIntegralEi()},
+        {"AQ", new AnalyticalQuotient() },
         {"MEAN", new Average()},
         {"IF", new IfThenElse()},
Index: /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
===================================================================
--- /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 16238)
+++ /branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs	(revision 16239)
@@ -233,7 +233,7 @@
         } else if (instr.opCode == OpCodes.Tan) {
           instr.value = Math.Tan(code[instr.childIndex].value);
-        } else if(instr.opCode == OpCodes.Square) {
+        } else if (instr.opCode == OpCodes.Square) {
           instr.value = Math.Pow(code[instr.childIndex].value, 2);
-        } else if(instr.opCode == OpCodes.Cube) {
+        } else if (instr.opCode == OpCodes.Cube) {
           instr.value = Math.Pow(code[instr.childIndex].value, 3);
         } else if (instr.opCode == OpCodes.Power) {
@@ -241,7 +241,7 @@
           double y = Math.Round(code[instr.childIndex + 1].value);
           instr.value = Math.Pow(x, y);
-        } else if(instr.opCode == OpCodes.SquareRoot) {
+        } else if (instr.opCode == OpCodes.SquareRoot) {
           instr.value = Math.Sqrt(code[instr.childIndex].value);
-        } else if(instr.opCode == OpCodes.CubeRoot) {
+        } else if (instr.opCode == OpCodes.CubeRoot) {
           instr.value = Math.Pow(code[instr.childIndex].value, 1.0 / 3.0);
         } else if (instr.opCode == OpCodes.Root) {
