Index: branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
===================================================================
--- branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 12779)
+++ branches/crossvalidation-2434/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs	(revision 14029)
@@ -40,4 +40,5 @@
     private const string ConstantOptimizationRowsPercentageParameterName = "ConstantOptimizationRowsPercentage";
     private const string UpdateConstantsInTreeParameterName = "UpdateConstantsInSymbolicExpressionTree";
+    private const string UpdateVariableWeightsParameterName = "Update Variable Weights";
 
     public IFixedValueParameter<IntValue> ConstantOptimizationIterationsParameter {
@@ -56,4 +57,8 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateConstantsInTreeParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> UpdateVariableWeightsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[UpdateVariableWeightsParameterName]; }
+    }
+
 
     public IntValue ConstantOptimizationIterations {
@@ -72,4 +77,9 @@
       get { return UpdateConstantsInTreeParameter.Value.Value; }
       set { UpdateConstantsInTreeParameter.Value.Value = value; }
+    }
+
+    public bool UpdateVariableWeights {
+      get { return UpdateVariableWeightsParameter.Value.Value; }
+      set { UpdateVariableWeightsParameter.Value.Value = value; }
     }
 
@@ -86,8 +96,9 @@
       : base() {
       Parameters.Add(new FixedValueParameter<IntValue>(ConstantOptimizationIterationsParameterName, "Determines how many iterations should be calculated while optimizing the constant of a symbolic expression tree (0 indicates other or default stopping criterion).", new IntValue(10), true));
-      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0), true));
+      Parameters.Add(new FixedValueParameter<DoubleValue>(ConstantOptimizationImprovementParameterName, "Determines the relative improvement which must be achieved in the constant optimization to continue with it (0 indicates other or default stopping criterion).", new DoubleValue(0), true) { Hidden = true });
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationProbabilityParameterName, "Determines the probability that the constants are optimized", new PercentValue(1), true));
       Parameters.Add(new FixedValueParameter<PercentValue>(ConstantOptimizationRowsPercentageParameterName, "Determines the percentage of the rows which should be used for constant optimization", new PercentValue(1), true));
-      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)) { Hidden = true });
+      Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)) { Hidden = true });
     }
 
@@ -100,4 +111,6 @@
       if (!Parameters.ContainsKey(UpdateConstantsInTreeParameterName))
         Parameters.Add(new FixedValueParameter<BoolValue>(UpdateConstantsInTreeParameterName, "Determines if the constants in the tree should be overwritten by the optimized constants.", new BoolValue(true)));
+      if (!Parameters.ContainsKey(UpdateVariableWeightsParameterName))
+        Parameters.Add(new FixedValueParameter<BoolValue>(UpdateVariableWeightsParameterName, "Determines if the variable weights in the tree should be  optimized.", new BoolValue(true)));
     }
 
@@ -108,6 +121,5 @@
         IEnumerable<int> constantOptimizationRows = GenerateRowsToEvaluate(ConstantOptimizationRowsPercentage.Value);
         quality = OptimizeConstants(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution, ProblemDataParameter.ActualValue,
-           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value,
-           EstimationLimitsParameter.ActualValue.Upper, EstimationLimitsParameter.ActualValue.Lower, UpdateConstantsInTree);
+           constantOptimizationRows, ApplyLinearScalingParameter.ActualValue.Value, ConstantOptimizationIterations.Value, updateVariableWeights: UpdateVariableWeights, lowerEstimationLimit: EstimationLimitsParameter.ActualValue.Lower, upperEstimationLimit: EstimationLimitsParameter.ActualValue.Upper, updateConstantsInTree: UpdateConstantsInTree);
 
         if (ConstantOptimizationRowsPercentage.Value != RelativeNumberOfEvaluatedSamplesParameter.ActualValue.Value) {
@@ -164,6 +176,5 @@
 
 
-    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
-      IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, bool updateConstantsInTree = true) {
+    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, bool updateVariableWeights = true, double lowerEstimationLimit = double.MinValue, double upperEstimationLimit = double.MaxValue, bool updateConstantsInTree = true) {
 
       List<AutoDiff.Variable> variables = new List<AutoDiff.Variable>();
@@ -172,17 +183,21 @@
 
       AutoDiff.Term func;
-      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, out func))
+      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out func))
         throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
       if (variableNames.Count == 0) return 0.0;
 
-      AutoDiff.IParametricCompiledTerm compiledFunc = AutoDiff.TermUtils.Compile(func, variables.ToArray(), parameters.ToArray());
-
-      List<SymbolicExpressionTreeTerminalNode> terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
+      AutoDiff.IParametricCompiledTerm compiledFunc = func.Compile(variables.ToArray(), parameters.ToArray());
+
+      List<SymbolicExpressionTreeTerminalNode> terminalNodes = null;
+      if (updateVariableWeights)
+        terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList();
+      else
+        terminalNodes = new List<SymbolicExpressionTreeTerminalNode>(tree.Root.IterateNodesPrefix().OfType<ConstantTreeNode>());
+
+      //extract inital constants
       double[] c = new double[variables.Count];
-
       {
         c[0] = 0.0;
         c[1] = 1.0;
-        //extract inital constants
         int i = 2;
         foreach (var node in terminalNodes) {
@@ -191,5 +206,5 @@
           if (constantTreeNode != null)
             c[i++] = constantTreeNode.Value;
-          else if (variableTreeNode != null)
+          else if (updateVariableWeights && variableTreeNode != null)
             c[i++] = variableTreeNode.Weight;
         }
@@ -234,10 +249,10 @@
 
       //info == -7  => constant optimization failed due to wrong gradient
-      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray());
+      if (info != -7) UpdateConstants(tree, c.Skip(2).ToArray(), updateVariableWeights);
       var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
 
-      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+      if (!updateConstantsInTree) UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
       if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
-        UpdateConstants(tree, originalConstants.Skip(2).ToArray());
+        UpdateConstants(tree, originalConstants.Skip(2).ToArray(), updateVariableWeights);
         return originalQuality;
       }
@@ -245,5 +260,5 @@
     }
 
-    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants) {
+    private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
       int i = 0;
       foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
@@ -252,5 +267,5 @@
         if (constantTreeNode != null)
           constantTreeNode.Value = constants[i++];
-        else if (variableTreeNode != null)
+        else if (updateVariableWeights && variableTreeNode != null)
           variableTreeNode.Weight = constants[i++];
       }
@@ -271,5 +286,5 @@
     }
 
-    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, out AutoDiff.Term term) {
+    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters, List<string> variableNames, bool updateVariableWeights, out AutoDiff.Term term) {
       if (node.Symbol is Constant) {
         var var = new AutoDiff.Variable();
@@ -283,7 +298,12 @@
         parameters.Add(par);
         variableNames.Add(varNode.VariableName);
-        var w = new AutoDiff.Variable();
-        variables.Add(w);
-        term = AutoDiff.TermBuilder.Product(w, par);
+
+        if (updateVariableWeights) {
+          var w = new AutoDiff.Variable();
+          variables.Add(w);
+          term = AutoDiff.TermBuilder.Product(w, par);
+        } else {
+          term = par;
+        }
         return true;
       }
@@ -292,5 +312,5 @@
         foreach (var subTree in node.Subtrees) {
           AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out t)) {
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
             term = null;
             return false;
@@ -305,5 +325,5 @@
         for (int i = 0; i < node.SubtreeCount; i++) {
           AutoDiff.Term t;
-          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, out t)) {
+          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, updateVariableWeights, out t)) {
             term = null;
             return false;
@@ -316,47 +336,35 @@
       }
       if (node.Symbol is Multiplication) {
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(f);
+        List<AutoDiff.Term> terms = new List<Term>();
+        foreach (var subTree in node.Subtrees) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
+            term = null;
+            return false;
           }
-          term = AutoDiff.TermBuilder.Product(a, b, factors.ToArray());
-          return true;
-        }
+          terms.Add(t);
+        }
+        if (terms.Count == 1) term = terms[0];
+        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, b));
+        return true;
+
       }
       if (node.Symbol is Division) {
-        // only works for at least two subtrees
-        AutoDiff.Term a, b;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out a) ||
-          !TryTransformToAutoDiff(node.GetSubtree(1), variables, parameters, variableNames, out b)) {
-          term = null;
-          return false;
-        } else {
-          List<AutoDiff.Term> factors = new List<Term>();
-          foreach (var subTree in node.Subtrees.Skip(2)) {
-            AutoDiff.Term f;
-            if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, out f)) {
-              term = null;
-              return false;
-            }
-            factors.Add(1.0 / f);
+        List<AutoDiff.Term> terms = new List<Term>();
+        foreach (var subTree in node.Subtrees) {
+          AutoDiff.Term t;
+          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, updateVariableWeights, out t)) {
+            term = null;
+            return false;
           }
-          term = AutoDiff.TermBuilder.Product(a, 1.0 / b, factors.ToArray());
-          return true;
-        }
+          terms.Add(t);
+        }
+        if (terms.Count == 1) term = 1.0 / terms[0];
+        else term = terms.Aggregate((a, b) => new AutoDiff.Product(a, 1.0 / b));
+        return true;
       }
       if (node.Symbol is Logarithm) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -368,5 +376,5 @@
       if (node.Symbol is Exponential) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -378,5 +386,5 @@
       if (node.Symbol is Square) {
         AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -385,7 +393,8 @@
           return true;
         }
-      } if (node.Symbol is SquareRoot) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is SquareRoot) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -394,7 +403,8 @@
           return true;
         }
-      } if (node.Symbol is Sine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Sine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -403,7 +413,8 @@
           return true;
         }
-      } if (node.Symbol is Cosine) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Cosine) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -412,7 +423,8 @@
           return true;
         }
-      } if (node.Symbol is Tangent) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Tangent) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -421,7 +433,8 @@
           return true;
         }
-      } if (node.Symbol is Erf) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Erf) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -430,7 +443,8 @@
           return true;
         }
-      } if (node.Symbol is Norm) {
-        AutoDiff.Term t;
-        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
+      }
+      if (node.Symbol is Norm) {
+        AutoDiff.Term t;
+        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out t)) {
           term = null;
           return false;
@@ -446,5 +460,5 @@
         variables.Add(alpha);
         AutoDiff.Term branchTerm;
-        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out branchTerm)) {
+        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, updateVariableWeights, out branchTerm)) {
           term = branchTerm * alpha + beta;
           return true;
