Index: /branches/3106_AnalyticContinuedFractionsRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/ContinuedFractionRegression/Algorithm.cs
===================================================================
--- /branches/3106_AnalyticContinuedFractionsRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/ContinuedFractionRegression/Algorithm.cs	(revision 17971)
+++ /branches/3106_AnalyticContinuedFractionsRegression/HeuristicLab.Algorithms.DataAnalysis/3.4/ContinuedFractionRegression/Algorithm.cs	(revision 17972)
@@ -24,13 +24,13 @@
       var x = problemData.Dataset.ToArray(problemData.AllowedInputVariables.Concat(new[] { problemData.TargetVariable }),
         problemData.TrainingIndices);
-      var nVars = x.GetLength(1);
+      var nVars = x.GetLength(1) - 1;
       var rand = new MersenneTwister(31415);
-      CFRAlgorithm(nVars, depth: 4, 0.10, x, out var best, out var bestObj, rand, numGen: 200, cancellationToken);
+      CFRAlgorithm(nVars, depth: 6, 0.10, x, out var best, out var bestObj, rand, numGen: 200, stagnatingGens: 5, cancellationToken);
     }
 
     private void CFRAlgorithm(int nVars, int depth, double mutationRate, double[,] trainingData,
       out ContinuedFraction best, out double bestObj,
-      IRandom rand, int numGen,
-      CancellationToken cancellation) {
+      IRandom rand, int numGen, int stagnatingGens,
+      CancellationToken cancellationToken) {
       /* Algorithm 1 */
       /* Generate initial population by a randomized algorithm */
@@ -38,6 +38,6 @@
       best = pop.pocket;
       bestObj = pop.pocketObjValue;
-
-      for (int gen = 1; gen <= numGen && !cancellation.IsCancellationRequested; gen++) {
+      var bestObjGen = 0;
+      for (int gen = 1; gen <= numGen && !cancellationToken.IsCancellationRequested; gen++) {
         /* mutate each current solution in the population */
         var pop_mu = Mutate(pop, mutationRate, rand);
@@ -47,14 +47,8 @@
         /* local search optimization of current solutions */
         foreach (var agent in pop_r.IterateLevels()) {
-          LocalSearchSimplex(agent.current, trainingData, rand);
+          LocalSearchSimplex(agent.current, ref agent.currentObjValue, trainingData, rand);
         }
 
         foreach (var agent in pop_r.IteratePostOrder()) agent.MaintainInvariant(); // Deviates from Alg1 in paper 
-
-        /* TODO 
-        if (stagnating(curQuality, bestQuality, numStagnatingGensForReset)) {
-          Reset(pop_r.root);
-        }
-        */
 
         /* replace old population with evolved population */
@@ -65,5 +59,13 @@
           best = pop.pocket;
           bestObj = pop.pocketObjValue;
+          bestObjGen = gen;
           Results.AddOrUpdateResult("MSE (best)", new DoubleValue(bestObj));
+        }
+
+
+        if (gen > bestObjGen + stagnatingGens) {
+          bestObjGen = gen; // wait at least stagnatingGens until resetting again
+          // Reset(pop, nVars, depth, rand, trainingData);
+          InitialPopulation(nVars, depth, rand, trainingData);
         }
       }
@@ -95,4 +97,20 @@
       return pop;
     }
+
+    // TODO: reset is not described in the paper
+    private void Reset(Agent root, int nVars, int depth, IRandom rand, double[,] trainingData) {
+      root.pocket = new ContinuedFraction(nVars, depth, rand);
+      root.current = new ContinuedFraction(nVars, depth, rand);
+
+      root.currentObjValue = Evaluate(root.current, trainingData);
+      root.pocketObjValue = Evaluate(root.pocket, trainingData);
+
+      /* within each agent, the pocket solution always holds the better value of guiding
+       * function than its current solution
+       */
+      root.MaintainInvariant();
+    }
+
+
 
     private Agent RecombinePopulation(Agent pop, IRandom rand, int nVars) {
@@ -182,5 +200,6 @@
              agent.currentObjValue > 2 * agent.pocketObjValue)
             ToggleVariables(agent.current, rand); // major mutation
-          else ModifyVariable(agent.current, rand); // soft mutation
+          else
+            ModifyVariable(agent.current, rand); // soft mutation
         }
       }
@@ -258,6 +277,6 @@
         var hi = cfrac.h[i];
         var hi1 = cfrac.h[i - 1];
-        var denom = hi.beta + dot(dataPoint, hi.coef) + res;
-        var numerator = hi1.beta + dot(dataPoint, hi1.coef);
+        var denom = hi.beta + dot(hi.vars, hi.coef, dataPoint) + res;
+        var numerator = hi1.beta + dot(hi1.vars, hi1.coef, dataPoint);
         res = numerator / denom;
       }
@@ -265,13 +284,14 @@
     }
 
-    private static double dot(double[] x, double[] y) {
+    private static double dot(bool[] filter, double[] x, double[] y) {
       var s = 0.0;
       for (int i = 0; i < x.Length; i++)
-        s += x[i] * y[i];
+        if (filter[i])
+          s += x[i] * y[i];
       return s;
     }
 
 
-    private static ContinuedFraction LocalSearchSimplex(ContinuedFraction ch, double[,] trainingData, IRandom rand) {
+    private static void LocalSearchSimplex(ContinuedFraction ch, ref double quality, double[,] trainingData, IRandom rand) {
       double uniformPeturbation = 1.0;
       double tolerance = 1e-3;
@@ -281,8 +301,10 @@
       int numSelectedRows = numRows / 5; // 20% of the training samples
 
+      quality = Evaluate(ch, trainingData); // get quality with origial coefficients
+
       double[] origCoeff = ExtractCoeff(ch);
-      if (origCoeff.Length == 0) return ch; // no parameters to optimize
-
-      var bestQuality = Evaluate(ch, trainingData); // get quality with origial coefficients
+      if (origCoeff.Length == 0) return; // no parameters to optimize
+
+      var bestQuality = quality;
       var bestCoeff = origCoeff;
 
@@ -317,5 +339,5 @@
 
       SetCoeff(ch, bestCoeff);
-      return ch;
+      quality = bestQuality;
     }
 
@@ -338,4 +360,5 @@
       var coeff = new List<double>();
       foreach (var hi in ch.h) {
+        coeff.Add(hi.beta);
         for (int vIdx = 0; vIdx < hi.vars.Length; vIdx++) {
           if (hi.vars[vIdx]) coeff.Add(hi.coef[vIdx]);
@@ -348,4 +371,5 @@
       int k = 0;
       foreach (var hi in ch.h) {
+        hi.beta = curCoeff[k++];
         for (int vIdx = 0; vIdx < hi.vars.Length; vIdx++) {
           if (hi.vars[vIdx]) hi.coef[vIdx] = curCoeff[k++];
