Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/15/21 11:50:57 (2 years ago)
Author:
gkronber
Message:

#3140: merged r18091:18131 from branch to trunk

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/HeuristicLab.Problems.DataAnalysis.Symbolic

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

    r17811 r18132  
    3333  public static class BaseInfixExpressionFormatter {
    3434    public static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder,
    35                                           NumberFormatInfo numberFormat, string formatString, List<KeyValuePair<string, double>> constants = null) {
     35                                          NumberFormatInfo numberFormat, string formatString, List<KeyValuePair<string, double>> parameters = null) {
    3636      if (node.SubtreeCount > 1) {
    3737        var token = GetToken(node.Symbol);
     
    4040            token == "*" || token == "/" || token == "AND") {
    4141          strBuilder.Append("(");
    42           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     42          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
    4343
    4444          foreach (var subtree in node.Subtrees.Skip(1)) {
    4545            strBuilder.Append(" ").Append(token).Append(" ");
    46             FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
     46            FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
    4747          }
    4848
     
    5151          // handle integer powers directly
    5252          strBuilder.Append("(");
    53           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     53          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
    5454
    5555          var power = node.GetSubtree(1);
    56           if(power is ConstantTreeNode constNode && Math.Truncate(constNode.Value) == constNode.Value) {
    57             strBuilder.Append(" ").Append(token).Append(" ").Append(constNode.Value.ToString(formatString, numberFormat));
     56          if(power is INumericTreeNode numNode && Math.Truncate(numNode.Value) == numNode.Value) {
     57            strBuilder.Append(" ").Append(token).Append(" ").Append(numNode.Value.ToString(formatString, numberFormat));
    5858          } else {
    5959            strBuilder.Append(" ").Append(token).Append(" ");
    60             FormatRecursively(power, strBuilder, numberFormat, formatString, constants);
     60            FormatRecursively(power, strBuilder, numberFormat, formatString, parameters);
    6161          }
    6262
     
    6565          // function with multiple arguments
    6666          strBuilder.Append(token).Append("(");
    67           FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants);
     67          FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, parameters);
    6868          foreach (var subtree in node.Subtrees.Skip(1)) {
    6969            strBuilder.Append(", ");
    70             FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants);
     70            FormatRecursively(subtree, strBuilder, numberFormat, formatString, parameters);
    7171          }
    7272
     
    7777        if (token == "-" || token == "NOT") {
    7878          strBuilder.Append("(").Append(token).Append("(");
    79           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     79          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    8080          strBuilder.Append("))");
    8181        } else if (token == "/") {
    8282          strBuilder.Append("1/");
    83           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     83          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    8484        } else if (token == "+" || token == "*") {
    85           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     85          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    8686        } else {
    8787          // function with only one argument
    8888          strBuilder.Append(token).Append("(");
    89           FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants);
     89          FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, parameters);
    9090          strBuilder.Append(")");
    9191        }
     
    9696          if (!varNode.Weight.IsAlmost(1.0)) {
    9797            strBuilder.Append("(");
    98             AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
     98            AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
    9999            strBuilder.Append("*");
    100100          }
     
    110110          if (!varNode.Weight.IsAlmost(1.0)) {
    111111            strBuilder.Append("(");
    112             AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat);
     112            AppendNumber(strBuilder, parameters, varNode.Weight, formatString, numberFormat);
    113113            strBuilder.Append("*");
    114114          }
     
    124124          for (int i = 0; i < factorNode.Weights.Length; i++) {
    125125            if (i > 0) strBuilder.Append(", ");
    126             AppendConstant(strBuilder, constants, factorNode.Weights[i], formatString, numberFormat);
     126            AppendNumber(strBuilder, parameters, factorNode.Weights[i], formatString, numberFormat);
    127127          }
    128128          strBuilder.Append("]");
     
    131131          if (!factorNode.Weight.IsAlmost(1.0)) {
    132132            strBuilder.Append("(");
    133             AppendConstant(strBuilder, constants, factorNode.Weight, formatString, numberFormat);
     133            AppendNumber(strBuilder, parameters, factorNode.Weight, formatString, numberFormat);
    134134
    135135            strBuilder.Append("*");
     
    141141
    142142          if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")");
    143         } else if (node.Symbol is Constant) {
    144           var constNode = node as ConstantTreeNode;
    145           if (constants == null && constNode.Value < 0) {
    146             strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat))
    147                       .Append(")"); // (-1
     143        } else if (node is INumericTreeNode numNode) {
     144          if (parameters == null && numNode.Value < 0) {
     145            // negative value
     146            strBuilder.Append("(").Append(numNode.Value.ToString(formatString, numberFormat))
     147                      .Append(")");
    148148          } else {
    149             AppendConstant(strBuilder, constants, constNode.Value, formatString, numberFormat);
     149            AppendNumber(strBuilder, parameters, numNode.Value, formatString, numberFormat);
    150150          }
    151151        }
     
    153153    }
    154154
    155     private static void AppendConstant(StringBuilder strBuilder, List<KeyValuePair<string, double>> constants, double value, string formatString, NumberFormatInfo numberFormat) {
    156       if (constants != null) {
    157         string constantKey = $"c_{constants.Count}";
    158         strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey);
    159         constants.Add(new KeyValuePair<string, double>(constantKey, value));
     155    private static void AppendNumber(StringBuilder strBuilder, List<KeyValuePair<string, double>> parameters, double value, string formatString, NumberFormatInfo numberFormat) {
     156      if (parameters != null) {
     157        string paramKey = $"c_{parameters.Count}";
     158        strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", paramKey);
     159        parameters.Add(new KeyValuePair<string, double>(paramKey, value));
    160160      } else {
    161161        strBuilder.Append(value.ToString(formatString, numberFormat));
     
    204204    /// </summary>
    205205    /// <param name="symbolicExpressionTree">The tree representation of the expression.</param>
    206     /// <param name="numberFormat">Number format that should be used for numeric parameters (e.g. NumberFormatInfo.InvariantInfo (default)).</param>
    207     /// <param name="formatString">The format string for numeric parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param>
     206    /// <param name="numberFormat">Number format that should be used for parameters (e.g. NumberFormatInfo.InvariantInfo (default)).</param>
     207    /// <param name="formatString">The format string for parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param>
    208208    /// <returns>Infix expression</returns>
    209209    public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat,
     
    241241    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
    242242      StringBuilder strBuilder = new StringBuilder();
    243       var constants = new List<KeyValuePair<string, double>>();
     243      var parameters = new List<KeyValuePair<string, double>>();
    244244      BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0),
    245         strBuilder, NumberFormatInfo.InvariantInfo, "G", constants);
     245        strBuilder, NumberFormatInfo.InvariantInfo, "G", parameters);
    246246      strBuilder.Append($"{Environment.NewLine}{Environment.NewLine}");
    247247
    248       int maxDigits = GetDigits(constants.Count);
    249       int padding = constants.Max(x => x.Value.ToString("F12", CultureInfo.InvariantCulture).Length);
    250       foreach (var constant in constants) {
    251         int digits = GetDigits(Int32.Parse(constant.Key.Substring(2)));
    252         strBuilder.Append($"{constant.Key}{new String(' ', maxDigits - digits)} = " +
    253                           string.Format($"{{0,{padding}:F12}}", constant.Value, CultureInfo.InvariantCulture) +
     248      int maxDigits = GetDigits(parameters.Count);
     249      int padding = parameters.Max(x => x.Value.ToString("F12", CultureInfo.InvariantCulture).Length);
     250      foreach (var param in parameters) {
     251        int digits = GetDigits(int.Parse(param.Key.Substring(2)));
     252        strBuilder.Append($"{param.Key}{new string(' ', maxDigits - digits)} = " +
     253                          string.Format($"{{0,{padding}:F12}}", param.Value, CultureInfo.InvariantCulture) +
    254254                          Environment.NewLine);
    255255      }
Note: See TracChangeset for help on using the changeset viewer.