Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionSmalltalkFormatter.cs @ 18242

Last change on this file since 18242 was 18220, checked in by gkronber, 3 years ago

#3136: reintegrated structure-template GP branch into trunk

File size: 9.3 KB
RevLine 
[4861]1#region License Information
2/* HeuristicLab
[17180]3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
[4861]4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
[16802]22using System;
[9794]23using System.Globalization;
[4861]24using System.Text;
[9821]25using HeuristicLab.Common;
[4861]26using HeuristicLab.Core;
[9821]27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
[4861]28
[9821]29namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
[4861]30
[9649]31  [Item("Smalltalk String Formatter", "String formatter for string representations of symbolic expression trees in Smalltalk syntax.")]
[9821]32  public class SymbolicDataAnalysisExpressionSmalltalkFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
[4861]33
[9821]34    protected SymbolicDataAnalysisExpressionSmalltalkFormatter(SymbolicDataAnalysisExpressionSmalltalkFormatter original, Cloner cloner) : base(original, cloner) { }
35    public SymbolicDataAnalysisExpressionSmalltalkFormatter()
[9649]36      : base() {
[9821]37      Name = ItemName;
38      Description = ItemDescription;
[4861]39    }
40
[9649]41    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
[4861]42      return FormatRecursively(symbolicExpressionTree.Root);
43    }
44
[9794]45    // returns the smalltalk expression corresponding to the node
46    // smalltalk expressions are always surrounded by parantheses "(<expr>)"
[9649]47    private string FormatRecursively(ISymbolicExpressionTreeNode node) {
[4868]48
[9649]49      ISymbol symbol = node.Symbol;
[4868]50
51      if (symbol is ProgramRootSymbol || symbol is StartSymbol)
[9649]52        return FormatRecursively(node.GetSubtree(0));
[4868]53
[9794]54      StringBuilder stringBuilder = new StringBuilder(20);
[4861]55
[4868]56      stringBuilder.Append("(");
57
[4861]58      if (symbol is Addition) {
[9649]59        for (int i = 0; i < node.SubtreeCount; i++) {
[4861]60          if (i > 0) stringBuilder.Append("+");
[9649]61          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[4861]62        }
63      } else if (symbol is And) {
[4868]64        stringBuilder.Append("(");
[9649]65        for (int i = 0; i < node.SubtreeCount; i++) {
[4861]66          if (i > 0) stringBuilder.Append("&");
[9794]67          stringBuilder.Append("(");
[9649]68          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[9794]69          stringBuilder.Append(" > 0)");
[4861]70        }
[4868]71        stringBuilder.Append(") ifTrue:[1] ifFalse:[-1]");
[16802]72      } else if (symbol is Absolute) {
73        stringBuilder.Append($"({FormatRecursively(node.GetSubtree(0))}) abs");
74      } else if (symbol is AnalyticQuotient) {
75        stringBuilder.Append($"({FormatRecursively(node.GetSubtree(0))}) / (1 + ({FormatPower(node.GetSubtree(1), "2")})) sqrt");
[4861]76      } else if (symbol is Average) {
77        stringBuilder.Append("(1/");
[9649]78        stringBuilder.Append(node.SubtreeCount);
[4861]79        stringBuilder.Append(")*(");
[9649]80        for (int i = 0; i < node.SubtreeCount; i++) {
[4861]81          if (i > 0) stringBuilder.Append("+");
[9649]82          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[4861]83        }
84        stringBuilder.Append(")");
[18132]85      } else if (symbol is INumericSymbol) {
86        var numberTreeNode = node as INumericTreeNode;
87        stringBuilder.Append(numberTreeNode.Value.ToString(CultureInfo.InvariantCulture));
[4861]88      } else if (symbol is Cosine) {
[9649]89        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]90        stringBuilder.Append(" cos");
[16802]91      } else if (symbol is Cube) {
92        stringBuilder.Append(FormatPower(node.GetSubtree(0), "3"));
93      } else if (symbol is CubeRoot) {
[16905]94        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
95        stringBuilder.Append(" cbrt");
[4861]96      } else if (symbol is Division) {
[9649]97        if (node.SubtreeCount == 1) {
[4868]98          stringBuilder.Append("1/");
[9649]99          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]100        } else {
[9649]101          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]102          stringBuilder.Append("/(");
[9649]103          for (int i = 1; i < node.SubtreeCount; i++) {
[4868]104            if (i > 1) stringBuilder.Append("*");
[9649]105            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[4868]106          }
[4861]107          stringBuilder.Append(")");
108        }
109      } else if (symbol is Exponential) {
[9649]110        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]111        stringBuilder.Append(" exp");
[4861]112      } else if (symbol is GreaterThan) {
113        stringBuilder.Append("(");
[9649]114        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]115        stringBuilder.Append(" > ");
[9649]116        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
[4868]117        stringBuilder.Append(") ifTrue: [1] ifFalse: [-1]");
[4861]118      } else if (symbol is IfThenElse) {
119        stringBuilder.Append("(");
[9649]120        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]121        stringBuilder.Append(" > 0) ifTrue: [");
[9649]122        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
[4861]123        stringBuilder.Append("] ifFalse: [");
[9649]124        stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
[4869]125        stringBuilder.Append("]");
[4861]126      } else if (symbol is LaggedVariable) {
[14826]127        stringBuilder.Append("lagged variables are not supported");
[4861]128      } else if (symbol is LessThan) {
129        stringBuilder.Append("(");
[9649]130        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]131        stringBuilder.Append(" < ");
[9649]132        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
[4868]133        stringBuilder.Append(") ifTrue: [1] ifFalse: [-1]");
[4861]134      } else if (symbol is Logarithm) {
[9649]135        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]136        stringBuilder.Append("ln");
[4861]137      } else if (symbol is Multiplication) {
[9649]138        for (int i = 0; i < node.SubtreeCount; i++) {
[4861]139          if (i > 0) stringBuilder.Append("*");
[9649]140          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[4861]141        }
142      } else if (symbol is Not) {
[9794]143        stringBuilder.Append("(");
[9649]144        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[9794]145        stringBuilder.Append(">0) ifTrue: [-1] ifFalse: [1.0]");
[4861]146      } else if (symbol is Or) {
[4868]147        stringBuilder.Append("(");
[9649]148        for (int i = 0; i < node.SubtreeCount; i++) {
[4861]149          if (i > 0) stringBuilder.Append("|");
[9794]150          stringBuilder.Append("(");
[9649]151          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[9794]152          stringBuilder.Append(">0)");
[4861]153        }
[4868]154        stringBuilder.Append(") ifTrue:[1] ifFalse:[-1]");
[4861]155      } else if (symbol is Sine) {
[9649]156        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]157        stringBuilder.Append(" sin");
[16802]158      } else if (symbol is Square) {
159        stringBuilder.Append(FormatPower(node.GetSubtree(0), "2"));
160      } else if (symbol is SquareRoot) {
161        stringBuilder.Append(FormatPower(node.GetSubtree(0), "(1/2)"));
[4861]162      } else if (symbol is Subtraction) {
[9649]163        if (node.SubtreeCount == 1) {
[4869]164          stringBuilder.Append("-1*");
[9649]165          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[4868]166        } else {
[9649]167          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
168          for (int i = 1; i < node.SubtreeCount; i++) {
[9794]169            stringBuilder.Append(" - ");
[9649]170            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
[4868]171          }
[4861]172        }
173      } else if (symbol is Tangent) {
[9649]174        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[9794]175        stringBuilder.Append(" tan");
[16702]176      } else if (symbol is HyperbolicTangent) {
177        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
178        stringBuilder.Append(" tanh");
[9649]179      } else if (symbol is Variable) {
[4868]180        VariableTreeNode variableTreeNode = node as VariableTreeNode;
[9794]181        stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
[4868]182        stringBuilder.Append("*");
183        stringBuilder.Append(variableTreeNode.VariableName);
[14826]184      } else if (symbol is BinaryFactorVariable || symbol is FactorVariable) {
185        stringBuilder.Append("factor variables are not supported");
[18220]186      } else if (symbol is SubFunctionSymbol) {
187        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
[9649]188      } else {
[9794]189        stringBuilder.Append("(");
190        for (int i = 0; i < node.SubtreeCount; i++) {
191          if (i > 0) stringBuilder.Append(", ");
192          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
193        }
194        stringBuilder.AppendFormat(" {0} [Not Supported] )", node.Symbol.Name);
[4861]195      }
196
[4868]197      stringBuilder.Append(")");
198
[4861]199      return stringBuilder.ToString();
200    }
201
[16802]202    private string FormatPower(ISymbolicExpressionTreeNode node, string exponent) {
203      return $"(({FormatRecursively(node)}) log * {exponent}) exp ";
204    }
205
[4861]206    public override IDeepCloneable Clone(Cloner cloner) {
[9821]207      return new SymbolicDataAnalysisExpressionSmalltalkFormatter(this, cloner);
[4861]208    }
209  }
210}
Note: See TracBrowser for help on using the repository browser.