1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022018 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.Collections.Generic;


23  using System.Linq;


24  using HeuristicLab.Common;


25  using HeuristicLab.Core;


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


27 


28  namespace HeuristicLab.Algorithms.DataAnalysis {


29  [StorableClass]


30  [Item(Name = "MeanProduct", Description = "Product of mean functions for Gaussian processes.")]


31  public sealed class MeanProduct : Item, IMeanFunction {


32  [Storable]


33  private ItemList<IMeanFunction> factors;


34 


35  [Storable]


36  private int numberOfVariables;


37 


38  public ItemList<IMeanFunction> Factors {


39  get { return factors; }


40  }


41 


42  [StorableConstructor]


43  private MeanProduct(bool deserializing)


44  : base(deserializing) {


45  }


46 


47  private MeanProduct(MeanProduct original, Cloner cloner)


48  : base(original, cloner) {


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


50  this.numberOfVariables = original.numberOfVariables;


51  }


52 


53  public MeanProduct() {


54  this.factors = new ItemList<IMeanFunction>();


55  }


56  public override IDeepCloneable Clone(Cloner cloner) {


57  return new MeanProduct(this, cloner);


58  }


59 


60  public int GetNumberOfParameters(int numberOfVariables) {


61  this.numberOfVariables = numberOfVariables;


62  return factors.Select(t => t.GetNumberOfParameters(numberOfVariables)).Sum();


63  }


64 


65  public void SetParameter(double[] p) {


66  int offset = 0;


67  foreach (var t in factors) {


68  var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);


69  t.SetParameter(p.Skip(offset).Take(numberOfParameters).ToArray());


70  offset += numberOfParameters;


71  }


72  }


73 


74 


75  public ParameterizedMeanFunction GetParameterizedMeanFunction(double[] p, int[] columnIndices) {


76  var factorMf = new List<ParameterizedMeanFunction>();


77  int totalNumberOfParameters = GetNumberOfParameters(numberOfVariables);


78  int[] factorIndexMap = new int[totalNumberOfParameters]; // maps kth hyperparameter to the correct meanterm


79  int[] hyperParameterIndexMap = new int[totalNumberOfParameters]; // maps kth hyperparameter to the lth hyperparameter of the correct meanterm


80  int c = 0;


81  // get the parameterized mean function for each term


82  for (int factorIndex = 0; factorIndex < factors.Count; factorIndex++) {


83  var numberOfParameters = factors[factorIndex].GetNumberOfParameters(numberOfVariables);


84  factorMf.Add(factors[factorIndex].GetParameterizedMeanFunction(p.Take(numberOfParameters).ToArray(), columnIndices));


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


86 


87  for (int hyperParameterIndex = 0; hyperParameterIndex < numberOfParameters; hyperParameterIndex++) {


88  factorIndexMap[c] = factorIndex;


89  hyperParameterIndexMap[c] = hyperParameterIndex;


90  c++;


91  }


92  }


93 


94  var mf = new ParameterizedMeanFunction();


95  mf.Mean = (x, i) => factorMf.Select(t => t.Mean(x, i)).Aggregate((a, b) => a * b);


96  mf.Gradient = (x, i, k) => {


97  double result = 1.0;


98  int hyperParameterFactorIndex = factorIndexMap[k];


99  for (int factorIndex = 0; factorIndex < factors.Count; factorIndex++) {


100  if (factorIndex == hyperParameterFactorIndex) {


101  // multiply gradient


102  result *= factorMf[factorIndex].Gradient(x, i, hyperParameterIndexMap[k]);


103  } else {


104  // multiply mean


105  result *= factorMf[factorIndex].Mean(x, i);


106  }


107  }


108  return result;


109  };


110  return mf;


111  }


112  }


113  }

