Changeset 18172


Ignore:
Timestamp:
12/27/21 10:59:13 (6 months ago)
Author:
gkronber
Message:

#3145: removed unnecessary parenthesis in InfixExpressionFormatter (and adapted the unit tests slightly)

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r18132 r18172  
    3737        var token = GetToken(node.Symbol);
    3838        // operators
    39         if (token == "+" || token == "-" || token == "OR" || token == "XOR" ||
    40             token == "*" || token == "/" || token == "AND") {
    41           strBuilder.Append("(");
     39        if (token == "+" || token == "-" || token == "OR" || token == "XOR") {
     40          var parenthesisRequired = false;
     41          if (node.Parent != null && node.Parent.SubtreeCount > 1) {
     42            var parentOp = GetToken(node.Parent.Symbol);
     43            if (parentOp != "+" && parentOp != "-" && parentOp != "OR" && parentOp != "XOR")
     44              parenthesisRequired = true;
     45          }
     46          if (parenthesisRequired) strBuilder.Append("(");
    4247          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
    4348
     
    4752          }
    4853
    49           strBuilder.Append(")");
     54          if (parenthesisRequired) strBuilder.Append(")");
     55        } else if (token == "*" || token == "/" || token == "AND") {
     56          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
     57
     58          foreach (var subtree in node.Subtrees.Skip(1)) {
     59            strBuilder.Append(" ").Append(token).Append(" ");
     60            // a / b * c => a / (b * C)
     61            if (subtree.SubtreeCount > 1 && token == "/" && GetToken(subtree.Symbol) == "*") {
     62              strBuilder.Append("(");
     63              FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
     64              strBuilder.Append(")");
     65            } else {
     66              FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
     67            }
     68          }
    5069        } else if (token == "^") {
    5170          // handle integer powers directly
    52           strBuilder.Append("(");
    5371          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
    5472
    5573          var power = node.GetSubtree(1);
    56           if(power is INumericTreeNode numNode && Math.Truncate(numNode.Value) == numNode.Value) {
     74          if (power is INumericTreeNode numNode && Math.Truncate(numNode.Value) == numNode.Value) {
    5775            strBuilder.Append(" ").Append(token).Append(" ").Append(numNode.Value.ToString(formatString, numberFormat));
    5876          } else {
     
    6078            FormatRecursively(power, strBuilder, numberFormat, formatString, parameters);
    6179          }
    62 
    63           strBuilder.Append(")");
    6480        } else {
    6581          // function with multiple arguments
     
    7692        var token = GetToken(node.Symbol);
    7793        if (token == "-" || token == "NOT") {
    78           strBuilder.Append("(").Append(token).Append("(");
    79           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    80           strBuilder.Append("))");
     94          strBuilder.Append(token);
     95          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    8196        } else if (token == "/") {
    8297          strBuilder.Append("1/");
     
    95110          var varNode = node as LaggedVariableTreeNode;
    96111          if (!varNode.Weight.IsAlmost(1.0)) {
    97             strBuilder.Append("(");
    98112            AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
    99113            strBuilder.Append("*");
     
    105119                    .AppendFormat(numberFormat, "{0}", varNode.Lag)
    106120                    .Append(")");
    107           if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    108121        } else if (node.Symbol is Variable) {
    109122          var varNode = node as VariableTreeNode;
    110123          if (!varNode.Weight.IsAlmost(1.0)) {
    111             strBuilder.Append("(");
    112124            AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
    113125            strBuilder.Append("*");
    114126          }
    115 
    116127          AppendVariableName(strBuilder, varNode.VariableName);
    117 
    118           if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    119128        } else if (node.Symbol is FactorVariable) {
    120129          var factorNode = node as FactorVariableTreeNode;
     
    130139          var factorNode = node as BinaryFactorVariableTreeNode;
    131140          if (!factorNode.Weight.IsAlmost(1.0)) {
    132             strBuilder.Append("(");
    133141            AppendNumber(strBuilder, parameters, factorNode.Weight, formatString, numberFormat);
    134 
    135142            strBuilder.Append("*");
    136143          }
    137 
    138144          AppendVariableName(strBuilder, factorNode.VariableName);
    139145          strBuilder.Append(" = ");
    140146          AppendVariableName(strBuilder, factorNode.VariableValue);
    141 
    142           if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    143147        } else if (node is INumericTreeNode numNode) {
    144148          if (parameters == null && numNode.Value < 0) {
    145149            // negative value
    146             strBuilder.Append("(").Append(numNode.Value.ToString(formatString, numberFormat))
    147                       .Append(")");
     150            strBuilder.Append(numNode.Value.ToString(formatString, numberFormat));
    148151          } else {
    149152            AppendNumber(strBuilder, parameters, numNode.Value, formatString, numberFormat);
  • trunk/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/DeriveTest.cs

    r18170 r18172  
    4343      Assert.AreEqual("20", Derive("<num=10>*x+<num=20>*y", "y"));
    4444      Assert.AreEqual("6", Derive("<num=2>*<num=3>*x", "x"));
    45       Assert.AreEqual("10 * 'y'", Derive("<num=10>*x*y+<num=20>*y", "x"));
    46       Assert.AreEqual("(1 / (SQR('x') * (-1)))", Derive("1/x", "x"));
    47       Assert.AreEqual("'y' / (SQR('x') * -1)", Derive("y/x", "x"));
    48       Assert.AreEqual("(-2*'x' + -1) * ('a' + 'b') / SQR('x' + 'x' * 'x')",
     45      Assert.AreEqual("10*'y'", Derive("<num=10>*x*y+<num=20>*y", "x"));
     46      Assert.AreEqual("1 * -1 / SQR('x')", Derive("1/x", "x"));
     47      Assert.AreEqual("-1*'y' / SQR('x')", Derive("y/x", "x"));
     48      Assert.AreEqual("('a' + 'b') * (-2*'x' + -1) / SQR('x' + 'x' * 'x')",
    4949        Derive("(a+b)/(x+x*x)", "x"));
    50       Assert.AreEqual("(-2*'x' + -1) * ('a' + 'b') / SQR('x' + SQR('x'))", Derive("(a+b)/(x+SQR(x))", "x"));
     50      Assert.AreEqual("('a' + 'b') * (-2*'x' + -1) / SQR('x' + SQR('x'))", Derive("(a+b)/(x+SQR(x))", "x"));
    5151      Assert.AreEqual("EXP('x')", Derive("exp(x)", "x"));
    5252      Assert.AreEqual("EXP(3*'x') * 3", Derive("exp(<num=3>*x)", "x"));
     
    6767
    6868      Assert.AreEqual("'a' * 'b' * 'c'", Derive("a*b*c*d", "d"));
    69       Assert.AreEqual("'a' / ('b' * 'c' * SQR('d') * -1)", Derive("a/b/c/d", "d"));
     69      Assert.AreEqual("'b' * 'c' * -1*'a' / (SQR('b') * SQR('c') * SQR('d'))", Derive("a/b/c/d", "d")); // TODO simplifier should be able to simplify this
    7070
    7171      Assert.AreEqual("'x' * (SQR(TANH(SQR('x'))) * -1 + 1) * 2", Derive("tanh(sqr(x))", "x")); // (2*'x'*(1 - SQR(TANH(SQR('x'))))
     
    8484        root.AddSubtree(start);
    8585        var t = new SymbolicExpressionTree(root);
    86         Assert.AreEqual("(1 / (SQR('x') * (-1)))",
     86        Assert.AreEqual("1 / (SQR('x') * -1)",
    8787          formatter.Format(DerivativeCalculator.Derive(t, "x")));
    8888      }
Note: See TracChangeset for help on using the changeset viewer.