Free cookie consent management tool by TermsFeed Policy Generator

source: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionMATLABFormatter.cs @ 7573

Last change on this file since 7573 was 7485, checked in by sforsten, 13 years ago

#1708:

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