Free cookie consent management tool by TermsFeed Policy Generator

source: branches/ExportSymbolicDataAnalysisSolutions/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs @ 9580

Last change on this file since 9580 was 9580, checked in by sforsten, 11 years ago

#1730:

  • added SymbolicDataAnalysisExpressionExcelFormatter
  • changed modifiers in SymbolicExpressionTreeChart of methods SaveImageAsBitmap and SaveImageAsEmf to public
  • added menu item ExportSymbolicSolutionToExcelMenuItem to export a symbolic solution to an excel file
  • added EPPlus-3.1.3 to ExtLibs
File size: 16.8 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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;
23using System.Collections.Generic;
24using System.Globalization;
25using System.Text;
26using HeuristicLab.Common;
27using HeuristicLab.Core;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
32  [Item("Excel String Formatter", "String formatter for string representations of symbolic data analysis expressions in Excel syntax.")]
33  [StorableClass]
34  public sealed class SymbolicDataAnalysisExpressionExcelFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
35    //private int currentLag;
36
37    [StorableConstructor]
38    private SymbolicDataAnalysisExpressionExcelFormatter(bool deserializing) : base(deserializing) { }
39    private SymbolicDataAnalysisExpressionExcelFormatter(SymbolicDataAnalysisExpressionExcelFormatter original, Cloner cloner) : base(original, cloner) { }
40    public SymbolicDataAnalysisExpressionExcelFormatter()
41      : base() {
42      Name = ItemName;
43      Description = ItemDescription;
44    }
45    public override IDeepCloneable Clone(Cloner cloner) {
46      return new SymbolicDataAnalysisExpressionExcelFormatter(this, cloner);
47    }
48    private string GetExcelColumnName(int columnNumber) {
49      int dividend = columnNumber;
50      string columnName = String.Empty;
51
52      while (dividend > 0) {
53        int modulo = (dividend - 1) % 26;
54        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
55        dividend = (int)((dividend - modulo) / 26);
56      }
57
58      return columnName;
59    }
60
61    private readonly Dictionary<string, string> variableNameMapping = new Dictionary<string, string>();
62    private int currentVariableIndex = 0;
63    private string GetColumnToVariableName(string variabelName) {
64      if (!variableNameMapping.ContainsKey(variabelName)) {
65        currentVariableIndex++;
66        variableNameMapping.Add(variabelName, GetExcelColumnName(currentVariableIndex));
67      }
68      return string.Format("${0}1", variableNameMapping[variabelName]);
69    }
70    //public string CurrentIndexVariable {
71    //  get {
72    //    return "i" + currentIndexNumber;
73    //  }
74    //}
75    //private void ReleaseIndexVariable() {
76    //  currentIndexNumber--;
77    //}
78
79    //private string AllocateIndexVariable() {
80    //  currentIndexNumber++;
81    //  return CurrentIndexVariable;
82    //}
83
84    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
85      var stringBuilder = new StringBuilder();
86      stringBuilder.Append("=");
87      stringBuilder.Append(FormatRecursively(symbolicExpressionTree.Root));
88      foreach (var variable in variableNameMapping) {
89        stringBuilder.AppendLine();
90        stringBuilder.Append(variable.Key + " = " + variable.Value);
91      }
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 Square) {
156        stringBuilder.Append("POWER(");
157        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
158        stringBuilder.Append(",2)");
159      } else if (symbol is SquareRoot) {
160        stringBuilder.Append("SQRT(");
161        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
162        stringBuilder.Append(")");
163        //} else if (symbol is GreaterThan) {
164        //  stringBuilder.Append("((");
165        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
166        //  stringBuilder.Append(">");
167        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
168        //  stringBuilder.Append(")-0.5)*2");
169        //  // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
170        //} else if (symbol is IfThenElse) {
171        //  stringBuilder.Append("(");
172        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
173        //  stringBuilder.Append(">0)*");
174        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
175        //  stringBuilder.Append("+");
176        //  stringBuilder.Append("(");
177        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
178        //  stringBuilder.Append("<=0)*");
179        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
180        //} else if (symbol is LaggedVariable) {
181        //  // this if must be checked before if(symbol is LaggedVariable)
182        //  LaggedVariableTreeNode laggedVariableTreeNode = node as LaggedVariableTreeNode;
183        //  stringBuilder.Append(laggedVariableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
184        //  stringBuilder.Append("*");
185        //  stringBuilder.Append(laggedVariableTreeNode.VariableName +
186        //                       LagToString(currentLag + laggedVariableTreeNode.Lag));
187        //} else if (symbol is LessThan) {
188        //  stringBuilder.Append("((");
189        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
190        //  stringBuilder.Append("<");
191        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
192        //  stringBuilder.Append(")-0.5)*2");
193        //  // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
194      } else if (symbol is Logarithm) {
195        stringBuilder.Append("LOG(");
196        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
197        stringBuilder.Append(", EXP(1))"); // Excel does not use the natural logarithm, therefor the base has to be set
198      } else if (symbol is Multiplication) {
199        for (int i = 0; i < node.SubtreeCount; i++) {
200          if (i > 0) stringBuilder.Append("*");
201          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
202        }
203        //} else if (symbol is Not) {
204        //  stringBuilder.Append("NOT(");
205        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
206        //  stringBuilder.Append(" > 0 )");
207        //} else if (symbol is Or) {
208        //  stringBuilder.Append("((");
209        //  for (int i = 0; i < node.SubtreeCount; i++) {
210        //    if (i > 0) stringBuilder.Append("|");
211        //    stringBuilder.Append("((");
212        //    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
213        //    stringBuilder.Append(")>0)");
214        //  }
215        //  stringBuilder.Append(")-0.5)*2");
216        //  // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
217      } else if (symbol is Sine) {
218        stringBuilder.Append("SIN(");
219        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
220        stringBuilder.Append(")");
221      } else if (symbol is Subtraction) {
222        stringBuilder.Append("(");
223        if (node.SubtreeCount == 1) {
224          stringBuilder.Append("-");
225          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
226        } else {
227          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
228          for (int i = 1; i < node.SubtreeCount; i++) {
229            stringBuilder.Append("-");
230            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
231          }
232        }
233        stringBuilder.Append(")");
234      } else if (symbol is Tangent) {
235        stringBuilder.Append("TAN(");
236        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
237        stringBuilder.Append(")");
238        //} else if (node.Symbol is AiryA) {
239        //  stringBuilder.Append("airy(");
240        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
241        //  stringBuilder.Append(")");
242        //} else if (node.Symbol is AiryB) {
243        //  stringBuilder.Append("airy(2, ");
244        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
245        //  stringBuilder.Append(")");
246        //} else if (node.Symbol is Bessel) {
247        //  stringBuilder.Append("besseli(0.0,");
248        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
249        //  stringBuilder.Append(")");
250        //} else if (node.Symbol is CosineIntegral) {
251        //  stringBuilder.Append("cosint(");
252        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
253        //  stringBuilder.Append(")");
254        //} else if (node.Symbol is Dawson) {
255        //  stringBuilder.Append("dawson(");
256        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
257        //  stringBuilder.Append(")");
258        //} else if (node.Symbol is Erf) {
259        //  stringBuilder.Append("erf(");
260        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
261        //  stringBuilder.Append(")");
262        //} else if (node.Symbol is ExponentialIntegralEi) {
263        //  stringBuilder.Append("expint(");
264        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
265        //  stringBuilder.Append(")");
266        //} else if (node.Symbol is FresnelCosineIntegral) {
267        //  stringBuilder.Append("FresnelC(");
268        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
269        //  stringBuilder.Append(")");
270        //} else if (node.Symbol is FresnelSineIntegral) {
271        //  stringBuilder.Append("FresnelS(");
272        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
273        //  stringBuilder.Append(")");
274        //} else if (node.Symbol is Gamma) {
275        //  stringBuilder.Append("gamma(");
276        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
277        //  stringBuilder.Append(")");
278        //} else if (node.Symbol is HyperbolicCosineIntegral) {
279        //  stringBuilder.Append("Chi(");
280        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
281        //  stringBuilder.Append(")");
282        //} else if (node.Symbol is HyperbolicSineIntegral) {
283        //  stringBuilder.Append("Shi(");
284        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
285        //  stringBuilder.Append(")");
286        //} else if (node.Symbol is Norm) {
287        //  stringBuilder.Append("normpdf(");
288        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
289        //  stringBuilder.Append(")");
290        //} else if (node.Symbol is Psi) {
291        //  stringBuilder.Append("psi(");
292        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
293        //  stringBuilder.Append(")");
294        //} else if (node.Symbol is SineIntegral) {
295        //  stringBuilder.Append("sinint(");
296        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
297        //  stringBuilder.Append(")");
298      } else if (symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) {
299        VariableTreeNode variableTreeNode = node as VariableTreeNode;
300        stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
301        stringBuilder.Append("*");
302        stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));// + LagToString(currentLag));
303      } else if (symbol is Power) {
304        stringBuilder.Append("POWER(");
305        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
306        stringBuilder.Append(",ROUND(");
307        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
308        stringBuilder.Append(",0))");
309      } else if (symbol is Root) {
310        stringBuilder.Append("(");
311        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
312        stringBuilder.Append(")^(1 / ROUND(");
313        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
314        stringBuilder.Append(",0))");
315        //} else if (symbol is Derivative) {
316        //  stringBuilder.Append("fivePoint(");
317        //  // f0
318        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
319        //  stringBuilder.Append(", ");
320        //  // f1
321        //  currentLag--;
322        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
323        //  stringBuilder.Append(", ");
324        //  // f3
325        //  currentLag -= 2;
326        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
327        //  stringBuilder.Append(", ");
328        //  currentLag--;
329        //  // f4
330        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
331        //  stringBuilder.Append(")");
332        //  currentLag += 4;
333        //} else if (symbol is Integral) {
334        //  var laggedNode = node as LaggedTreeNode;
335        //  string prevCounterVariable = CurrentIndexVariable;
336        //  string counterVariable = AllocateIndexVariable();
337        //  stringBuilder.AppendLine(" sum (map(@(" + counterVariable + ") " + FormatRecursively(node.GetSubtree(0)) +
338        //                           ", (" + prevCounterVariable + "+" + laggedNode.Lag + "):" + prevCounterVariable +
339        //                           "))");
340        //  ReleaseIndexVariable();
341        //} else if (symbol is TimeLag) {
342        //  var laggedNode = node as LaggedTreeNode;
343        //  currentLag += laggedNode.Lag;
344        //  stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
345        //currentLag -= laggedNode.Lag;
346      } else {
347        stringBuilder.Append("ERROR");
348      }
349      return stringBuilder.ToString();
350    }
351
352
353    //private string LagToString(int lag) {
354    //  if (lag < 0) {
355    //    return "(" + CurrentIndexVariable + "" + lag + ")";
356    //  } else if (lag > 0) {
357    //    return "(" + CurrentIndexVariable + "+" + lag + ")";
358    //  } else return "(" + CurrentIndexVariable + ")";
359    //}
360
361  }
362}
Note: See TracBrowser for help on using the repository browser.