Free cookie consent management tool by TermsFeed Policy Generator

Changeset 18234


Ignore:
Timestamp:
03/14/22 11:35:10 (2 years ago)
Author:
pfleck
Message:

#3040 Fixed vector-unrolling AutoDiff conversion.

Location:
branches/3040_VectorBasedGP
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/VectorUnrollingNonlinearLeastSquaresConstantOptimizationEvaluator.cs

    r17726 r18234  
    8585        .SelectMany(var => problemData.Dataset.GetDoubleVectorValues(var, rows))
    8686        .Select(v => v.Count);
    87       var vectorlength = vectorLengths.First();
    88       if (vectorLengths.Any(l => l != vectorlength))
     87      if (vectorLengths.Distinct().Count() > 1)
    8988        throw new InvalidOperationException("All vectors must be of same length.");
    9089      var evaluationTraces = interpreter.GetIntermediateNodeValues(tree, problemData.Dataset, rows);
  • branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/VectorUnrollingTreeToAutoDiffTermConverter.cs

    r17726 r18234  
    153153    }
    154154
     155    private static IEnumerable<IEnumerable<T>> Broadcast<T>(IList<T>[] source) {
     156      var maxLength = source.Max(x => x.Count);
     157      if (source.Any(x => x.Count != maxLength && x.Count != 1))
     158        throw new InvalidOperationException("Length must match to maxLength or one");
     159      return source.Select(x => x.Count == maxLength ? x : Enumerable.Repeat(x[0], maxLength));
     160    }
     161    public static IEnumerable<IEnumerable<T>> Transpose<T>(IEnumerable<IEnumerable<T>> source) {
     162      var enumerators = source.Select(x => x.GetEnumerator()).ToArray();
     163      try {
     164        while (enumerators.All(x => x.MoveNext())) {
     165          yield return enumerators.Select(x => x.Current).ToArray();
     166        }
     167      } finally {
     168        foreach (var enumerator in enumerators)
     169          enumerator.Dispose();
     170      }
     171    }
     172
    155173    private IList<AutoDiff.Term> ConvertToAutoDiff(ISymbolicExpressionTreeNode node) {
    156174      IList<Term> BinaryOp(Func<Term, Term, Term> binaryOp, Func<Term, Term> singleElementOp, params IList<Term>[] terms) {
    157175        if (terms.Length == 1) return terms[0].Select(singleElementOp).ToList();
    158         return terms.Aggregate((acc, vectorizedTerm) => acc.Zip(vectorizedTerm, binaryOp).ToList());
    159       }
    160       IList<Term> BinaryOp2(Func<Term, Term, Term> binaryOp, params IList<Term>[] terms) {
    161         return terms.Aggregate((acc, vectorizedTerm) => acc.Zip(vectorizedTerm, binaryOp).ToList());
     176        var broadcastedTerms = Broadcast(terms);
     177        var transposedTerms = Transpose(broadcastedTerms);
     178        return transposedTerms.Select(term => term.Aggregate(binaryOp)).ToList();
    162179      }
    163180      IList<Term> UnaryOp(Func<Term, Term> unaryOp, IList<Term> term) {
     
    340357      //}
    341358
     359      if (node.Symbol is SubVector) {
     360        var term = node.Subtrees.Select(ConvertToAutoDiff).Single();
     361        var windowedNode = (IWindowedSymbolTreeNode)node;
     362        int startIdx = SymbolicDataAnalysisExpressionTreeVectorInterpreter.ToVectorIdx(windowedNode.Offset, term.Count);
     363        int endIdx = SymbolicDataAnalysisExpressionTreeVectorInterpreter.ToVectorIdx(windowedNode.Length, term.Count);
     364        var slices = SymbolicDataAnalysisExpressionTreeVectorInterpreter.GetVectorSlices(startIdx, endIdx, term.Count);
     365
     366        var selectedTerms = new List<Term>(capacity: slices.Sum(s => s.Item2));
     367        foreach (var (start, count) in slices) {
     368          for (int i = start; i < start + count; i++){
     369             selectedTerms.Add(term[i]);
     370          }
     371        }
     372        return selectedTerms;
     373      }
    342374
    343375      throw new ConversionException();
     
    394426          //!(n.Symbol is Min) &&
    395427          //!(n.Symbol is Max) &&
    396           !(n.Symbol is Variance)
     428          !(n.Symbol is Variance) &&
    397429        //!(n.Symbol is Skewness) &&
    398430        //!(n.Symbol is Kurtosis) &&
    399431        //!(n.Symbol is EuclideanDistance) &&
    400         //!(n.Symbol is Covariance)
     432        //!(n.Symbol is Covariance) &&
     433          !(n.Symbol is SubVector)
    401434        select n).Any();
    402435      return !containsUnknownSymbol;
  • branches/3040_VectorBasedGP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeVectorInterpreter.cs

    r18230 r18234  
    728728          }
    729729        case OpCodes.SubVector: {
    730             DoubleVector SubVector(DoubleVector v , double start, double end) {
    731               int size = v.Count;
    732               int ToIdx(double x) {
    733                 int idx = (int)Math.Round(x * (size - 1));
    734                 return (idx % size + size) % size; // positive mod
    735               }
    736               int startIdx = ToIdx(start);
    737               int endIdx = ToIdx(end);
    738               if (startIdx <= endIdx) {
    739                 return v.SubVector(startIdx, count: endIdx - startIdx + 1); // incl end
    740               } else { // wrap around
    741                 var resultVector = DoubleVector.Build.Dense(size: size - (startIdx - endIdx) + 1);
    742                 v.CopySubVectorTo(resultVector, sourceIndex: startIdx, targetIndex: 0,               count: size - startIdx); // copy [startIdx:size] to [0:size-startIdx]
    743                 v.CopySubVectorTo(resultVector, sourceIndex: 0,        targetIndex: size - startIdx, count: endIdx);          // copy [0:endIdx]      to [size-startIdx:size]
    744                 return resultVector;
    745               }
     730            DoubleVector SubVector(DoubleVector v , double start, double end) {
     731              int startIdx = ToVectorIdx(start, v.Count), endIdx = ToVectorIdx(end, v.Count);
     732              return RoundTripSubVector(v, startIdx, endIdx);
    746733            }
    747734            var cur = Evaluate(dataset, ref row, state, traceDict);
     
    756743        case OpCodes.SubVectorSubtree: {
    757744            DoubleVector SubVector(DoubleVector v, double start, double end) {
    758               int Mod(int x, int m) => (x % m + m) % m;
    759               int startIdx = Mod((int)Math.Round(start * v.Count), v.Count);
    760               int endIdx = Mod((int)Math.Round(end * v.Count), v.Count);
    761               int size = v.Count;
    762               if (startIdx < endIdx) {
    763                 return v.SubVector(startIdx, count: endIdx - startIdx);
    764               } else { // wrap around
    765                 var resultVector = DoubleVector.Build.Dense(size: size - (startIdx - endIdx));
    766                 v.CopySubVectorTo(resultVector, startIdx, 0, size - startIdx); // copy [startIdx:size] to [0:size-startIdx]
    767                 v.CopySubVectorTo(resultVector, 0, size - startIdx, endIdx);   // copy [0:endIdx]      to [size-startIdx:size]
    768                 return resultVector;
    769               }
     745              int startIdx = ToVectorIdx(start, v.Count), endIdx = ToVectorIdx(end, v.Count);
     746              return RoundTripSubVector(v, startIdx, endIdx);
    770747            }
    771748            var cur = Evaluate(dataset, ref row, state, traceDict);
     
    11871164    }
    11881165
     1166    public static int ToVectorIdx(double relPosition, int size) {
     1167      int idx = (int)Math.Round(relPosition * (size - 1));
     1168      return (idx % size + size) % size; // positive mod
     1169    }
     1170
     1171    public static IEnumerable<Tuple<int, int>>/*start, count*/ GetVectorSlices(int startIdx, int endIdx, int size) {
     1172      if (startIdx <= endIdx) {
     1173        yield return Tuple.Create(startIdx, endIdx - startIdx + 1); // incl end
     1174      } else {
     1175        yield return Tuple.Create(startIdx, size - startIdx); // startIdx to end of vector
     1176        yield return Tuple.Create(0, endIdx);                 // start to endIdx of vector
     1177      }
     1178    }
     1179   
     1180    public static DoubleVector RoundTripSubVector(DoubleVector v, int startIdx, int endIdx) {
     1181      var slices = GetVectorSlices(startIdx, endIdx, v.Count).ToList();
     1182      var totalSize = slices.Sum(s => s.Item2);
     1183      var resultVector = DoubleVector.Build.Dense(size: totalSize);
     1184
     1185      var curIdx = 0;
     1186      foreach (var slice in slices) {
     1187        int start = slice.Item1, count = slice.Item2;
     1188        v.CopySubVectorTo(resultVector, sourceIndex: start, targetIndex: curIdx, count: count);
     1189        curIdx += count;
     1190      }
     1191      return resultVector;
     1192    }
     1193
    11891194    private static int LongestStrikeAbove(DoubleVector v, double threshold) {
    11901195      int longestStrike = 0, currentStrike = 0;
Note: See TracChangeset for help on using the changeset viewer.