Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Hive.Azure/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionMATLABFormatter.cs @ 7669

Last change on this file since 7669 was 7669, checked in by spimming, 12 years ago

#1680: merged changes from trunk into branch

File size: 12.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
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
22using System.Text;
23using System.Linq;
24using HeuristicLab.Core;
25using HeuristicLab.Common;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27using HeuristicLab.Problems.DataAnalysis;
28using System.Collections.Generic;
29using System;
30using System.Globalization;
31using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
32
33namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
34
35  [Item("MATLAB String Formatter", "String formatter for string representations of symbolic data analysis expressions in MATLAB syntax.")]
36  [StorableClass]
37  public sealed class SymbolicDataAnalysisExpressionMATLABFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
38    private int currentLag;
39
40    [StorableConstructor]
41    private SymbolicDataAnalysisExpressionMATLABFormatter(bool deserializing) : base(deserializing) { }
42    private SymbolicDataAnalysisExpressionMATLABFormatter(SymbolicDataAnalysisExpressionMATLABFormatter original, Cloner cloner) : base(original, cloner) { }
43    public SymbolicDataAnalysisExpressionMATLABFormatter()
44      : base() {
45      Name = ItemName;
46      Description = ItemDescription;
47    }
48    public override IDeepCloneable Clone(Cloner cloner) {
49      return new SymbolicDataAnalysisExpressionMATLABFormatter(this, cloner);
50    }
51    private int currentIndexNumber;
52    public string CurrentIndexVariable {
53      get {
54        return "i" + currentIndexNumber;
55      }
56    }
57    private void ReleaseIndexVariable() {
58      currentIndexNumber--;
59    }
60
61    private string AllocateIndexVariable() {
62      currentIndexNumber++;
63      return CurrentIndexVariable;
64    }
65
66    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
67      currentLag = 0;
68      currentIndexNumber = 0;
69
70      var stringBuilder = new StringBuilder();
71      stringBuilder.AppendLine("rows = ???");
72      stringBuilder.AppendLine(FormatOnlyExpression(symbolicExpressionTree.Root) + ";");
73      stringBuilder.AppendLine();
74      stringBuilder.AppendLine("function y = log_(x)");
75      stringBuilder.AppendLine("  if(x<=0) y = NaN;");
76      stringBuilder.AppendLine("  else     y = log(x);");
77      stringBuilder.AppendLine("  end");
78      stringBuilder.AppendLine("end");
79      stringBuilder.AppendLine();
80      stringBuilder.AppendLine("function y = fivePoint(f0, f1, f3, f4)");
81      stringBuilder.AppendLine("  y = (f0 + 2*f1 - 2*f3 - f4) / 8;");
82      stringBuilder.AppendLine("end");
83      return stringBuilder.ToString();
84    }
85
86    public string FormatOnlyExpression(ISymbolicExpressionTreeNode expressionNode)
87    {
88      var stringBuilder = new StringBuilder();
89      stringBuilder.AppendLine("  for " + CurrentIndexVariable + " = 1:1:rows");
90      stringBuilder.AppendLine("    estimated(" + CurrentIndexVariable + ") = " + FormatRecursively(expressionNode.GetSubtree(0)) + ";");
91      stringBuilder.AppendLine("  end;");
92      return stringBuilder.ToString();
93    }
94
95    private string FormatRecursively(ISymbolicExpressionTreeNode node) {
96      ISymbol symbol = node.Symbol;
97      StringBuilder stringBuilder = new StringBuilder();
98
99      if (symbol is ProgramRootSymbol) {
100        stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0)));
101      } else if (symbol is StartSymbol)
102        return FormatRecursively(node.GetSubtree(0));
103      else if (symbol is Addition) {
104        stringBuilder.Append("(");
105        for (int i = 0; i < node.SubtreeCount; i++) {
106          if (i > 0) stringBuilder.Append("+");
107          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
108        }
109        stringBuilder.Append(")");
110      } else if (symbol is And) {
111        stringBuilder.Append("((");
112        for (int i = 0; i < node.SubtreeCount; i++) {
113          if (i > 0) stringBuilder.Append("&");
114          stringBuilder.Append("((");
115          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
116          stringBuilder.Append(")>0)");
117        }
118        stringBuilder.Append(")-0.5)*2");
119        // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
120      } else if (symbol is Average) {
121        stringBuilder.Append("(1/");
122        stringBuilder.Append(node.SubtreeCount);
123        stringBuilder.Append(")*(");
124        for (int i = 0; i < node.SubtreeCount; i++) {
125          if (i > 0) stringBuilder.Append("+");
126          stringBuilder.Append("(");
127          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
128          stringBuilder.Append(")");
129        }
130        stringBuilder.Append(")");
131      } else if (symbol is Constant) {
132        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
133        stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
134      } else if (symbol is Cosine) {
135        stringBuilder.Append("cos(");
136        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
137        stringBuilder.Append(")");
138      } else if (symbol is Division) {
139        if (node.SubtreeCount == 1) {
140          stringBuilder.Append("1/");
141          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
142        } else {
143          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
144          stringBuilder.Append("/(");
145          for (int i = 1; i < node.SubtreeCount; i++) {
146            if (i > 1) stringBuilder.Append("*");
147            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
148          }
149          stringBuilder.Append(")");
150        }
151      } else if (symbol is Exponential) {
152        stringBuilder.Append("exp(");
153        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
154        stringBuilder.Append(")");
155      } else if (symbol is GreaterThan) {
156        stringBuilder.Append("((");
157        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
158        stringBuilder.Append(">");
159        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
160        stringBuilder.Append(")-0.5)*2");
161        // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
162      } else if (symbol is IfThenElse) {
163        stringBuilder.Append("(");
164        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
165        stringBuilder.Append(">0)*");
166        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
167        stringBuilder.Append("+");
168        stringBuilder.Append("(");
169        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
170        stringBuilder.Append("<=0)*");
171        stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
172      } else if (symbol is LaggedVariable) {
173        // this if must be checked before if(symbol is LaggedVariable)
174        LaggedVariableTreeNode laggedVariableTreeNode = node as LaggedVariableTreeNode;
175        stringBuilder.Append(laggedVariableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
176        stringBuilder.Append("*");
177        stringBuilder.Append(laggedVariableTreeNode.VariableName +
178                             LagToString(currentLag + laggedVariableTreeNode.Lag));
179      } else if (symbol is LessThan) {
180        stringBuilder.Append("((");
181        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
182        stringBuilder.Append("<");
183        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
184        stringBuilder.Append(")-0.5)*2");
185        // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
186      } else if (symbol is Logarithm) {
187        stringBuilder.Append("log_(");
188        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
189        stringBuilder.Append(")");
190      } else if (symbol is Multiplication) {
191        for (int i = 0; i < node.SubtreeCount; i++) {
192          if (i > 0) stringBuilder.Append("*");
193          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
194        }
195      } else if (symbol is Not) {
196        stringBuilder.Append("~(");
197        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
198        stringBuilder.Append(" > 0 )");
199      } else if (symbol is Or) {
200        stringBuilder.Append("((");
201        for (int i = 0; i < node.SubtreeCount; i++) {
202          if (i > 0) stringBuilder.Append("|");
203          stringBuilder.Append("((");
204          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
205          stringBuilder.Append(")>0)");
206        }
207        stringBuilder.Append(")-0.5)*2");
208        // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
209      } else if (symbol is Sine) {
210        stringBuilder.Append("sin(");
211        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
212        stringBuilder.Append(")");
213      } else if (symbol is Subtraction) {
214        stringBuilder.Append("(");
215        if (node.SubtreeCount == 1) {
216          stringBuilder.Append("-");
217          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
218        } else {
219          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
220          for (int i = 1; i < node.SubtreeCount; i++) {
221            stringBuilder.Append("-");
222            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
223          }
224        }
225        stringBuilder.Append(")");
226      } else if (symbol is Tangent) {
227        stringBuilder.Append("tan(");
228        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
229        stringBuilder.Append(")");
230      } else if (symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) {
231        VariableTreeNode variableTreeNode = node as VariableTreeNode;
232        stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
233        stringBuilder.Append("*");
234        stringBuilder.Append(variableTreeNode.VariableName + LagToString(currentLag));
235      } else if (symbol is Power) {
236        stringBuilder.Append("(");
237        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
238        stringBuilder.Append(")^round(");
239        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
240        stringBuilder.Append(")");
241      } else if (symbol is Root) {
242        stringBuilder.Append("(");
243        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
244        stringBuilder.Append(")^(1 / round(");
245        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
246        stringBuilder.Append("))");
247      } else if (symbol is Derivative) {
248        stringBuilder.Append("fivePoint(");
249        // f0
250        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
251        stringBuilder.Append(", ");
252        // f1
253        currentLag--;
254        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
255        stringBuilder.Append(", ");
256        // f3
257        currentLag -= 2;
258        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
259        stringBuilder.Append(", ");
260        currentLag--;
261        // f4
262        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
263        stringBuilder.Append(")");
264        currentLag += 4;
265      } else if (symbol is Integral) {
266        var laggedNode = node as LaggedTreeNode;
267        string prevCounterVariable = CurrentIndexVariable;
268        string counterVariable = AllocateIndexVariable();
269        stringBuilder.AppendLine(" sum (map(@(" + counterVariable + ") " + FormatRecursively(node.GetSubtree(0)) +
270                                 ", (" + prevCounterVariable + "+" + laggedNode.Lag + "):" + prevCounterVariable +
271                                 "))");
272        ReleaseIndexVariable();
273      } else if (symbol is TimeLag) {
274        var laggedNode = node as LaggedTreeNode;
275        currentLag += laggedNode.Lag;
276        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
277        currentLag -= laggedNode.Lag;
278      } else {
279        stringBuilder.Append("ERROR");
280      }
281      return stringBuilder.ToString();
282    }
283
284
285    private string LagToString(int lag)
286    {
287      if (lag < 0) {
288        return "(" + CurrentIndexVariable + "" + lag + ")";
289      } else if (lag > 0) {
290        return "(" + CurrentIndexVariable + "+" + lag + ")";
291      } else return "(" + CurrentIndexVariable + ")";
292    }
293
294  }
295}
Note: See TracBrowser for help on using the repository browser.