Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/22/16 13:47:35 (9 years ago)
Author:
pfleck
Message:

#2591 Made the creation of a GaussianProcessModel faster by avoiding additional iterators during calculation of the hyperparameter gradients.
The gradients of the hyperparameters are now calculated in one sweep and returned as IList, instead of returning an iterator (with yield return).
This avoids a large amount of Move-calls of the iterator, especially for covariance functions with a lot of hyperparameters.
Besides, the signature of the CovarianceGradientFunctionDelegate is changed, to return an IList instead of an IEnumerable to avoid unnececary ToList or ToArray calls.

Location:
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceConst.cs

    r13721 r13784  
    2121
    2222using System;
    23 using System.Collections.Generic;
    24 using System.Linq;
    2523using HeuristicLab.Common;
    2624using HeuristicLab.Core;
     
    9189      cov.CrossCovariance = (x, xt, i, j) => scale;
    9290      if (HasFixedScaleParameter) {
    93         cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
     91        cov.CovarianceGradient = (x, i, j) => new double[0];
    9492      } else {
    95         cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, scale, columnIndices);
     93        cov.CovarianceGradient = (x, i, j) => new[] { 2.0 * scale };
    9694      }
    9795      return cov;
    9896    }
    99 
    100     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double scale, int[] columnIndices) {
    101       yield return 2.0 * scale;
    102     }
    10397  }
    10498}
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinear.cs

    r13721 r13784  
    2121
    2222using System;
    23 using System.Linq;
    2423using HeuristicLab.Common;
    2524using HeuristicLab.Core;
     
    5756      cov.Covariance = (x, i, j) => Util.ScalarProd(x, i, j, columnIndices, 1.0);
    5857      cov.CrossCovariance = (x, xt, i, j) => Util.ScalarProd(x, i, xt, j, columnIndices, 1.0);
    59       cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
     58      cov.CovarianceGradient = (x, i, j) => new double[0];
    6059      return cov;
    6160    }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinearArd.cs

    r13721 r13784  
    9090      cov.CrossCovariance = (x, xt, i, j) => Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);
    9191      if (fixedInverseLength)
    92         cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
     92        cov.CovarianceGradient = (x, i, j) => new double[0];
    9393      else
    9494        cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, inverseLength, columnIndices);
     
    9696    }
    9797
    98     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double[] inverseLength, int[] columnIndices) {
     98    private static IList<double> GetGradient(double[,] x, int i, int j, double[] inverseLength, int[] columnIndices) {
    9999      int k = 0;
     100      var g = new List<double>(columnIndices.Length);
    100101      for (int c = 0; c < columnIndices.Length; c++) {
    101102        var columnIndex = columnIndices[c];
    102         yield return -2.0 * x[i, columnIndex] * x[j, columnIndex] * inverseLength[k] * inverseLength[k];
     103        g.Add(-2.0 * x[i, columnIndex] * x[j, columnIndex] * inverseLength[k] * inverseLength[k]);
    103104        k++;
    104105      }
     106      return g;
    105107    }
    106108  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMaternIso.cs

    r13721 r13784  
    155155    }
    156156
    157 
    158     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int d, double scale, double inverseLength, int[] columnIndices,
     157    private static IList<double> GetGradient(double[,] x, int i, int j, int d, double scale, double inverseLength, int[] columnIndices,
    159158      bool fixedInverseLength, bool fixedScale) {
    160159      double dist = i == j
     
    162161                   : Math.Sqrt(Util.SqrDist(x, i, j, columnIndices, Math.Sqrt(d) * inverseLength));
    163162
    164       if (!fixedInverseLength) yield return scale * dm(d, dist);
    165       if (!fixedScale) yield return 2 * scale * m(d, dist);
     163      var g = new List<double>(2);
     164      if (!fixedInverseLength) g.Add(scale * dm(d, dist));
     165      if (!fixedScale) g.Add(2 * scale * m(d, dist));
     166      return g;
    166167    }
    167168  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNeuralNetwork.cs

    r13721 r13784  
    140140
    141141    // order of returned gradients must match the order in GetParameterValues!
    142     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double length, double scale, int[] columnIndices,
     142    private static IList<double> GetGradient(double[,] x, int i, int j, double length, double scale, int[] columnIndices,
    143143      bool fixedLength, bool fixedScale) {
    144       {
    145         double sx = 1.0;
    146         double s1 = 1.0;
    147         double s2 = 1.0;
    148         for (int c = 0; c < columnIndices.Length; c++) {
    149           var col = columnIndices[c];
    150           sx += x[i, col] * x[j, col];
    151           s1 += x[i, col] * x[i, col];
    152           s2 += x[j, col] * x[j, col];
    153         }
    154         var h = (length + s1) * (length + s2);
    155         var f = sx / Math.Sqrt(h);
    156         if (!fixedLength) {
    157           yield return -scale / Math.Sqrt(1.0 - f * f) * ((length * sx * (2.0 * length + s1 + s2)) / Math.Pow(h, 3.0 / 2.0));
    158         }
    159         if (!fixedScale) {
    160           yield return 2.0 * scale * Math.Asin(f);
    161         }
     144      double sx = 1.0;
     145      double s1 = 1.0;
     146      double s2 = 1.0;
     147      for (int c = 0; c < columnIndices.Length; c++) {
     148        var col = columnIndices[c];
     149        sx += x[i, col] * x[j, col];
     150        s1 += x[i, col] * x[i, col];
     151        s2 += x[j, col] * x[j, col];
    162152      }
     153      var h = (length + s1) * (length + s2);
     154      var f = sx / Math.Sqrt(h);
     155
     156      var g = new List<double>(2);
     157      if (!fixedLength) g.Add(-scale / Math.Sqrt(1.0 - f * f) * ((length * sx * (2.0 * length + s1 + s2)) / Math.Pow(h, 3.0 / 2.0)));
     158      if (!fixedScale) g.Add(2.0 * scale * Math.Asin(f));
     159      return g;
    163160    }
    164161  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNoise.cs

    r13721 r13784  
    2121
    2222using System;
    23 using System.Linq;
    2423using HeuristicLab.Common;
    2524using HeuristicLab.Core;
     
    9291      cov.CrossCovariance = (x, xt, i, j) => Util.SqrDist(x, i, xt, j, columnIndices, 1.0) < 1e-9 ? scale : 0.0;
    9392      if (fixedScale)
    94         cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
     93        cov.CovarianceGradient = (x, i, j) => new double[0];
    9594      else
    96         cov.CovarianceGradient = (x, i, j) => Enumerable.Repeat(i == j ? 2.0 * scale : 0.0, 1);
     95        cov.CovarianceGradient = (x, i, j) => new double[1] { i == j ? 2.0 * scale : 0.0 };
    9796      return cov;
    9897    }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePeriodic.cs

    r13721 r13784  
    2222using System;
    2323using System.Collections.Generic;
    24 using System.Linq;
    2524using HeuristicLab.Common;
    2625using HeuristicLab.Core;
     
    117116    }
    118117
    119     public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[]columnIndices) {
     118    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[] columnIndices) {
    120119      double inverseLength, period, scale;
    121120      GetParameterValues(p, out scale, out period, out inverseLength);
     
    145144    }
    146145
    147 
    148     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double period, double inverseLength,
     146    private static IList<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double period, double inverseLength,
    149147      bool fixedInverseLength, bool fixedPeriod, bool fixedScale) {
    150148      double k = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j, columnIndices) / period;
    151149      double gradient = Math.Sin(k) * inverseLength;
    152150      gradient *= gradient;
    153       if (!fixedInverseLength) yield return 4.0 * scale * Math.Exp(-2.0 * gradient) * gradient;
     151      var g = new List<double>(3);
     152      if (!fixedInverseLength)
     153        g.Add(4.0 * scale * Math.Exp(-2.0 * gradient) * gradient);
    154154      if (!fixedPeriod) {
    155155        double r = Math.Sin(k) * inverseLength;
    156         yield return 2.0 * k * scale * Math.Exp(-2 * r * r) * Math.Sin(2 * k) * inverseLength * inverseLength;
     156        g.Add(2.0 * k * scale * Math.Exp(-2 * r * r) * Math.Sin(2 * k) * inverseLength * inverseLength);
    157157      }
    158158      if (!fixedScale)
    159         yield return 2.0 * scale * Math.Exp(-2 * gradient);
    160 
     159        g.Add(2.0 * scale * Math.Exp(-2 * gradient));
     160      return g;
    161161    }
    162162
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePiecewisePolynomial.cs

    r13721 r13784  
    6969      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the piecewise polynomial covariance function."));
    7070
    71       var validValues = new ItemSet<IntValue>(new IntValue[] { 
    72         (IntValue)(new IntValue().AsReadOnly()), 
    73         (IntValue)(new IntValue(1).AsReadOnly()), 
    74         (IntValue)(new IntValue(2).AsReadOnly()), 
     71      var validValues = new ItemSet<IntValue>(new IntValue[] {
     72        (IntValue)(new IntValue().AsReadOnly()),
     73        (IntValue)(new IntValue(1).AsReadOnly()),
     74        (IntValue)(new IntValue(2).AsReadOnly()),
    7575        (IntValue)(new IntValue(3).AsReadOnly()) });
    7676      Parameters.Add(new ConstrainedValueParameter<IntValue>("V", "The v parameter of the piecewise polynomial function (allowed values 0, 1, 2, 3).", validValues, validValues.First()));
     
    159159    }
    160160
    161     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double length, double scale, int v, double exp, Func<double, double> f, Func<double, double> df, int[] columnIndices,
     161    private static IList<double> GetGradient(double[,] x, int i, int j, double length, double scale, int v, double exp, Func<double, double> f, Func<double, double> df, int[] columnIndices,
    162162      bool fixedLength, bool fixedScale) {
    163163      double k = Math.Sqrt(Util.SqrDist(x, i, x, j, columnIndices, 1.0 / length));
    164       if (!fixedLength) yield return scale * Math.Pow(Math.Max(1.0 - k, 0), exp + v - 1) * k * ((exp + v) * f(k) - Math.Max(1 - k, 0) * df(k));
    165       if (!fixedScale) yield return 2.0 * scale * Math.Pow(Math.Max(1 - k, 0), exp + v) * f(k);
     164      var g = new List<double>(2);
     165      if (!fixedLength) g.Add(scale * Math.Pow(Math.Max(1.0 - k, 0), exp + v - 1) * k * ((exp + v) * f(k) - Math.Max(1 - k, 0) * df(k)));
     166      if (!fixedScale) g.Add(2.0 * scale * Math.Pow(Math.Max(1 - k, 0), exp + v) * f(k));
     167      return g;
    166168    }
    167169  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePolynomial.cs

    r13721 r13784  
    121121    }
    122122
    123     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double c, double scale, int degree, int[] columnIndices,
     123    private static IList<double> GetGradient(double[,] x, int i, int j, double c, double scale, int degree, int[] columnIndices,
    124124      bool fixedConst, bool fixedScale) {
    125125      double s = Util.ScalarProd(x, i, j, columnIndices, 1.0);
    126       if (!fixedConst) yield return c * degree * scale * Math.Pow(c + s, degree - 1);
    127       if (!fixedScale) yield return 2 * scale * Math.Pow(c + s, degree);
     126      var g = new List<double>(2);
     127      if (!fixedConst) g.Add(c * degree * scale * Math.Pow(c + s, degree - 1));
     128      if (!fixedScale) g.Add(2 * scale * Math.Pow(c + s, degree));
     129      return g;
    128130    }
    129131  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs

    r13721 r13784  
    2323using System.Collections.Generic;
    2424using System.Linq;
    25 using System.Linq.Expressions;
    2625using HeuristicLab.Common;
    2726using HeuristicLab.Core;
     
    9392    }
    9493
    95     public static IEnumerable<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {
     94    public static IList<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {
    9695      var covariances = factorFunctions.Select(f => f.Covariance(x, i, j)).ToArray();
     96      var gr = new List<double>(factorFunctions.Sum(f => f.CovarianceGradient(x, i, j).Count));
    9797      for (int ii = 0; ii < factorFunctions.Count; ii++) {
    9898        foreach (var g in factorFunctions[ii].CovarianceGradient(x, i, j)) {
     
    100100          for (int jj = 0; jj < covariances.Length; jj++)
    101101            if (ii != jj) res *= covariances[jj];
    102           yield return res;
     102          gr.Add(res);
    103103        }
    104104      }
     105      return gr;
    105106    }
    106107  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticArd.cs

    r13721 r13784  
    144144    }
    145145
    146     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double shape, double[] inverseLength,
     146    private static IList<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double shape, double[] inverseLength,
    147147      bool fixedInverseLength, bool fixedScale, bool fixedShape) {
    148148      double d = i == j
     
    151151      double b = 1 + 0.5 * d / shape;
    152152      int k = 0;
     153      var g = new List<double>(columnIndices.Length + 2);
    153154      if (!fixedInverseLength) {
    154155        foreach (var columnIndex in columnIndices) {
    155           yield return
     156          g.Add(
    156157            scale * Math.Pow(b, -shape - 1) *
    157             Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
     158            Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]));
    158159          k++;
    159160        }
    160161      }
    161       if (!fixedScale) yield return 2 * scale * Math.Pow(b, -shape);
    162       if (!fixedShape) yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     162      if (!fixedScale) g.Add(2 * scale * Math.Pow(b, -shape));
     163      if (!fixedShape) g.Add(scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b)));
     164      return g;
    163165    }
    164166  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticIso.cs

    r13721 r13784  
    139139    }
    140140
    141     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double shape, double inverseLength,
     141    private static IList<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double shape, double inverseLength,
    142142      bool fixedInverseLength, bool fixedScale, bool fixedShape) {
    143143      double d = i == j
     
    146146
    147147      double b = 1 + 0.5 * d / shape;
    148       if (!fixedInverseLength) yield return scale * Math.Pow(b, -shape - 1) * d;
    149       if (!fixedScale) yield return 2 * scale * Math.Pow(b, -shape);
    150       if (!fixedShape) yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
     148      var g = new List<double>(3);
     149      if (!fixedInverseLength) g.Add(scale * Math.Pow(b, -shape - 1) * d);
     150      if (!fixedScale) g.Add(2 * scale * Math.Pow(b, -shape));
     151      if (!fixedShape) g.Add(scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b)));
     152      return g;
    151153    }
    152154  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceScale.cs

    r13721 r13784  
    100100    }
    101101
    102     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, ParameterizedCovarianceFunction cov,
     102    private static IList<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, ParameterizedCovarianceFunction cov,
    103103      bool fixedScale) {
     104      var gr = new List<double>((!fixedScale ? 1 : 0) + cov.CovarianceGradient(x, i, j).Count);
    104105      if (!fixedScale) {
    105         yield return 2 * scale * cov.Covariance(x, i, j);
     106        gr.Add(2 * scale * cov.Covariance(x, i, j));
    106107      }
    107108      foreach (var g in cov.CovarianceGradient(x, i, j))
    108         yield return scale * g;
     109        gr.Add(scale * g);
     110      return gr;
    109111    }
    110112  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSpectralMixture.cs

    r13721 r13784  
    181181
    182182    // order of returned gradients must match the order in GetParameterValues!
    183     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int maxQ, double[] weight, double[] frequency, double[] lengthScale, int[] columnIndices,
     183    private static IList<double> GetGradient(double[,] x, int i, int j, int maxQ, double[] weight, double[] frequency, double[] lengthScale, int[] columnIndices,
    184184      bool fixedWeight, bool fixedFrequency, bool fixedLengthScale) {
    185185      double[] tau = Util.GetRow(x, i, columnIndices).Zip(Util.GetRow(x, j, columnIndices), (xi, xj) => xi - xj).ToArray();
    186186      int numberOfVariables = lengthScale.Length / maxQ;
    187187
     188      var g = new List<double>((!fixedWeight ? maxQ : 0) + (!fixedFrequency ? maxQ * columnIndices.Length : 0) + (!fixedLengthScale ? maxQ * columnIndices.Length : 0));
    188189      if (!fixedWeight) {
    189190        // weight
     
    198199            idx++;
    199200          }
    200           yield return k;
     201          g.Add(k);
    201202        }
    202203      }
     
    213214                       Math.Sin(2 * Math.PI * tau[idx] * frequency[q * numberOfVariables + c]);
    214215            idx++;
    215             yield return weight[q] * k;
     216            g.Add(weight[q] * k);
    216217          }
    217218        }
     
    229230                       f2(tau[idx], frequency[q * numberOfVariables + c]);
    230231            idx++;
    231             yield return weight[q] * k;
     232            g.Add(weight[q] * k);
    232233          }
    233234        }
    234235      }
     236
     237      return g;
    235238    }
    236239  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialArd.cs

    r13721 r13784  
    122122
    123123    // order of returned gradients must match the order in GetParameterValues!
    124     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double[] inverseLength,
     124    private static IList<double> GetGradient(double[,] x, int i, int j, int[] columnIndices, double scale, double[] inverseLength,
    125125      bool fixedInverseLength, bool fixedScale) {
    126126      double d = i == j
     
    129129
    130130      int k = 0;
     131      var g = new List<double>((!fixedInverseLength ? columnIndices.Length : 0) + (!fixedScale ? 1 : 0));
    131132      if (!fixedInverseLength) {
    132133        for (int c = 0; c < columnIndices.Length; c++) {
    133134          var columnIndex = columnIndices[c];
    134135          double sqrDist = Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
    135           yield return scale * Math.Exp(-d / 2.0) * sqrDist;
     136          g.Add(scale * Math.Exp(-d / 2.0) * sqrDist);
    136137          k++;
    137138        }
    138139      }
    139       if (!fixedScale) yield return 2.0 * scale * Math.Exp(-d / 2.0);
     140      if (!fixedScale) g.Add(2.0 * scale * Math.Exp(-d / 2.0));
     141      return g;
    140142    }
    141143  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialIso.cs

    r13721 r13784  
    126126
    127127    // order of returned gradients must match the order in GetParameterValues!
    128     private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double sf2, double inverseLength, int[] columnIndices,
     128    private static IList<double> GetGradient(double[,] x, int i, int j, double sf2, double inverseLength, int[] columnIndices,
    129129      bool fixedInverseLength, bool fixedScale) {
    130130      double d = i == j
     
    132132                   : Util.SqrDist(x, i, j, columnIndices, inverseLength);
    133133      double g = Math.Exp(-d / 2.0);
    134       if (!fixedInverseLength) yield return sf2 * g * d;
    135       if (!fixedScale) yield return 2.0 * sf2 * g;
     134      var gr = new List<double>(2);
     135      if (!fixedInverseLength) gr.Add(sf2 * g * d);
     136      if (!fixedScale) gr.Add(2.0 * sf2 * g);
     137      return gr;
    136138    }
    137139  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs

    r13721 r13784  
    8787      sum.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Sum();
    8888      sum.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Sum();
    89       sum.CovarianceGradient = (x, i, j) => functions.Select(e => e.CovarianceGradient(x, i, j)).Aggregate(Enumerable.Concat);
     89      sum.CovarianceGradient = (x, i, j) => {
     90        var g = new List<double>(functions.Sum(e => e.CovarianceGradient(x, i, j).Count));
     91        foreach (var e in functions)
     92          g.AddRange(e.CovarianceGradient(x, i, j));
     93        return g;
     94      };
    9095      return sum;
    9196    }
Note: See TracChangeset for help on using the changeset viewer.