Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.cs	(revision 18233)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.cs	(revision 18234)
@@ -85,6 +85,5 @@
         .SelectMany(var => problemData.Dataset.GetDoubleVectorValues(var, rows))
         .Select(v => v.Count);
-      var vectorlength = vectorLengths.First();
-      if (vectorLengths.Any(l => l != vectorlength))
+      if (vectorLengths.Distinct().Count() > 1)
         throw new InvalidOperationException("All vectors must be of same length.");
       var evaluationTraces = interpreter.GetIntermediateNodeValues(tree, problemData.Dataset, rows);
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/VectorUnrollingTreeToAutoDiffTermConverter.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/VectorUnrollingTreeToAutoDiffTermConverter.cs	(revision 18233)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/VectorUnrollingTreeToAutoDiffTermConverter.cs	(revision 18234)
@@ -153,11 +153,28 @@
     }
 
+    private static IEnumerable<IEnumerable<T>> Broadcast<T>(IList<T>[] source) {
+      var maxLength = source.Max(x => x.Count);
+      if (source.Any(x => x.Count != maxLength && x.Count != 1))
+        throw new InvalidOperationException("Length must match to maxLength or one");
+      return source.Select(x => x.Count == maxLength ? x : Enumerable.Repeat(x[0], maxLength));
+    }
+    public static IEnumerable<IEnumerable<T>> Transpose<T>(IEnumerable<IEnumerable<T>> source) {
+      var enumerators = source.Select(x => x.GetEnumerator()).ToArray();
+      try {
+        while (enumerators.All(x => x.MoveNext())) {
+          yield return enumerators.Select(x => x.Current).ToArray();
+        }
+      } finally {
+        foreach (var enumerator in enumerators)
+          enumerator.Dispose();
+      }
+    }
+
     private IList<AutoDiff.Term> ConvertToAutoDiff(ISymbolicExpressionTreeNode node) {
       IList<Term> BinaryOp(Func<Term, Term, Term> binaryOp, Func<Term, Term> singleElementOp, params IList<Term>[] terms) {
         if (terms.Length == 1) return terms[0].Select(singleElementOp).ToList();
-        return terms.Aggregate((acc, vectorizedTerm) => acc.Zip(vectorizedTerm, binaryOp).ToList());
-      }
-      IList<Term> BinaryOp2(Func<Term, Term, Term> binaryOp, params IList<Term>[] terms) {
-        return terms.Aggregate((acc, vectorizedTerm) => acc.Zip(vectorizedTerm, binaryOp).ToList());
+        var broadcastedTerms = Broadcast(terms);
+        var transposedTerms = Transpose(broadcastedTerms);
+        return transposedTerms.Select(term => term.Aggregate(binaryOp)).ToList();
       }
       IList<Term> UnaryOp(Func<Term, Term> unaryOp, IList<Term> term) {
@@ -340,4 +357,19 @@
       //}
 
+      if (node.Symbol is SubVector) {
+        var term = node.Subtrees.Select(ConvertToAutoDiff).Single();
+        var windowedNode = (IWindowedSymbolTreeNode)node;
+        int startIdx = SymbolicDataAnalysisExpressionTreeVectorInterpreter.ToVectorIdx(windowedNode.Offset, term.Count);
+        int endIdx = SymbolicDataAnalysisExpressionTreeVectorInterpreter.ToVectorIdx(windowedNode.Length, term.Count);
+        var slices = SymbolicDataAnalysisExpressionTreeVectorInterpreter.GetVectorSlices(startIdx, endIdx, term.Count);
+
+        var selectedTerms = new List<Term>(capacity: slices.Sum(s => s.Item2));
+        foreach (var (start, count) in slices) {
+          for (int i = start; i < start + count; i++){
+             selectedTerms.Add(term[i]);
+          }
+        }
+        return selectedTerms;
+      }
 
       throw new ConversionException();
@@ -394,9 +426,10 @@
           //!(n.Symbol is Min) &&
           //!(n.Symbol is Max) &&
-          !(n.Symbol is Variance)
+          !(n.Symbol is Variance) &&
         //!(n.Symbol is Skewness) &&
         //!(n.Symbol is Kurtosis) &&
         //!(n.Symbol is EuclideanDistance) &&
-        //!(n.Symbol is Covariance)
+        //!(n.Symbol is Covariance) &&
+          !(n.Symbol is SubVector)
         select n).Any();
       return !containsUnknownSymbol;
Index: /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs
===================================================================
--- /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs	(revision 18233)
+++ /branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs	(revision 18234)
@@ -728,20 +728,7 @@
           }
         case OpCodes.SubVector: {
-            DoubleVector SubVector(DoubleVector v , double start, double end) { 
-              int size = v.Count;
-              int ToIdx(double x) {
-                int idx = (int)Math.Round(x * (size - 1));
-                return (idx % size + size) % size; // positive mod
-              }
-              int startIdx = ToIdx(start);
-              int endIdx = ToIdx(end);
-              if (startIdx <= endIdx) {
-                return v.SubVector(startIdx, count: endIdx - startIdx + 1); // incl end
-              } else { // wrap around
-                var resultVector = DoubleVector.Build.Dense(size: size - (startIdx - endIdx) + 1);
-                v.CopySubVectorTo(resultVector, sourceIndex: startIdx, targetIndex: 0,               count: size - startIdx); // copy [startIdx:size] to [0:size-startIdx]
-                v.CopySubVectorTo(resultVector, sourceIndex: 0,        targetIndex: size - startIdx, count: endIdx);          // copy [0:endIdx]      to [size-startIdx:size]
-                return resultVector;
-              }
+            DoubleVector SubVector(DoubleVector v , double start, double end) {
+              int startIdx = ToVectorIdx(start, v.Count), endIdx = ToVectorIdx(end, v.Count);
+              return RoundTripSubVector(v, startIdx, endIdx);
             }
             var cur = Evaluate(dataset, ref row, state, traceDict);
@@ -756,16 +743,6 @@
         case OpCodes.SubVectorSubtree: {
             DoubleVector SubVector(DoubleVector v, double start, double end) {
-              int Mod(int x, int m) => (x % m + m) % m;
-              int startIdx = Mod((int)Math.Round(start * v.Count), v.Count);
-              int endIdx = Mod((int)Math.Round(end * v.Count), v.Count);
-              int size = v.Count;
-              if (startIdx < endIdx) {
-                return v.SubVector(startIdx, count: endIdx - startIdx);
-              } else { // wrap around
-                var resultVector = DoubleVector.Build.Dense(size: size - (startIdx - endIdx));
-                v.CopySubVectorTo(resultVector, startIdx, 0, size - startIdx); // copy [startIdx:size] to [0:size-startIdx]
-                v.CopySubVectorTo(resultVector, 0, size - startIdx, endIdx);   // copy [0:endIdx]      to [size-startIdx:size]
-                return resultVector;
-              }
+              int startIdx = ToVectorIdx(start, v.Count), endIdx = ToVectorIdx(end, v.Count);
+              return RoundTripSubVector(v, startIdx, endIdx);
             }
             var cur = Evaluate(dataset, ref row, state, traceDict);
@@ -1187,4 +1164,32 @@
     }
 
+    public static int ToVectorIdx(double relPosition, int size) {
+      int idx = (int)Math.Round(relPosition * (size - 1));
+      return (idx % size + size) % size; // positive mod
+    }
+
+    public static IEnumerable<Tuple<int, int>>/*start, count*/ GetVectorSlices(int startIdx, int endIdx, int size) {
+      if (startIdx <= endIdx) {
+        yield return Tuple.Create(startIdx, endIdx - startIdx + 1); // incl end
+      } else {
+        yield return Tuple.Create(startIdx, size - startIdx); // startIdx to end of vector
+        yield return Tuple.Create(0, endIdx);                 // start to endIdx of vector
+      }
+    }
+   
+    public static DoubleVector RoundTripSubVector(DoubleVector v, int startIdx, int endIdx) {
+      var slices = GetVectorSlices(startIdx, endIdx, v.Count).ToList();
+      var totalSize = slices.Sum(s => s.Item2);
+      var resultVector = DoubleVector.Build.Dense(size: totalSize);
+
+      var curIdx = 0;
+      foreach (var slice in slices) {
+        int start = slice.Item1, count = slice.Item2;
+        v.CopySubVectorTo(resultVector, sourceIndex: start, targetIndex: curIdx, count: count);
+        curIdx += count;
+      }
+      return resultVector;
+    }
+
     private static int LongestStrikeAbove(DoubleVector v, double threshold) {
       int longestStrike = 0, currentStrike = 0;
