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


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


34  public sealed class CovarianceLinearArd : ParameterizedNamedItem, ICovarianceFunction {


35  [Storable]


36  private double[] inverseLength;


37  [Storable]


38  private readonly HyperParameter<DoubleArray> inverseLengthParameter;


39  public IValueParameter<DoubleArray> InverseLengthParameter {


40  get { return inverseLengthParameter; }


41  }


42 


43  [StorableConstructor]


44  private CovarianceLinearArd(bool deserializing) : base(deserializing) { }


45  private CovarianceLinearArd(CovarianceLinearArd original, Cloner cloner)


46  : base(original, cloner) {


47  inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);


48  if (original.inverseLength != null) {


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


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


51  }


52 


53  RegisterEvents();


54  }


55  public CovarianceLinearArd()


56  : base() {


57  Name = ItemName;


58  Description = ItemDescription;


59 


60  inverseLengthParameter = new HyperParameter<DoubleArray>("InverseLength",


61  "The inverse length parameter for ARD.");


62  Parameters.Add(inverseLengthParameter);


63  RegisterEvents();


64  }


65 


66  [StorableHook(HookType.AfterDeserialization)]


67  private void AfterDeserialization() {


68  RegisterEvents();


69  }


70 


71  public override IDeepCloneable Clone(Cloner cloner) {


72  return new CovarianceLinearArd(this, cloner);


73  }


74 


75  // caching


76  private void RegisterEvents() {


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


78  }


79 


80 


81  public int GetNumberOfParameters(int numberOfVariables) {


82  if (!inverseLengthParameter.Fixed)


83  return numberOfVariables;


84  else


85  return 0;


86  }


87 


88  public void SetParameter(double[] hyp) {


89  if (!inverseLengthParameter.Fixed && hyp.Length > 0) {


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


91  } else throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceLinearArd", "hyp");


92  }


93 


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


95  return Util.ScalarProd(x, i, j, inverseLength, columnIndices);


96  }


97 


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


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


100 


101  int k = 0;


102  foreach (int columnIndex in columnIndices) {


103  yield return 2.0 * x[i, columnIndex] * x[j, columnIndex] * inverseLength[k] * inverseLength[k];


104  k++;


105  }


106  }


107 


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


109  return Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);


110  }


111  }


112  }

