Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs	(revision 14258)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionExcelFormatter.cs	(revision 14259)
@@ -28,4 +28,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -71,4 +72,5 @@
     }
 
+
     public string Format(ISymbolicExpressionTree symbolicExpressionTree, IDataset dataset) {
       var stringBuilder = new StringBuilder();
@@ -88,5 +90,5 @@
       int columnIndex = 0;
       int inputIndex = 0;
-      var usedVariables = tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(v => v.VariableName).Distinct();
+      var usedVariables = tree.IterateNodesPrefix().OfType<IVariableTreeNode>().Select(v => v.VariableName).Distinct();
       foreach (var variable in dataset.VariableNames) {
         columnIndex++;
@@ -190,5 +192,25 @@
         stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
         stringBuilder.Append("*");
-        stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));// + LagToString(currentLag));
+        stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName)); // + LagToString(currentLag));
+      } else if (symbol is BinaryFactorVariable) {
+        var binFactorNode = node as BinaryFactorVariableTreeNode;
+        stringBuilder.AppendFormat("IF({0}=\"{1}\", {2}, 0)",
+          GetColumnToVariableName(binFactorNode.VariableName),
+          binFactorNode.VariableValue,
+          binFactorNode.Weight.ToString(CultureInfo.InvariantCulture)
+          );
+      } else if (symbol is FactorVariable) {
+        var factorNode = node as FactorVariableTreeNode;
+        var values = factorNode.Symbol.GetVariableValues(factorNode.VariableName).ToArray();
+        var w = factorNode.Weights;
+        // create nested if
+        for (int i = 0; i < values.Length; i++) {
+          stringBuilder.AppendFormat("IF({0}=\"{1}\", {2}, ",
+            GetColumnToVariableName(factorNode.VariableName),
+            values[i],
+            w[i].ToString(CultureInfo.InvariantCulture));
+        }
+        stringBuilder.Append("\"\""); // return empty string on unknown value
+        stringBuilder.Append(')', values.Length); // add closing parenthesis
       } else if (symbol is Power) {
         stringBuilder.Append("POWER(");
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14258)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs	(revision 14259)
@@ -33,5 +33,6 @@
   [StorableClass]
   public sealed class SymbolicDataAnalysisExpressionLatexFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter {
-    private readonly List<double> constants;
+    private readonly List<KeyValuePair<string, double>> constants;
+    private int constIndex;
     private int targetCount;
     private int currentLag;
@@ -41,5 +42,8 @@
     private SymbolicDataAnalysisExpressionLatexFormatter(SymbolicDataAnalysisExpressionLatexFormatter original, Cloner cloner)
       : base(original, cloner) {
-      constants = new List<double>(original.constants);
+      constants = new List<KeyValuePair<string, double>>(original.constants);
+      constIndex = original.constIndex;
+      currentLag = original.currentLag;
+      targetCount = original.targetCount;
     }
     public SymbolicDataAnalysisExpressionLatexFormatter()
@@ -47,5 +51,5 @@
       Name = ItemName;
       Description = ItemDescription;
-      constants = new List<double>();
+      constants = new List<KeyValuePair<string, double>>();
     }
 
@@ -58,8 +62,8 @@
         StringBuilder strBuilder = new StringBuilder();
         constants.Clear();
+        constIndex = 0;
         strBuilder.AppendLine(FormatRecursively(symbolicExpressionTree.Root));
         return strBuilder.ToString();
-      }
-      catch (NotImplementedException ex) {
+      } catch (NotImplementedException ex) {
         return ex.Message + Environment.NewLine + ex.StackTrace;
       }
@@ -75,5 +79,5 @@
       }
       int i = 1;
-      foreach (SymbolicExpressionTreeNode subTree in node.Subtrees.Skip(1)) {
+      foreach (var subTree in node.Subtrees.Skip(1)) {
         FormatSep(node, strBuilder, i);
         // format the whole subtree
@@ -166,12 +170,36 @@
         strBuilder.Append(@" \operatorname{if}  \left( ");
       } else if (node.Symbol is Constant) {
-        strBuilder.Append("c_{" + constants.Count + "} ");
+        var constName = "c_{" + constIndex + "}";
+        constIndex++;
+        strBuilder.Append(constName + " ");
         var constNode = node as ConstantTreeNode;
-        constants.Add(constNode.Value);
+        constants.Add(new KeyValuePair<string, double>(constName, constNode.Value));
+      } else if (node.Symbol is FactorVariable) {
+        var factorNode = node as FactorVariableTreeNode;
+        var constName = "c_{" + constIndex + "}";
+        strBuilder.Append(constName + " ");
+        foreach (var e in factorNode.Symbol.GetVariableValues(factorNode.VariableName)
+          .Zip(factorNode.Weights, Tuple.Create)) {
+          constants.Add(new KeyValuePair<string, double>("c_{" + constIndex + ", " + EscapeLatexString(factorNode.VariableName) + "=" + EscapeLatexString(e.Item1) + "}", e.Item2));
+        }
+        constIndex++;
+      } else if (node.Symbol is BinaryFactorVariable) {
+        var binFactorNode = node as BinaryFactorVariableTreeNode;
+        if (!binFactorNode.Weight.IsAlmost((1.0))) {
+          var constName = "c_{" + constIndex + "}";
+          strBuilder.Append(constName + "  \\cdot");
+          constants.Add(new KeyValuePair<string, double>(constName, binFactorNode.Weight));
+          constIndex++;
+        }
+        strBuilder.Append(EscapeLatexString(binFactorNode.VariableName));
+        strBuilder.Append(LagToString(currentLag));
+        strBuilder.Append(" = " + EscapeLatexString(binFactorNode.VariableValue));
       } else if (node.Symbol is LaggedVariable) {
         var laggedVarNode = node as LaggedVariableTreeNode;
         if (!laggedVarNode.Weight.IsAlmost(1.0)) {
-          strBuilder.Append("c_{" + constants.Count + "} \\cdot ");
-          constants.Add(laggedVarNode.Weight);
+          var constName = "c_{" + constIndex + "}";
+          strBuilder.Append(constName + "  \\cdot");
+          constants.Add(new KeyValuePair<string, double>(constName, laggedVarNode.Weight));
+          constIndex++;
         }
         strBuilder.Append(EscapeLatexString(laggedVarNode.VariableName));
@@ -181,6 +209,8 @@
         var varNode = node as VariableTreeNode;
         if (!varNode.Weight.IsAlmost((1.0))) {
-          strBuilder.Append("c_{" + constants.Count + "} \\cdot ");
-          constants.Add(varNode.Weight);
+          var constName = "c_{" + constIndex + "}";
+          strBuilder.Append(constName + "  \\cdot");
+          constants.Add(new KeyValuePair<string, double>(constName, varNode.Weight));
+          constIndex++;
         }
         strBuilder.Append(EscapeLatexString(varNode.VariableName));
@@ -216,8 +246,12 @@
       } else if (node.Symbol is VariableCondition) {
         var conditionTreeNode = node as VariableConditionTreeNode;
-        string p = @"1 /  1 + \exp  - c_{" + constants.Count + "} ";
-        constants.Add(conditionTreeNode.Slope);
-        p += @" \cdot " + EscapeLatexString(conditionTreeNode.VariableName) + LagToString(currentLag) + " - c_{" + constants.Count + @"}   ";
-        constants.Add(conditionTreeNode.Threshold);
+        var constName = "c_{" + constants.Count + "}";
+        string p = @"1 /  1 + \exp  - " + constName + " ";
+        constants.Add(new KeyValuePair<string, double>(constName, conditionTreeNode.Slope));
+        constIndex++;
+        var const2Name = "c_{" + constants.Count + @"}";
+        p += @" \cdot " + EscapeLatexString(conditionTreeNode.VariableName) + LagToString(currentLag) + " - " + const2Name + "   ";
+        constants.Add(new KeyValuePair<string, double>(const2Name, conditionTreeNode.Threshold));
+        constIndex++;
         strBuilder.Append(@" \left( " + p + @"\cdot ");
       } else {
@@ -310,8 +344,12 @@
       } 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 " + EscapeLatexString(conditionTreeNode.VariableName) + LagToString(currentLag) + " - c_{" + constants.Count + @"} \right) \right) \right)   ";
-        constants.Add(conditionTreeNode.Threshold);
+        var const1Name = "c_{" + constants.Count + "}";
+        string p = @"1 / \left( 1 + \exp \left( - " + const1Name + " ";
+        constants.Add(new KeyValuePair<string, double>(const1Name, conditionTreeNode.Slope));
+        constIndex++;
+        var const2Name = "c_{" + constants.Count + "}";
+        p += @" \cdot " + EscapeLatexString(conditionTreeNode.VariableName) + LagToString(currentLag) + " - " + const2Name + " \right) \right) \right)   ";
+        constants.Add(new KeyValuePair<string, double>(const2Name, conditionTreeNode.Threshold));
+        constIndex++;
         strBuilder.Append(@" +  \left( 1 - " + p + @" \right) \cdot ");
       } else {
@@ -391,4 +429,6 @@
       } else if (node.Symbol is LaggedVariable) {
       } else if (node.Symbol is Variable) {
+      } else if (node.Symbol is FactorVariable) {
+      } else if (node.Symbol is BinaryFactorVariable) {
       } else if (node.Symbol is ProgramRootSymbol) {
         strBuilder
@@ -398,13 +438,11 @@
         // output all constant values
         if (constants.Count > 0) {
-          int i = 0;
           foreach (var constant in constants) {
             // replace "." with ".&" to align decimal points
-            var constStr = string.Format(System.Globalization.NumberFormatInfo.InvariantInfo, "{0:G5}", constant);
+            var constStr = string.Format(System.Globalization.NumberFormatInfo.InvariantInfo, "{0:G5}", constant.Value);
             if (!constStr.Contains(".")) constStr = constStr + ".0";
             constStr = constStr.Replace(".", "&.");  // fix problem in rendering of aligned expressions
-            strBuilder.Append("c_{" + i + "}& = & " + constStr);
+            strBuilder.Append(constant.Key + "& = & " + constStr);
             strBuilder.Append(@"\\");
-            i++;
           }
         }
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 14258)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 14259)
@@ -35,5 +35,4 @@
   public class SymbolicDataAnalysisExpressionTreeSimplifier {
     private Addition addSymbol = new Addition();
-    private Subtraction subSymbol = new Subtraction();
     private Multiplication mulSymbol = new Multiplication();
     private Division divSymbol = new Division();
@@ -1034,6 +1033,5 @@
         return a;
       } else if (IsConstant(b) && IsAddition(a) ||
-          IsFactor(a) && IsAddition(b) ||
-          IsAddition(b) && IsFactor(a)) {
+          IsFactor(b) && IsAddition(a)) {
         // multiply constants into additions
         return a.Subtrees.Select(x => MakeProduct(x, b)).Aggregate((c, d) => MakeSum(c, d));
Index: /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs
===================================================================
--- /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs	(revision 14258)
+++ /branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs	(revision 14259)
@@ -114,5 +114,8 @@
 
     public override string ToString() {
-      return VariableName + " (factor)";
+      var weightStr = string.Join("; ",
+        Symbol.GetVariableValues(VariableName).Select(value => value + ": " + GetValue(value).ToString("E4")));
+      return VariableName + " (factor) "
+        + "[" + weightStr + "]";
     }
   }
