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 14330)
+++ branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs	(revision 14339)
@@ -651,6 +651,5 @@
       } else if (IsFactor(node)) {
         var factNode = node as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Exp(factNode.Weights[i]);
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Exp(w)));
       } else if (IsLog(node)) {
         return node.GetSubtree(0);
@@ -672,6 +671,5 @@
       } else if (IsFactor(node)) {
         var factNode = node as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] * factNode.Weights[i];
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w * w));
       } else if (IsSquareRoot(node)) {
         return node.GetSubtree(0);
@@ -689,6 +687,5 @@
       } else if (IsFactor(node)) {
         var factNode = node as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Sqrt(factNode.Weights[i]);
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Sqrt(w)));
       } else if (IsSquare(node)) {
         return node.GetSubtree(0);
@@ -706,6 +703,5 @@
       } else if (IsFactor(node)) {
         var factNode = node as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Log(factNode.Weights[i]);
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Log(w)));
       } else if (IsExp(node)) {
         return node.GetSubtree(0);
@@ -727,19 +723,14 @@
         var factNode = a as FactorVariableTreeNode;
         var constNode = b as ConstantTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++)
-          factNode.Weights[i] = Math.Pow(factNode.Weights[i], 1.0 / Math.Round(constNode.Value));
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName,
+          factNode.Weights.Select(w => Math.Pow(w, 1.0 / Math.Round(constNode.Value))));
       } else if (IsConstant(a) && IsFactor(b)) {
         var constNode = a as ConstantTreeNode;
         var factNode = b as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++)
-          factNode.Weights[i] = Math.Pow(constNode.Value, 1.0 / Math.Round(factNode.Weights[i]));
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, 1.0 / Math.Round(w))));
       } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) {
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as FactorVariableTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++)
-          node0.Weights[i] = Math.Pow(node0.Weights[i], 1.0 / Math.Round(node1.Weights[i]));
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, 1.0 / Math.Round(v))));
       } else if (IsConstant(b)) {
         var constB = b as ConstantTreeNode;
@@ -770,4 +761,5 @@
     }
 
+
     private ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) {
       if (IsConstant(a) && IsConstant(b)) {
@@ -778,19 +770,13 @@
         var factNode = a as FactorVariableTreeNode;
         var constNode = b as ConstantTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++)
-          factNode.Weights[i] = Math.Pow(factNode.Weights[i], Math.Round(constNode.Value));
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(w, Math.Round(constNode.Value))));
       } else if (IsConstant(a) && IsFactor(b)) {
         var constNode = a as ConstantTreeNode;
         var factNode = b as FactorVariableTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++)
-          factNode.Weights[i] = Math.Pow(constNode.Value, Math.Round(factNode.Weights[i]));
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => Math.Pow(constNode.Value, Math.Round(w))));
       } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) {
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as FactorVariableTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++)
-          node0.Weights[i] = Math.Pow(node0.Weights[i], Math.Round(node1.Weights[i]));
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => Math.Pow(u, Math.Round(v))));
       } else if (IsConstant(b)) {
         var constB = b as ConstantTreeNode;
@@ -837,11 +823,9 @@
         var factNode = a as FactorVariableTreeNode;
         var constNode = b as ConstantTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] / constNode.Value;
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select(w => w / constNode.Value));
       } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) {
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as FactorVariableTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] / node1.Weights[i];
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => u / v));
       } else if (IsFactor(a)) {
         return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a)));
@@ -893,11 +877,9 @@
         var factNode = a as FactorVariableTreeNode;
         var constNode = b as ConstantTreeNode;
-        for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] + constNode.Value;
-        return factNode;
+        return MakeFactor(factNode.Symbol, factNode.VariableName, factNode.Weights.Select((w) => w + constNode.Value));
       } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) {
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as FactorVariableTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] + node1.Weights[i];
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => u + v));
       } else if (IsAddition(a) && IsAddition(b)) {
         // merge additions
@@ -1018,11 +1000,9 @@
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as FactorVariableTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] * node1.Weights[i];
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Zip(node1.Weights, (u, v) => u * v));
       } else if (IsFactor(a) && IsConstant(b)) {
         var node0 = a as FactorVariableTreeNode;
         var node1 = b as ConstantTreeNode;
-        for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] * node1.Value;
-        return node0;
+        return MakeFactor(node0.Symbol, node0.VariableName, node0.Weights.Select(w => w * node1.Value));
       } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(1.0)) {
         // $ * 1.0 => $
@@ -1257,4 +1237,11 @@
       return tree;
     }
+    private ISymbolicExpressionTreeNode MakeFactor(FactorVariable sy, string variableName, IEnumerable<double> weights) {
+      var tree = (FactorVariableTreeNode)sy.CreateTreeNode();
+      tree.VariableName = variableName;
+      tree.Weights = weights.ToArray();
+      return tree;
+    }
+
 
     #endregion
