1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)


4  *


5  * This file is part of HeuristicLab.


6  *


7  * HeuristicLab is free software: you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation, either version 3 of the License, or


10  * (at your option) any later version.


11  *


12  * HeuristicLab is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.


19  */


20  #endregion


21 


22  using System;


23  using System.Collections.Generic;


24  using System.Linq;


25  using HeuristicLab.Common;


26  using HeuristicLab.Core;


27  using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;


28 


29  namespace HeuristicLab.Algorithms.DataAnalysis {


30  [StorableClass]


31  [Item(Name = "CovarianceProduct",


32  Description = "Product covariance function for Gaussian processes.")]


33  public sealed class CovarianceProduct : Item, ICovarianceFunction {


34  [Storable]


35  private ItemList<ICovarianceFunction> factors;


36 


37  [Storable]


38  private int numberOfVariables;


39  public ItemList<ICovarianceFunction> Factors {


40  get { return factors; }


41  }


42 


43  [StorableConstructor]


44  private CovarianceProduct(bool deserializing)


45  : base(deserializing) {


46  }


47 


48  private CovarianceProduct(CovarianceProduct original, Cloner cloner)


49  : base(original, cloner) {


50  this.factors = cloner.Clone(original.factors);


51  this.numberOfVariables = original.numberOfVariables;


52  }


53 


54  public CovarianceProduct()


55  : base() {


56  this.factors = new ItemList<ICovarianceFunction>();


57  }


58 


59  public override IDeepCloneable Clone(Cloner cloner) {


60  return new CovarianceProduct(this, cloner);


61  }


62 


63  public int GetNumberOfParameters(int numberOfVariables) {


64  this.numberOfVariables = numberOfVariables;


65  return factors.Select(f => f.GetNumberOfParameters(numberOfVariables)).Sum();


66  }


67 


68  public void SetParameter(double[] hyp) {


69  if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");


70  int offset = 0;


71  foreach (var t in factors) {


72  var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);


73  t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());


74  offset += numberOfParameters;


75  }


76  }


77 


78  public double GetCovariance(double[,] x, int i, int j) {


79  return factors.Select(f => f.GetCovariance(x, i, j)).Aggregate((a, b) => a * b);


80  }


81 


82  public IEnumerable<double> GetGradient(double[,] x, int i, int j) {


83  var covariances = factors.Select(f => f.GetCovariance(x, i, j)).ToArray();


84  for (int ii = 0; ii < factors.Count; ii++) {


85  foreach (var g in factors[ii].GetGradient(x, i, j)) {


86  double res = g;


87  for (int jj = 0; jj < covariances.Length; jj++)


88  if (ii != jj) res *= covariances[jj];


89  yield return res;


90  }


91  }


92  }


93 


94  public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j) {


95  return factors.Select(f => f.GetCrossCovariance(x, xt, i, j)).Aggregate((a, b) => a * b);


96  }


97  }


98  }

