Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 10743 was 9585, checked in by mkommend, 11 years ago

#1730: Added necessary plugin dependency and improved error handling.

File size: 8.4 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    [StorableConstructor]
36    private SymbolicDataAnalysisExpressionExcelFormatter(bool deserializing) : base(deserializing) { }
37    private SymbolicDataAnalysisExpressionExcelFormatter(SymbolicDataAnalysisExpressionExcelFormatter original, Cloner cloner) : base(original, cloner) { }
38    public SymbolicDataAnalysisExpressionExcelFormatter()
39      : base() {
40      Name = ItemName;
41      Description = ItemDescription;
42    }
43    public override IDeepCloneable Clone(Cloner cloner) {
44      return new SymbolicDataAnalysisExpressionExcelFormatter(this, cloner);
45    }
46    private string GetExcelColumnName(int columnNumber) {
47      int dividend = columnNumber;
48      string columnName = String.Empty;
49
50      while (dividend > 0) {
51        int modulo = (dividend - 1) % 26;
52        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
53        dividend = (int)((dividend - modulo) / 26);
54      }
55
56      return columnName;
57    }
58
59    private readonly Dictionary<string, string> variableNameMapping = new Dictionary<string, string>();
60    private int currentVariableIndex = 0;
61    private string GetColumnToVariableName(string variabelName) {
62      if (!variableNameMapping.ContainsKey(variabelName)) {
63        currentVariableIndex++;
64        variableNameMapping.Add(variabelName, GetExcelColumnName(currentVariableIndex));
65      }
66      return string.Format("${0}1", variableNameMapping[variabelName]);
67    }
68
69    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
70      var stringBuilder = new StringBuilder();
71      stringBuilder.Append("=");
72      stringBuilder.Append(FormatRecursively(symbolicExpressionTree.Root));
73      foreach (var variable in variableNameMapping) {
74        stringBuilder.AppendLine();
75        stringBuilder.Append(variable.Key + " = " + variable.Value);
76      }
77      return stringBuilder.ToString();
78    }
79
80    private string FormatRecursively(ISymbolicExpressionTreeNode node) {
81      ISymbol symbol = node.Symbol;
82      StringBuilder stringBuilder = new StringBuilder();
83
84      if (symbol is ProgramRootSymbol) {
85        stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0)));
86      } else if (symbol is StartSymbol)
87        return FormatRecursively(node.GetSubtree(0));
88      else if (symbol is Addition) {
89        stringBuilder.Append("(");
90        for (int i = 0; i < node.SubtreeCount; i++) {
91          if (i > 0) stringBuilder.Append("+");
92          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
93        }
94        stringBuilder.Append(")");
95      } else if (symbol is Average) {
96        stringBuilder.Append("(1/");
97        stringBuilder.Append(node.SubtreeCount);
98        stringBuilder.Append(")*(");
99        for (int i = 0; i < node.SubtreeCount; i++) {
100          if (i > 0) stringBuilder.Append("+");
101          stringBuilder.Append("(");
102          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
103          stringBuilder.Append(")");
104        }
105        stringBuilder.Append(")");
106      } else if (symbol is Constant) {
107        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
108        stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
109      } else if (symbol is Cosine) {
110        stringBuilder.Append("COS(");
111        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
112        stringBuilder.Append(")");
113      } else if (symbol is Division) {
114        if (node.SubtreeCount == 1) {
115          stringBuilder.Append("1/");
116          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
117        } else {
118          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
119          stringBuilder.Append("/(");
120          for (int i = 1; i < node.SubtreeCount; i++) {
121            if (i > 1) stringBuilder.Append("*");
122            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
123          }
124          stringBuilder.Append(")");
125        }
126      } else if (symbol is Exponential) {
127        stringBuilder.Append("EXP(");
128        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
129        stringBuilder.Append(")");
130      } else if (symbol is Square) {
131        stringBuilder.Append("POWER(");
132        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
133        stringBuilder.Append(",2)");
134      } else if (symbol is SquareRoot) {
135        stringBuilder.Append("SQRT(");
136        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
137        stringBuilder.Append(")");
138      } else if (symbol is Logarithm) {
139        stringBuilder.Append("LOG(");
140        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
141        stringBuilder.Append(", EXP(1))"); // Excel does not use the natural logarithm, therefor the base has to be set
142      } else if (symbol is Multiplication) {
143        for (int i = 0; i < node.SubtreeCount; i++) {
144          if (i > 0) stringBuilder.Append("*");
145          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
146        }
147      } else if (symbol is Sine) {
148        stringBuilder.Append("SIN(");
149        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
150        stringBuilder.Append(")");
151      } else if (symbol is Subtraction) {
152        stringBuilder.Append("(");
153        if (node.SubtreeCount == 1) {
154          stringBuilder.Append("-");
155          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
156        } else {
157          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
158          for (int i = 1; i < node.SubtreeCount; i++) {
159            stringBuilder.Append("-");
160            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
161          }
162        }
163        stringBuilder.Append(")");
164      } else if (symbol is Tangent) {
165        stringBuilder.Append("TAN(");
166        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
167        stringBuilder.Append(")");
168
169      } else if (symbol is Variable) {
170        VariableTreeNode variableTreeNode = node as VariableTreeNode;
171        stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
172        stringBuilder.Append("*");
173        stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));// + LagToString(currentLag));
174      } else if (symbol is Power) {
175        stringBuilder.Append("POWER(");
176        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
177        stringBuilder.Append(",ROUND(");
178        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
179        stringBuilder.Append(",0))");
180      } else if (symbol is Root) {
181        stringBuilder.Append("(");
182        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
183        stringBuilder.Append(")^(1 / ROUND(");
184        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
185        stringBuilder.Append(",0))");
186      } else {
187        throw new NotImplementedException("Excel export of " + node.Symbol + " is not implemented.");
188      }
189      return stringBuilder.ToString();
190    }
191  }
192}
Note: See TracBrowser for help on using the repository browser.