Index: /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 5745)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 5745)
@@ -0,0 +1,321 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Text;
+using System.Linq;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using System.Collections.Generic;
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  [Item("LaTeX String Formatter", "Formatter for symbolic expression trees for import into LaTeX documents.")]
+  [StorableClass]
+  public sealed class SymbolicDataAnalysisExpressionLatexFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
+    private List<double> constants;
+    private int currentLag;
+
+    [StorableConstructor]
+    private SymbolicDataAnalysisExpressionLatexFormatter(bool deserializing) : base(deserializing) { }
+    private SymbolicDataAnalysisExpressionLatexFormatter(SymbolicDataAnalysisExpressionLatexFormatter original, Cloner cloner)
+      : base(original, cloner) {
+      constants = new List<double>(original.constants);
+    }
+    public SymbolicDataAnalysisExpressionLatexFormatter()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+      constants = new List<double>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisExpressionLatexFormatter(this, cloner);
+    }
+
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
+      try {
+        StringBuilder strBuilder = new StringBuilder();
+        constants.Clear();
+        strBuilder.AppendLine("% needs \\usepackage{amsmath}");
+        strBuilder.AppendLine("\\begin{align}");
+        strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root));
+        strBuilder.AppendLine("\\end{align}");
+        return strBuilder.ToString();
+      }
+      catch (NotImplementedException ex) {
+        return ex.Message + Environment.NewLine + ex.StackTrace;
+      }
+    }
+
+    private string FormatRecursively(ISymbolicExpressionTreeNode node) {
+      StringBuilder strBuilder = new StringBuilder();
+      currentLag = 0;
+      FormatBegin(node, strBuilder);
+
+      if (node.SubtreesCount > 0) {
+        strBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+      }
+      foreach (SymbolicExpressionTreeNode subTree in node.Subtrees.Skip(1)) {
+        FormatSep(node, strBuilder);
+        // format the whole subtree
+        strBuilder.Append(FormatRecursively(subTree));
+      }
+
+      FormatEnd(node, strBuilder);
+
+      return strBuilder.ToString();
+    }
+
+    private void FormatBegin(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      if (node.Symbol is Addition) {
+        strBuilder.Append(@" \left( ");
+      } else if (node.Symbol is Subtraction) {
+        if (node.SubtreesCount == 1) {
+          strBuilder.Append(@"- \left(");
+        } else {
+          strBuilder.Append(@" \left( ");
+        }
+      } else if (node.Symbol is Multiplication) {
+      } else if (node.Symbol is Division) {
+        if (node.SubtreesCount == 1) {
+          strBuilder.Append(@" \cfrac{1}{");
+        } else {
+          strBuilder.Append(@" \cfrac{ ");
+        }
+      } else if (node.Symbol is Average) {
+        // skip output of (1/1) if only one subtree
+        if (node.SubtreesCount > 1) {
+          strBuilder.Append(@" \cfrac{1}{" + node.SubtreesCount + @"}");
+        }
+        strBuilder.Append(@" \left(");
+      } else if (node.Symbol is Logarithm) {
+        strBuilder.Append(@"\log \left(");
+      } else if (node.Symbol is Exponential) {
+        strBuilder.Append(@"\exp \left(");
+      } else if (node.Symbol is Sine) {
+        strBuilder.Append(@"\sin \left(");
+      } else if (node.Symbol is Cosine) {
+        strBuilder.Append(@"\cos \left(");
+      } else if (node.Symbol is Tangent) {
+        strBuilder.Append(@"\tan \left(");
+      } else if (node.Symbol is GreaterThan) {
+        strBuilder.Append(@" \left( ");
+      } else if (node.Symbol is LessThan) {
+        strBuilder.Append(@" \left( ");
+      } else if (node.Symbol is And) {
+        strBuilder.Append(@" \left( \left( ");
+      } else if (node.Symbol is Or) {
+        strBuilder.Append(@" \left( \left( ");
+      } else if (node.Symbol is Not) {
+        strBuilder.Append(@" \neg \left( ");
+      } else if (node.Symbol is IfThenElse) {
+        strBuilder.Append(@"\left( \operatorname{if} \left( 0 < ");
+      } else if (node.Symbol is Constant) {
+        strBuilder.Append("c_{" + constants.Count + "} ");
+        var constNode = node as ConstantTreeNode;
+        constants.Add(constNode.Value);
+      } else if (node.Symbol is LaggedVariable) {
+        var laggedVarNode = node as LaggedVariableTreeNode;
+        strBuilder.Append("c_{" + constants.Count + "} " + laggedVarNode.VariableName);
+        strBuilder.Append(LagToString(currentLag + laggedVarNode.Lag));
+        constants.Add(laggedVarNode.Weight);
+      } else if (node.Symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) {
+        var varNode = node as VariableTreeNode;
+        strBuilder.Append("c_{" + constants.Count + "} " + varNode.VariableName);
+        strBuilder.Append(LagToString(currentLag));
+        constants.Add(varNode.Weight);
+      } else if (node.Symbol is ProgramRootSymbol) {
+      } else if (node.Symbol is Defun) {
+        var defunNode = node as DefunTreeNode;
+        strBuilder.Append(defunNode.FunctionName + " & = ");
+      } else if (node.Symbol is InvokeFunction) {
+        var invokeNode = node as InvokeFunctionTreeNode;
+        strBuilder.Append(invokeNode.Symbol.FunctionName + @" \left( ");
+      } else if (node.Symbol is StartSymbol) {
+        strBuilder.Append("Result & = ");
+      } else if (node.Symbol is Argument) {
+        var argSym = node.Symbol as Argument;
+        strBuilder.Append(" ARG+" + argSym.ArgumentIndex + " ");
+      } else if (node.Symbol is Derivative) {
+        strBuilder.Append(@" \cfrac{d \left(");
+      } else if (node.Symbol is TimeLag) {
+        var laggedNode = node as ILaggedTreeNode;
+        currentLag += laggedNode.Lag;
+      } else if (node.Symbol is Power) {
+        strBuilder.Append(@"\left(");
+      } else if (node.Symbol is Root) {
+        strBuilder.Append(@"\left(");
+      } else if (node.Symbol is Integral) {
+        // actually a new variable for t is needed in all subtrees (TODO)
+        var laggedTreeNode = node as ILaggedTreeNode;
+        strBuilder.Append(@"\sum_{t=" + (laggedTreeNode.Lag + currentLag) + @"}^0 \left(");
+      } else if (node.Symbol is VariableCondition) {
+        var conditionTreeNode = node as VariableConditionTreeNode;
+        string p = @"1 / \left( 1 + \exp \left( - c_{" + constants.Count + "} ";
+        constants.Add(conditionTreeNode.Slope);
+        p += @" \cdot \left(" + conditionTreeNode.VariableName + LagToString(currentLag) + " - c_{" + constants.Count + "} \right) \right) \right)";
+        constants.Add(conditionTreeNode.Threshold);
+        strBuilder.Append(@"\left( " + p + @"\cdot ");
+      } else {
+        throw new NotImplementedException("Export of " + node.Symbol + " is not implemented.");
+      }
+    }
+
+    private void FormatSep(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      if (node.Symbol is Addition) {
+        strBuilder.Append(" + ");
+      } else if (node.Symbol is Subtraction) {
+        strBuilder.Append(" - ");
+      } else if (node.Symbol is Multiplication) {
+        strBuilder.Append(@" \cdot ");
+      } else if (node.Symbol is Division) {
+        strBuilder.Append(@" }{ \cfrac{ ");
+      } else if (node.Symbol is Average) {
+        strBuilder.Append(@" + ");
+      } else if (node.Symbol is Logarithm) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is Exponential) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is Sine) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is Cosine) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is Tangent) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is GreaterThan) {
+        strBuilder.Append(@" > ");
+      } else if (node.Symbol is LessThan) {
+        strBuilder.Append(@" < ");
+      } else if (node.Symbol is And) {
+        strBuilder.Append(@" > 0 \right) \land \left(");
+      } else if (node.Symbol is Or) {
+        strBuilder.Append(@" > 0 \right) \lor \left(");
+      } else if (node.Symbol is Not) {
+        throw new InvalidOperationException();
+      } else if (node.Symbol is IfThenElse) {
+        strBuilder.Append(@" \right) , \left(");
+      } else if (node.Symbol is ProgramRootSymbol) {
+        strBuilder.Append(@"\\" + Environment.NewLine);
+      } else if (node.Symbol is Defun) {
+      } else if (node.Symbol is InvokeFunction) {
+        strBuilder.Append(" , ");
+      } else if (node.Symbol is StartSymbol) {
+        strBuilder.Append(@"\\" + Environment.NewLine + " & ");
+      } else if (node.Symbol is Power) {
+        strBuilder.Append(@"\right) ^ { \operatorname{round} \left(");
+      } else if (node.Symbol is Root) {
+        strBuilder.Append(@"\right) ^ { \left( \cfrac{1}{ \operatorname{round} \left(");
+      } else if (node.Symbol is VariableCondition) {
+        var conditionTreeNode = node as VariableConditionTreeNode;
+        string p = @"1 / \left( 1 + \exp \left( - c_{" + constants.Count + "} ";
+        constants.Add(conditionTreeNode.Slope);
+        p += @" \cdot \left(" + conditionTreeNode.VariableName + LagToString(currentLag) + " - c_{" + constants.Count + "} \right) \right) \right)";
+        constants.Add(conditionTreeNode.Threshold);
+        strBuilder.Append(@" + \left( 1 - " + p + @" \right) \cdot ");
+      } else {
+        throw new NotImplementedException("Export of " + node.Symbol + " is not implemented.");
+      }
+    }
+
+    private void FormatEnd(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {
+      if (node.Symbol is Addition) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Subtraction) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Multiplication) {
+      } else if (node.Symbol is Division) {
+        strBuilder.Append("} ");
+        if (node.SubtreesCount > 1)
+          strBuilder.Append("{1} ");
+        for (int i = 1; i < node.SubtreesCount; i++) {
+          strBuilder.Append(" } ");
+        }
+      } else if (node.Symbol is Average) {
+        strBuilder.Append(@" \right)");
+      } else if (node.Symbol is Logarithm) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Exponential) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Sine) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Cosine) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is Tangent) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is GreaterThan) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is LessThan) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is And) {
+        strBuilder.Append(@" > 0 \right) \right) ");
+      } else if (node.Symbol is Or) {
+        strBuilder.Append(@" > 0 \right) \right) ");
+      } else if (node.Symbol is Not) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is IfThenElse) {
+        strBuilder.Append(@" \right) \right) ");
+      } else if (node.Symbol is Constant) {
+      } else if (node.Symbol is LaggedVariable) {
+      } else if (node.Symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) {
+      } else if (node.Symbol is ProgramRootSymbol) {
+        // output all constant values
+        if (constants.Count > 0) {
+          int i = 0;
+          foreach (var constant in constants) {
+            strBuilder.AppendLine(@"\\");
+            strBuilder.Append("c_{" + i + "} & = " + constant);
+            i++;
+          }
+        }
+      } else if (node.Symbol is Defun) {
+      } else if (node.Symbol is InvokeFunction) {
+        strBuilder.Append(@" \right) ");
+      } else if (node.Symbol is StartSymbol) {
+      } else if (node.Symbol is Argument) {
+      } else if (node.Symbol is Derivative) {
+        strBuilder.Append(@" \right) }{dt} ");
+      } else if (node.Symbol is TimeLag) {
+        var laggedNode = node as ILaggedTreeNode;
+        currentLag -= laggedNode.Lag;
+      } else if (node.Symbol is Power) {
+        strBuilder.Append(@"\right) } ");
+      } else if (node.Symbol is Root) {
+        strBuilder.Append(@"\right) } \right) } ");
+      } else if (node.Symbol is Integral) {
+        var laggedTreeNode = node as ILaggedTreeNode;
+        strBuilder.Append(@"\right) ");
+      } else if (node.Symbol is VariableCondition) {
+        strBuilder.Append(@"\left) ");
+      } else {
+        throw new NotImplementedException("Export of " + node.Symbol + " is not implemented.");
+      }
+    }
+    private string LagToString(int lag) {
+      if (lag < 0) {
+        return "(t" + lag + ")";
+      } else if (lag > 0) {
+        return "(t+" + lag + ")";
+      } else return "(t)";
+    }
+  }
+}
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionMATLABFormatter.cs
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionMATLABFormatter.cs	(revision 5745)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionMATLABFormatter.cs	(revision 5745)
@@ -0,0 +1,289 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Text;
+using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using System.Collections.Generic;
+using System;
+using System.Globalization;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+
+  [Item("MATLAB String Formatter", "String formatter for string representations of symbolic data analysis expressions in MATLAB syntax.")]
+  [StorableClass]
+  public sealed class SymbolicDataAnalysisExpressionMATLABFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
+    private int currentLag;
+
+    [StorableConstructor]
+    private SymbolicDataAnalysisExpressionMATLABFormatter(bool deserializing) : base(deserializing) { }
+    private SymbolicDataAnalysisExpressionMATLABFormatter(SymbolicDataAnalysisExpressionMATLABFormatter original, Cloner cloner) : base(original, cloner) { }
+    public SymbolicDataAnalysisExpressionMATLABFormatter()
+      : base() {
+      Name = ItemName;
+      Description = ItemDescription;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicDataAnalysisExpressionMATLABFormatter(this, cloner);
+    }
+    private int currentIndexNumber;
+    public string CurrentIndexVariable {
+      get {
+        return "i" + currentIndexNumber;
+      }
+    }
+    private void ReleaseIndexVariable() {
+      currentIndexNumber--;
+    }
+
+    private string AllocateIndexVariable() {
+      currentIndexNumber++;
+      return CurrentIndexVariable;
+    }
+
+    public string Format(ISymbolicExpressionTree symbolicExpressionTree) {
+      currentLag = 0;
+      currentIndexNumber = 0;
+      return FormatRecursively(symbolicExpressionTree.Root);
+    }
+
+    private string FormatRecursively(ISymbolicExpressionTreeNode node) {
+      ISymbol symbol = node.Symbol;
+      StringBuilder stringBuilder = new StringBuilder();
+
+      if (symbol is ProgramRootSymbol) {
+        var variableNames = node.IterateNodesPostfix()
+          .OfType<VariableTreeNode>()
+          .Select(n => n.VariableName)
+          .Distinct()
+          .OrderBy(x => x);
+        stringBuilder.AppendLine("function test_model");
+        foreach (string variableName in variableNames)
+          stringBuilder.AppendLine("  " + variableName + " = Data(:, ???);");
+        stringBuilder.AppendLine("  for " + CurrentIndexVariable + " = size(Data,1):-1:1");
+        stringBuilder.AppendLine("    Target_estimated(" + CurrentIndexVariable + ") = " + FormatRecursively(node.GetSubtree(0)) + ";");
+        stringBuilder.AppendLine("  end");
+        stringBuilder.AppendLine("end");
+        stringBuilder.AppendLine();
+        stringBuilder.AppendLine("function y = log_(x)");
+        stringBuilder.AppendLine("  if(x<=0) y = NaN;");
+        stringBuilder.AppendLine("  else     y = log(x);");
+        stringBuilder.AppendLine("  end");
+        stringBuilder.AppendLine("end");
+        stringBuilder.AppendLine();
+        stringBuilder.AppendLine("function y = fivePoint(f0, f1, f3, f4)");
+        stringBuilder.AppendLine("  y = (f0 + 2*f1 - 2*f3 - f4) / 8;");
+        stringBuilder.AppendLine("end");
+        return stringBuilder.ToString();
+      }
+
+      if (symbol is StartSymbol)
+        return FormatRecursively(node.GetSubtree(0));
+
+      stringBuilder.Append("(");
+
+      if (symbol is Addition) {
+        for (int i = 0; i < node.SubtreesCount; i++) {
+          if (i > 0) stringBuilder.Append("+");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+        }
+      } else if (symbol is And) {
+        stringBuilder.Append("((");
+        for (int i = 0; i < node.SubtreesCount; i++) {
+          if (i > 0) stringBuilder.Append("&");
+          stringBuilder.Append("((");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+          stringBuilder.Append(")>0)");
+        }
+        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.
+      } else if (symbol is Average) {
+        stringBuilder.Append("(1/");
+        stringBuilder.Append(node.SubtreesCount);
+        stringBuilder.Append(")*(");
+        for (int i = 0; i < node.SubtreesCount; i++) {
+          if (i > 0) stringBuilder.Append("+");
+          stringBuilder.Append("(");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+          stringBuilder.Append(")");
+        }
+        stringBuilder.Append(")");
+      } else if (symbol is Constant) {
+        ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
+        stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
+      } else if (symbol is Cosine) {
+        stringBuilder.Append("cos(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+      } else if (symbol is Division) {
+        if (node.SubtreesCount == 1) {
+          stringBuilder.Append("1/");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        } else {
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+          stringBuilder.Append("/(");
+          for (int i = 1; i < node.SubtreesCount; i++) {
+            if (i > 1) stringBuilder.Append("*");
+            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+          }
+          stringBuilder.Append(")");
+        }
+      } else if (symbol is Exponential) {
+        stringBuilder.Append("exp(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+      } else if (symbol is GreaterThan) {
+        stringBuilder.Append("((");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(">");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
+        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.
+      } else if (symbol is IfThenElse) {
+        stringBuilder.Append("(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(">0)*");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
+        stringBuilder.Append("+");
+        stringBuilder.Append("(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append("<=0)*");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
+      } else if (symbol is LaggedVariable) {
+        // this if must be checked before if(symbol is LaggedVariable)
+        LaggedVariableTreeNode laggedVariableTreeNode = node as LaggedVariableTreeNode;
+        stringBuilder.Append(laggedVariableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
+        stringBuilder.Append("*");
+        stringBuilder.Append(laggedVariableTreeNode.VariableName + LagToString(currentLag + laggedVariableTreeNode.Lag));
+      } else if (symbol is LessThan) {
+        stringBuilder.Append("((");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append("<");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
+        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.
+      } else if (symbol is Logarithm) {
+        stringBuilder.Append("log_(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+      } else if (symbol is Multiplication) {
+        for (int i = 0; i < node.SubtreesCount; i++) {
+          if (i > 0) stringBuilder.Append("*");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+        }
+      } else if (symbol is Not) {
+        stringBuilder.Append("~(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(" > 0 )");
+      } else if (symbol is Or) {
+        stringBuilder.Append("((");
+        for (int i = 0; i < node.SubtreesCount; i++) {
+          if (i > 0) stringBuilder.Append("|");
+          stringBuilder.Append("((");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+          stringBuilder.Append(")>0)");
+        }
+        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.
+      } else if (symbol is Sine) {
+        stringBuilder.Append("sin(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+      } else if (symbol is Subtraction) {
+        if (node.SubtreesCount == 1) {
+          stringBuilder.Append("-1*");
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        } else {
+          stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+          for (int i = 1; i < node.SubtreesCount; i++) {
+            stringBuilder.Append("-");
+            stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
+          }
+        }
+      } else if (symbol is Tangent) {
+        stringBuilder.Append("tan(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+      } else if (symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable) {
+        VariableTreeNode variableTreeNode = node as VariableTreeNode;
+        stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
+        stringBuilder.Append("*");
+        stringBuilder.Append(variableTreeNode.VariableName + LagToString(currentLag));
+      } else if (symbol is Power) {
+        stringBuilder.Append("(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")^round(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
+        stringBuilder.Append(")");
+      } else if (symbol is Root) {
+        stringBuilder.Append("(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")^(1 / round(");
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
+        stringBuilder.Append("))");
+      } else if (symbol is Derivative) {
+        stringBuilder.Append("fivePoint(");
+        // f0
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(", ");
+        // f1
+        currentLag--;
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(", ");
+        // f3
+        currentLag -= 2;
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(", ");
+        currentLag--;
+        // f4
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        stringBuilder.Append(")");
+        currentLag += 4;
+      } else if (symbol is Integral) {
+        var laggedNode = node as LaggedTreeNode;
+        string prevCounterVariable = CurrentIndexVariable;
+        string counterVariable = AllocateIndexVariable();
+        stringBuilder.AppendLine(" sum (map(@(" + counterVariable + ") " + FormatRecursively(node.GetSubtree(0)) + ", (" + prevCounterVariable + "+" + laggedNode.Lag + "):" + prevCounterVariable + "))");
+        ReleaseIndexVariable();
+      } else if (symbol is TimeLag) {
+        var laggedNode = node as LaggedTreeNode;
+        currentLag += laggedNode.Lag;
+        stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
+        currentLag -= laggedNode.Lag;
+      } else {
+        stringBuilder.Append("ERROR");
+      }
+
+      stringBuilder.Append(")");
+      return stringBuilder.ToString();
+    }
+
+
+    private string LagToString(int lag) {
+      if (lag < 0) {
+        return "(" + CurrentIndexVariable + "" + lag + ")";
+      } else if (lag > 0) {
+        return "(" + CurrentIndexVariable + "+" + lag + ")";
+      } else return "(" + CurrentIndexVariable + ")";
+    }
+
+  }
+}
Index: /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 5744)
+++ /branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 5745)
@@ -119,4 +119,6 @@
     </Compile>
     <Compile Include="Analyzers\SymbolicDataAnalysisVariableFrequencyAnalyzer.cs" />
+    <Compile Include="Formatters\SymbolicDataAnalysisExpressionLatexFormatter.cs" />
+    <Compile Include="Formatters\SymbolicDataAnalysisExpressionMATLABFormatter.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisBoundedOperator.cs" />
     <Compile Include="Interfaces\ISymbolicDataAnalysisExpressionTreeInterpreter.cs" />
