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.Data;


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


29 


30  namespace HeuristicLab.Algorithms.DataAnalysis {


31  [StorableClass]


32  [Item(Name = "CovarianceSEard", Description = "Squared exponential covariance function with automatic relevance determination for Gaussian processes.")]


33  public sealed class CovarianceSEard : ParameterizedNamedItem, ICovarianceFunction {


34  [Storable]


35  private double sf2;


36  [Storable]


37  private readonly HyperParameter<DoubleValue> scaleParameter;


38  public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }


39 


40  [Storable]


41  private double[] inverseLength;


42  [Storable]


43  private readonly HyperParameter<DoubleArray> inverseLengthParameter;


44  public IValueParameter<DoubleArray> InverseLengthParameter { get { return inverseLengthParameter; } }


45 


46  [StorableConstructor]


47  private CovarianceSEard(bool deserializing) : base(deserializing) { }


48  private CovarianceSEard(CovarianceSEard original, Cloner cloner)


49  : base(original, cloner) {


50  this.sf2 = original.sf2;


51  this.scaleParameter = cloner.Clone(original.scaleParameter);


52 


53  if (original.inverseLength != null) {


54  this.inverseLength = new double[original.inverseLength.Length];


55  Array.Copy(original.inverseLength, this.inverseLength, this.inverseLength.Length);


56  }


57  this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);


58 


59  RegisterEvents();


60  }


61  public CovarianceSEard()


62  : base() {


63  Name = ItemName;


64  Description = ItemDescription;


65 


66  this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the squared exponential covariance function with ARD.");


67  this.inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination.");


68 


69  Parameters.Add(scaleParameter);


70  Parameters.Add(inverseLengthParameter);


71 


72  RegisterEvents();


73  }


74 


75  public override IDeepCloneable Clone(Cloner cloner) {


76  return new CovarianceSEard(this, cloner);


77  }


78 


79  [StorableHook(HookType.AfterDeserialization)]


80  private void AfterDeserialization() {


81  RegisterEvents();


82  }


83 


84  private void RegisterEvents() {


85  Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });


86  Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => {


87  inverseLength =


88  inverseLengthParameter.Value.ToArray();


89  });


90  }


91 


92  public int GetNumberOfParameters(int numberOfVariables) {


93  return


94  (scaleParameter.Fixed ? 0 : 1) +


95  (inverseLengthParameter.Fixed ? 0 : numberOfVariables);


96  }


97 


98 


99  public void SetParameter(double[] hyp) {


100  int i = 0;


101  if (!scaleParameter.Fixed) {


102  scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));


103  i++;


104  }


105  if (!inverseLengthParameter.Fixed) {


106  inverseLengthParameter.SetValue(new DoubleArray(hyp.Skip(i).Select(e => 1.0 / Math.Exp(e)).ToArray()));


107  i += hyp.Skip(i).Count();


108  }


109  if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancSEard", "hyp");


110  }


111 


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


113  double d = i == j


114  ? 0.0


115  : Util.SqrDist(x, i, j, inverseLength);


116  return sf2 * Math.Exp(d / 2.0);


117  }


118 


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


120  double d = i == j


121  ? 0.0


122  : Util.SqrDist(x, i, j, inverseLength);


123 


124  for (int ii = 0; ii < inverseLength.Length; ii++) {


125  double sqrDist = Util.SqrDist(x[i, ii] * inverseLength[ii], x[j, ii] * inverseLength[ii]);


126  yield return sf2 * Math.Exp(d / 2.0) * sqrDist;


127  }


128  yield return 2.0 * sf2 * Math.Exp(d / 2.0);


129  }


130 


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


132  double d = Util.SqrDist(x, i, xt, j, inverseLength);


133  return sf2 * Math.Exp(d / 2.0);


134  }


135  }


136  }

