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 = "CovarianceRationalQuadraticArd",


33  Description = "Rational quadratic covariance function with automatic relevance determination for Gaussian processes.")]


34  public sealed class CovarianceRationalQuadraticArd : ParameterizedNamedItem, ICovarianceFunction {


35  [Storable]


36  private double sf2;


37  [Storable]


38  private readonly HyperParameter<DoubleValue> scaleParameter;


39  public IValueParameter<DoubleValue> ScaleParameter {


40  get { return scaleParameter; }


41  }


42 


43  [Storable]


44  private double[] inverseLength;


45  [Storable]


46  private readonly HyperParameter<DoubleArray> inverseLengthParameter;


47  public IValueParameter<DoubleArray> InverseLengthParameter {


48  get { return inverseLengthParameter; }


49  }


50 


51  [Storable]


52  private double shape;


53  [Storable]


54  private readonly HyperParameter<DoubleValue> shapeParameter;


55  public IValueParameter<DoubleValue> ShapeParameter {


56  get { return shapeParameter; }


57  }


58 


59  [StorableConstructor]


60  private CovarianceRationalQuadraticArd(bool deserializing)


61  : base(deserializing) {


62  }


63 


64  private CovarianceRationalQuadraticArd(CovarianceRationalQuadraticArd original, Cloner cloner)


65  : base(original, cloner) {


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


67  this.sf2 = original.sf2;


68 


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


70  if (original.inverseLength != null) {


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


72  Array.Copy(original.inverseLength, inverseLength, inverseLength.Length);


73  }


74 


75  this.shapeParameter = cloner.Clone(original.shapeParameter);


76  this.shape = original.shape;


77 


78  RegisterEvents();


79  }


80 


81  public CovarianceRationalQuadraticArd()


82  : base() {


83  Name = ItemName;


84  Description = ItemDescription;


85 


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


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


88  this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the rational quadratic covariance function with ARD.");


89 


90  Parameters.Add(scaleParameter);


91  Parameters.Add(inverseLengthParameter);


92  Parameters.Add(shapeParameter);


93 


94  RegisterEvents();


95  }


96 


97  public override IDeepCloneable Clone(Cloner cloner) {


98  return new CovarianceRationalQuadraticArd(this, cloner);


99  }


100 


101  [StorableHook(HookType.AfterDeserialization)]


102  private void AfterDeserialization() {


103  RegisterEvents();


104  }


105 


106  private void RegisterEvents() {


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


108  Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });


109  Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });


110  }


111 


112  public int GetNumberOfParameters(int numberOfVariables) {


113  return


114  (scaleParameter.Fixed ? 0 : 1) +


115  (shapeParameter.Fixed ? 0 : 1) +


116  (inverseLengthParameter.Fixed ? 0 : numberOfVariables);


117  }


118 


119  public void SetParameter(double[] hyp) {


120  int i = 0;


121  if (!scaleParameter.Fixed) {


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


123  i++;


124  }


125  if (!shapeParameter.Fixed) {


126  shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));


127  i++;


128  }


129  if (!inverseLengthParameter.Fixed) {


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


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


132  }


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


134  }


135 


136 


137  public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {


138  double d = i == j


139  ? 0.0


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


141  return sf2 * Math.Pow(1 + 0.5 * d / shape, shape);


142  }


143 


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


145  if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));


146  double d = i == j


147  ? 0.0


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


149  double b = 1 + 0.5 * d / shape;


150  int k = 0;


151  foreach (var columnIndex in columnIndices) {


152  yield return sf2 * Math.Pow(b, shape  1) * Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);


153  k++;


154  }


155  yield return 2 * sf2 * Math.Pow(b, shape);


156  yield return sf2 * Math.Pow(b, shape) * (0.5 * d / b  shape * Math.Log(b));


157  }


158 


159  public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {


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


161  return sf2 * Math.Pow(1 + 0.5 * d / shape, shape);


162  }


163  }


164  }

