1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022015 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[] p) {


69  int offset = 0;


70  foreach (var f in factors) {


71  var numberOfParameters = f.GetNumberOfParameters(numberOfVariables);


72  f.SetParameter(p.Skip(offset).Take(numberOfParameters).ToArray());


73  offset += numberOfParameters;


74  }


75  }


76 


77  public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[] columnIndices) {


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


79  var functions = new List<ParameterizedCovarianceFunction>();


80  foreach (var f in factors) {


81  int numberOfParameters = f.GetNumberOfParameters(numberOfVariables);


82  functions.Add(f.GetParameterizedCovarianceFunction(p.Take(numberOfParameters).ToArray(), columnIndices));


83  p = p.Skip(numberOfParameters).ToArray();


84  }


85 


86 


87  var product = new ParameterizedCovarianceFunction();


88  product.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Aggregate((a, b) => a * b);


89  product.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Aggregate((a, b) => a * b);


90  product.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, functions);


91  return product;


92  }


93 


94  public static IList<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {


95  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));


97  for (int ii = 0; ii < factorFunctions.Count; ii++) {


98  foreach (var g in factorFunctions[ii].CovarianceGradient(x, i, j)) {


99  double res = g;


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


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


102  gr.Add(res);


103  }


104  }


105  return gr;


106  }


107  }


108  }

