Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/01/12 19:02:47 (12 years ago)
Author:
gkronber
Message:

#1902: removed class HyperParameter and changed implementations of covariance and mean functions to remove the parameter value caching and event handlers for parameter caching. Instead it is now possible to create the actual covariance and mean functions as Func from templates and specified parameter values. The instances of mean and covariance functions configured in the GUI are actually templates where the structure and fixed parameters can be specified.

Location:
trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceConst.cs

    r8929 r8982  
    2525using HeuristicLab.Core;
    2626using HeuristicLab.Data;
     27using HeuristicLab.Parameters;
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2829
     
    3233    Description = "Constant covariance function for Gaussian processes.")]
    3334  public sealed class CovarianceConst : ParameterizedNamedItem, ICovarianceFunction {
    34 
    35     [Storable]
    36     private double scale;
    37     [Storable]
    38     private readonly HyperParameter<DoubleValue> scaleParameter;
    3935    public IValueParameter<DoubleValue> ScaleParameter {
    40       get { return scaleParameter; }
     36      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    4137    }
    4238
     
    4844    private CovarianceConst(CovarianceConst original, Cloner cloner)
    4945      : base(original, cloner) {
    50       this.scaleParameter = cloner.Clone(original.scaleParameter);
    51       this.scale = original.scale;
    52 
    53       RegisterEvents();
    5446    }
    5547
     
    5951      Description = ItemDescription;
    6052
    61       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the constant covariance function.");
    62       Parameters.Add(scaleParameter);
    63       RegisterEvents();
     53      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of the constant covariance function."));
    6454    }
    65 
    66     [StorableHook(HookType.AfterDeserialization)]
    67     private void AfterDeserialization() {
    68       RegisterEvents();
    69     }
    70 
    71     // caching
    72     private void RegisterEvents() {
    73       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
    74     }
    75 
    7655
    7756    public override IDeepCloneable Clone(Cloner cloner) {
     
    8059
    8160    public int GetNumberOfParameters(int numberOfVariables) {
    82       return scaleParameter.Fixed ? 0 : 1;
     61      return ScaleParameter.Value != null ? 0 : 1;
    8362    }
    8463
    85     public void SetParameter(double[] hyp) {
    86       if (!scaleParameter.Fixed && hyp.Length == 1) {
    87         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
    88       } else {
    89         throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceConst", "hyp");
    90       }
     64    public void SetParameter(double[] p) {
     65      double scale;
     66      GetParameterValues(p, out scale);
     67      ScaleParameter.Value = new DoubleValue(scale);
    9168    }
    9269
    93     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    94       return scale;
     70    private void GetParameterValues(double[] p, out double scale) {
     71      int c = 0;
     72      // gather parameter values
     73      if (ScaleParameter.Value != null) {
     74        scale = ScaleParameter.Value.Value;
     75      } else {
     76        scale = Math.Exp(2 * p[c]);
     77        c++;
     78      }
     79      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceConst", "p");
    9580    }
    9681
    97     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    98       yield return 2.0 * scale;
     82    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     83      double scale;
     84      GetParameterValues(p, out scale);
     85      // create functions
     86      var cov = new ParameterizedCovarianceFunction();
     87      cov.Covariance = (x, i, j) => scale;
     88      cov.CrossCovariance = (x, xt, i, j) => scale;
     89      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, scale, columnIndices);
     90      return cov;
    9991    }
    10092
    101     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    102       return scale;
     93    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double scale, IEnumerable<int> columnIndices) {
     94      yield return 2.0 * scale;
    10395    }
    10496  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinear.cs

    r8931 r8982  
    4848    }
    4949
    50     public void SetParameter(double[] hyp) {
    51       if (hyp.Length > 0) throw new ArgumentException("No hyperparameters are allowed for the linear covariance function.");
     50    public void SetParameter(double[] p) {
     51      if (p.Length > 0) throw new ArgumentException("No parameters are allowed for the linear covariance function.");
    5252    }
    5353
    54     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    55       return Util.ScalarProd(x, i, j, 1, columnIndices);
    56     }
    57 
    58     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    59       yield break;
    60     }
    61 
    62     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    63       return Util.ScalarProd(x, i, xt, j, 1.0 , columnIndices);
     54    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     55      if (p.Length > 0) throw new ArgumentException("No parameters are allowed for the linear covariance function.");
     56      // create functions
     57      var cov = new ParameterizedCovarianceFunction();
     58      cov.Covariance = (x, i, j) => Util.ScalarProd(x, i, j, 1, columnIndices);
     59      cov.CrossCovariance = (x, xt, i, j) =>  Util.ScalarProd(x, i, xt, j, 1.0 , columnIndices);
     60      cov.CovarianceGradient = (x, i, j) => Enumerable.Empty<double>();
     61      return cov;
    6462    }
    6563  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceLinearArd.cs

    r8933 r8982  
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
     
    3334    Description = "Linear covariance function with automatic relevance determination for Gaussian processes.")]
    3435  public sealed class CovarianceLinearArd : ParameterizedNamedItem, ICovarianceFunction {
    35     [Storable]
    36     private double[] inverseLength;
    37     [Storable]
    38     private readonly HyperParameter<DoubleArray> inverseLengthParameter;
    3936    public IValueParameter<DoubleArray> InverseLengthParameter {
    40       get { return inverseLengthParameter; }
     37      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
    4138    }
    4239
     
    4542    private CovarianceLinearArd(CovarianceLinearArd original, Cloner cloner)
    4643      : 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();
    5444    }
    5545    public CovarianceLinearArd()
     
    5848      Description = ItemDescription;
    5949
    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();
     50      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength",
     51                                                             "The inverse length parameter for ARD."));
    6952    }
    7053
     
    7356    }
    7457
    75     // caching
    76     private void RegisterEvents() {
    77       Util.AttachArrayChangeHandler<DoubleArray, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.ToArray(); });
    78     }
    79 
    80 
    8158    public int GetNumberOfParameters(int numberOfVariables) {
    82       if (!inverseLengthParameter.Fixed)
     59      if (InverseLengthParameter.Value == null)
    8360        return numberOfVariables;
    8461      else
     
    8663    }
    8764
    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");
     65    public void SetParameter(double[] p) {
     66      double[] inverseLength;
     67      GetParameterValues(p, out inverseLength);
     68      InverseLengthParameter.Value = new DoubleArray(inverseLength);
    9269    }
    9370
    94     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    95       return Util.ScalarProd(x, i, j, inverseLength, columnIndices);
     71    private void GetParameterValues(double[] p, out double[] inverseLength) {
     72      // gather parameter values
     73      if (InverseLengthParameter.Value != null) {
     74        inverseLength = InverseLengthParameter.Value.ToArray();
     75      } else {
     76        inverseLength = p.Select(e => 1.0 / Math.Exp(e)).ToArray();
     77      }
    9678    }
    9779
    98     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     80    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     81      double[] inverseLength;
     82      GetParameterValues(p, out inverseLength);
     83      // create functions
     84      var cov = new ParameterizedCovarianceFunction();
     85      cov.Covariance = (x, i, j) => Util.ScalarProd(x, i, j, inverseLength, columnIndices);
     86      cov.CrossCovariance = (x, xt, i, j) => Util.ScalarProd(x, i, xt, j, inverseLength, columnIndices);
     87      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, inverseLength, columnIndices);
     88      return cov;
     89    }
     90
     91    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double[] inverseLength, IEnumerable<int> columnIndices) {
    9992      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
    10093
     
    10598      }
    10699    }
    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     }
    111100  }
    112101}
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMask.cs

    r8933 r8982  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using System.Linq.Expressions;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    3435    Description = "Masking covariance function for dimension selection can be used to apply a covariance function only on certain input dimensions.")]
    3536  public sealed class CovarianceMask : ParameterizedNamedItem, ICovarianceFunction {
    36     [Storable]
    37     private int[] selectedDimensions;
    38     [Storable]
    39     private readonly ValueParameter<IntArray> selectedDimensionsParameter;
    4037    public IValueParameter<IntArray> SelectedDimensionsParameter {
    41       get { return selectedDimensionsParameter; }
     38      get { return (IValueParameter<IntArray>)Parameters["SelectedDimensions"]; }
    4239    }
    43 
    44     [Storable]
    45     private ICovarianceFunction cov;
    46     [Storable]
    47     private readonly ValueParameter<ICovarianceFunction> covParameter;
    4840    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
    49       get { return covParameter; }
     41      get { return (IValueParameter<ICovarianceFunction>)Parameters["CovarianceFunction"]; }
    5042    }
    5143
     
    5749    private CovarianceMask(CovarianceMask original, Cloner cloner)
    5850      : base(original, cloner) {
    59       this.selectedDimensionsParameter = cloner.Clone(original.selectedDimensionsParameter);
    60       if (original.selectedDimensions != null) {
    61         this.selectedDimensions = (int[])original.selectedDimensions.Clone();
    62       }
    63 
    64       this.covParameter = cloner.Clone(original.covParameter);
    65       this.cov = cloner.Clone(original.cov);
    66       RegisterEvents();
    6751    }
    6852
     
    7256      Description = ItemDescription;
    7357
    74       this.selectedDimensionsParameter = new ValueParameter<IntArray>("SelectedDimensions", "The dimensions on which the specified covariance function should be applied to.");
    75       this.covParameter = new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso());
    76       cov = covParameter.Value;
    77 
    78       Parameters.Add(selectedDimensionsParameter);
    79       Parameters.Add(covParameter);
    80 
    81       RegisterEvents();
     58      Parameters.Add(new OptionalValueParameter<IntArray>("SelectedDimensions", "The dimensions on which the specified covariance function should be applied to."));
     59      Parameters.Add(new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso()));
    8260    }
    8361
     
    8664    }
    8765
    88     [StorableHook(HookType.AfterDeserialization)]
    89     private void AfterDeserialization() {
    90       RegisterEvents();
     66    public int GetNumberOfParameters(int numberOfVariables) {
     67      if (SelectedDimensionsParameter.Value == null) return CovarianceFunctionParameter.Value.GetNumberOfParameters(numberOfVariables);
     68      else return CovarianceFunctionParameter.Value.GetNumberOfParameters(SelectedDimensionsParameter.Value.Length);
    9169    }
    9270
    93     private void RegisterEvents() {
    94       Util.AttachArrayChangeHandler<IntArray, int>(selectedDimensionsParameter, () => {
    95         selectedDimensions = selectedDimensionsParameter.Value
    96           .OrderBy(x => x)
    97           .Distinct()
    98           .ToArray();
    99         if (selectedDimensions.Length == 0) selectedDimensions = null;
    100       });
    101       covParameter.ValueChanged += (sender, args) => { cov = covParameter.Value; };
     71    public void SetParameter(double[] p) {
     72      CovarianceFunctionParameter.Value.SetParameter(p);
    10273    }
    10374
    104     public int GetNumberOfParameters(int numberOfVariables) {
    105       if (selectedDimensions == null) return cov.GetNumberOfParameters(numberOfVariables);
    106       else return cov.GetNumberOfParameters(selectedDimensions.Length);
    107     }
     75    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     76      if (columnIndices != null)
     77        throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
     78      var cov = CovarianceFunctionParameter.Value;
     79      var selectedDimensions = SelectedDimensionsParameter.Value;
    10880
    109     public void SetParameter(double[] hyp) {
    110       cov.SetParameter(hyp);
    111     }
    112 
    113     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    114       // cov mask overwrites the previously selected columnIndices
    115       // -> stacking of CovarianceMask is not supported
    116       if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
    117         throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
    118 
    119       return cov.GetCovariance(x, i, j, selectedDimensions);
    120     }
    121 
    122     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    123       if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
    124         throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
    125 
    126       return cov.GetGradient(x, i, j, selectedDimensions);
    127     }
    128 
    129     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    130       if (columnIndices != null && columnIndices.Count() != x.GetLength(1))
    131         throw new InvalidOperationException("Stacking of masking covariance functions is not supported.");
    132 
    133       return cov.GetCrossCovariance(x, xt, i, j, selectedDimensions);
     81      return cov.GetParameterizedCovarianceFunction(p, selectedDimensions);
    13482    }
    13583  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceMaternIso.cs

    r8929 r8982  
    3434    Description = "Matern covariance function for Gaussian processes.")]
    3535  public sealed class CovarianceMaternIso : ParameterizedNamedItem, ICovarianceFunction {
    36     [Storable]
    37     private double inverseLength;
    38     [Storable]
    39     private readonly HyperParameter<DoubleValue> inverseLengthParameter;
    4036    public IValueParameter<DoubleValue> InverseLengthParameter {
    41       get { return inverseLengthParameter; }
     37      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
    4238    }
    4339
    44     [Storable]
    45     private double sf2;
    46     [Storable]
    47     private readonly HyperParameter<DoubleValue> scaleParameter;
    4840    public IValueParameter<DoubleValue> ScaleParameter {
    49       get { return scaleParameter; }
     41      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    5042    }
    5143
    52     [Storable]
    53     private int d;
    54     [Storable]
    55     private readonly ConstrainedValueParameter<IntValue> dParameter;
    5644    public IConstrainedValueParameter<IntValue> DParameter {
    57       get { return dParameter; }
     45      get { return (IConstrainedValueParameter<IntValue>)Parameters["D"]; }
    5846    }
    5947
     
    6654    private CovarianceMaternIso(CovarianceMaternIso original, Cloner cloner)
    6755      : base(original, cloner) {
    68       this.scaleParameter = cloner.Clone(original.scaleParameter);
    69       this.sf2 = original.sf2;
    70       this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
    71       this.inverseLength = original.inverseLength;
    72       this.dParameter = cloner.Clone(original.dParameter);
    73       this.d = original.d;
    74       RegisterEvents();
    7556    }
    7657
     
    8061      Description = ItemDescription;
    8162
    82       inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric Matern covariance function.");
    83       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric Matern covariance function.");
     63      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric Matern covariance function."));
     64      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the isometric Matern covariance function."));
    8465      var validDValues = new ItemSet<IntValue>();
    8566      validDValues.Add((IntValue)new IntValue(1).AsReadOnly());
    8667      validDValues.Add((IntValue)new IntValue(3).AsReadOnly());
    8768      validDValues.Add((IntValue)new IntValue(5).AsReadOnly());
    88       dParameter = new ConstrainedValueParameter<IntValue>("D", "The d parameter (allowed values: 1, 3, or 5) of the isometric Matern covariance function.", validDValues, validDValues.First());
    89       d = dParameter.Value.Value;
    90 
    91       Parameters.Add(inverseLengthParameter);
    92       Parameters.Add(scaleParameter);
    93       Parameters.Add(dParameter);
    94 
    95       RegisterEvents();
    96     }
    97 
    98     [StorableHook(HookType.AfterDeserialization)]
    99     private void AfterDeserialization() {
    100       RegisterEvents();
     69      Parameters.Add(new ConstrainedValueParameter<IntValue>("D", "The d parameter (allowed values: 1, 3, or 5) of the isometric Matern covariance function.", validDValues, validDValues.First()));
    10170    }
    10271
     
    10574    }
    10675
    107     // caching
    108     private void RegisterEvents() {
    109       Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
    110       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
    111       Util.AttachValueChangeHandler<IntValue, int>(dParameter, () => { d = dParameter.Value.Value; });
     76    public int GetNumberOfParameters(int numberOfVariables) {
     77      return
     78        (InverseLengthParameter.Value != null ? 0 : 1) +
     79        (ScaleParameter.Value != null ? 0 : 1);
    11280    }
    11381
    114     public int GetNumberOfParameters(int numberOfVariables) {
    115       return
    116         (inverseLengthParameter.Fixed ? 0 : 1) +
    117         (scaleParameter.Fixed ? 0 : 1);
     82    public void SetParameter(double[] p) {
     83      double inverseLength, scale;
     84      GetParameterValues(p, out scale, out inverseLength);
     85      InverseLengthParameter.Value = new DoubleValue(inverseLength);
     86      ScaleParameter.Value = new DoubleValue(scale);
    11887    }
    11988
    120     public void SetParameter(double[] hyp) {
    121       int i = 0;
    122       if (!inverseLengthParameter.Fixed) {
    123         inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
    124         i++;
     89    private void GetParameterValues(double[] p, out double scale, out double inverseLength) {
     90      // gather parameter values
     91      int c = 0;
     92      if (InverseLengthParameter.Value != null) {
     93        inverseLength = InverseLengthParameter.Value.Value;
     94      } else {
     95        inverseLength = 1.0 / Math.Exp(p[c]);
     96        c++;
    12597      }
    126       if (!scaleParameter.Fixed) {
    127         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
    128         i++;
     98
     99      if (ScaleParameter.Value != null) {
     100        scale = ScaleParameter.Value.Value;
     101      } else {
     102        scale = Math.Exp(2 * p[c]);
     103        c++;
    129104      }
    130       if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceMaternIso", "hyp");
     105      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceMaternIso", "p");
    131106    }
    132107
     108    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     109      double inverseLength, scale;
     110      int d = DParameter.Value.Value;
     111      GetParameterValues(p, out scale, out inverseLength);
     112      // create functions
     113      var cov = new ParameterizedCovarianceFunction();
     114      cov.Covariance = (x, i, j) => {
     115        double dist = i == j
     116                       ? 0.0
     117                       : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
     118        return scale * m(d, dist);
     119      };
     120      cov.CrossCovariance = (x, xt, i, j) => {
     121        double dist = Math.Sqrt(Util.SqrDist(x, i, xt, j, Math.Sqrt(d) * inverseLength, columnIndices));
     122        return scale * m(d, dist);
     123      };
     124      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, d, scale, inverseLength, columnIndices);
     125      return cov;
     126    }
    133127
    134     private double m(double t) {
     128    private static double m(int d, double t) {
    135129      double f;
    136130      switch (d) {
     
    143137    }
    144138
    145     private double dm(double t) {
     139    private static double dm(int d, double t) {
    146140      double df;
    147141      switch (d) {
     
    154148    }
    155149
    156     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    157       double dist = i == j
    158                    ? 0.0
    159                    : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
    160       return sf2 * m(dist);
    161     }
    162150
    163     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     151    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, int d, double scale, double inverseLength, IEnumerable<int> columnIndices) {
    164152      double dist = i == j
    165153                   ? 0.0
    166154                   : Math.Sqrt(Util.SqrDist(x, i, j, Math.Sqrt(d) * inverseLength, columnIndices));
    167155
    168       yield return sf2 * dm(dist);
    169       yield return 2 * sf2 * m(dist);
    170     }
    171 
    172     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    173       double dist = Math.Sqrt(Util.SqrDist(x, i, xt, j, Math.Sqrt(d) * inverseLength, columnIndices));
    174       return sf2 * m(dist);
     156      yield return scale * dm(d, dist);
     157      yield return 2 * scale * m(d, dist);
    175158    }
    176159  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceNoise.cs

    r8929 r8982  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Linq;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    2627using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2729using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2830
     
    3234    Description = "Noise covariance function for Gaussian processes.")]
    3335  public sealed class CovarianceNoise : ParameterizedNamedItem, ICovarianceFunction {
    34 
    35 
    36     [Storable]
    37     private double sf2;
    38     [Storable]
    39     private readonly HyperParameter<DoubleValue> scaleParameter;
    4036    public IValueParameter<DoubleValue> ScaleParameter {
    41       get { return scaleParameter; }
     37      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    4238    }
    4339
     
    4945    private CovarianceNoise(CovarianceNoise original, Cloner cloner)
    5046      : base(original, cloner) {
    51       this.scaleParameter = cloner.Clone(original.scaleParameter);
    52       this.sf2 = original.sf2;
    53       RegisterEvents();
    5447    }
    5548
     
    5952      Description = ItemDescription;
    6053
    61       this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of noise.");
    62       Parameters.Add(this.scaleParameter);
    63 
    64       RegisterEvents();
     54      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of noise."));
    6555    }
    6656
     
    6959    }
    7060
    71     [StorableHook(HookType.AfterDeserialization)]
    72     private void AfterDeserialization() {
    73       RegisterEvents();
     61    public int GetNumberOfParameters(int numberOfVariables) {
     62      return ScaleParameter.Value != null ? 0 : 1;
    7463    }
    7564
    76     private void RegisterEvents() {
    77       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
     65    public void SetParameter(double[] p) {
     66      double scale;
     67      GetParameterValues(p, out scale);
     68      ScaleParameter.Value = new DoubleValue(scale);
    7869    }
    7970
    80     public int GetNumberOfParameters(int numberOfVariables) {
    81       return scaleParameter.Fixed ? 0 : 1;
     71    private void GetParameterValues(double[] p, out double scale) {
     72      int c = 0;
     73      // gather parameter values
     74      if (ScaleParameter.Value != null) {
     75        scale = ScaleParameter.Value.Value;
     76      } else {
     77        scale = Math.Exp(2 * p[c]);
     78        c++;
     79      }
     80      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNoise", "p");
    8281    }
    8382
    84     public void SetParameter(double[] hyp) {
    85       if (!scaleParameter.Fixed) {
    86         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[0])));
    87       } else {
    88         if (hyp.Length > 0) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceNoise", "hyp");
    89       }
    90     }
    91 
    92     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    93       return i == j ? sf2 : 0.0;
    94     }
    95 
    96     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    97       yield return i == j ? 2 * sf2 : 0.0;
    98     }
    99 
    100     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    101       return 0.0;
     83    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     84      double scale;
     85      GetParameterValues(p, out scale);
     86      // create functions
     87      var cov = new ParameterizedCovarianceFunction();
     88      cov.Covariance = (x, i, j) => i == j ? scale : 0.0;
     89      cov.CrossCovariance = (x, xt, i, j) => 0.0;
     90      cov.CovarianceGradient = (x, i, j) => Enumerable.Repeat(i == j ? 2.0 * scale : 0.0, 1);
     91      return cov;
    10292    }
    10393  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePeriodic.cs

    r8929 r8982  
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
     
    3334  public sealed class CovariancePeriodic : ParameterizedNamedItem, ICovarianceFunction {
    3435
    35     [Storable]
    36     private double scale;
    37     [Storable]
    38     private readonly HyperParameter<DoubleValue> scaleParameter;
    3936    public IValueParameter<DoubleValue> ScaleParameter {
    40       get { return scaleParameter; }
     37      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    4138    }
    4239
    43     [Storable]
    44     private double inverseLength;
    45     [Storable]
    46     private readonly HyperParameter<DoubleValue> inverseLengthParameter;
    4740    public IValueParameter<DoubleValue> InverseLengthParameter {
    48       get { return inverseLengthParameter; }
     41      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
    4942    }
    5043
    51     [Storable]
    52     private double period;
    53     [Storable]
    54     private readonly HyperParameter<DoubleValue> periodParameter;
    5544    public IValueParameter<DoubleValue> PeriodParameter {
    56       get { return periodParameter; }
     45      get { return (IValueParameter<DoubleValue>)Parameters["Period"]; }
    5746    }
    5847
     
    6251    private CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
    6352      : base(original, cloner) {
    64       this.scaleParameter = cloner.Clone(original.scaleParameter);
    65       this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
    66       this.periodParameter = cloner.Clone(original.periodParameter);
    67       this.scale = original.scale;
    68       this.inverseLength = original.inverseLength;
    69       this.period = original.period;
    70 
    71       RegisterEvents();
    7253    }
    7354
     
    7758      Description = ItemDescription;
    7859
    79       scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale of the periodic covariance function.");
    80       inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter for the periodic covariance function.");
    81       periodParameter = new HyperParameter<DoubleValue>("Period", "The period parameter for the periodic covariance function.");
    82       Parameters.Add(scaleParameter);
    83       Parameters.Add(inverseLengthParameter);
    84       Parameters.Add(periodParameter);
    85 
    86       RegisterEvents();
    87     }
    88 
    89     [StorableHook(HookType.AfterDeserialization)]
    90     private void AfterDeserialization() {
    91       RegisterEvents();
     60      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale of the periodic covariance function."));
     61      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter for the periodic covariance function."));
     62      Parameters.Add(new OptionalValueParameter<DoubleValue>("Period", "The period parameter for the periodic covariance function."));
    9263    }
    9364
     
    9667    }
    9768
    98     // caching
    99     private void RegisterEvents() {
    100       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { scale = scaleParameter.Value.Value; });
    101       Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
    102       Util.AttachValueChangeHandler<DoubleValue, double>(periodParameter, () => { period = periodParameter.Value.Value; });
     69    public int GetNumberOfParameters(int numberOfVariables) {
     70      return (ScaleParameter.Value != null ? 0 : 1) +
     71       (PeriodParameter.Value != null ? 0 : 1) +
     72       (InverseLengthParameter.Value != null ? 0 : 1);
    10373    }
    10474
    105     public int GetNumberOfParameters(int numberOfVariables) {
    106       return
    107         (new[] { scaleParameter, inverseLengthParameter, periodParameter }).Count(p => !p.Fixed);
     75    public void SetParameter(double[] p) {
     76      double scale, inverseLength, period;
     77      GetParameterValues(p, out scale, out period, out inverseLength);
     78      ScaleParameter.Value = new DoubleValue(scale);
     79      PeriodParameter.Value = new DoubleValue(period);
     80      InverseLengthParameter.Value = new DoubleValue(inverseLength);
    10881    }
    10982
    110     public void SetParameter(double[] hyp) {
    111       int i = 0;
    112       if (!inverseLengthParameter.Fixed) {
    113         inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
    114         i++;
     83
     84    private void GetParameterValues(double[] p, out double scale, out double period, out double inverseLength) {
     85      // gather parameter values
     86      int c = 0;
     87      if (InverseLengthParameter.Value != null) {
     88        inverseLength = InverseLengthParameter.Value.Value;
     89      } else {
     90        inverseLength = 1.0 / Math.Exp(p[c]);
     91        c++;
    11592      }
    116       if (!periodParameter.Fixed) {
    117         periodParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
    118         i++;
     93      if (PeriodParameter.Value != null) {
     94        period = PeriodParameter.Value.Value;
     95      } else {
     96        period = Math.Exp(p[c]);
     97        c++;
    11998      }
    120       if (!scaleParameter.Fixed) {
    121         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
    122         i++;
     99      if (ScaleParameter.Value != null) {
     100        scale = ScaleParameter.Value.Value;
     101      } else {
     102        scale = Math.Exp(2 * p[c]);
     103        c++;
    123104      }
    124       if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePeriod", "hyp");
     105      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePeriodic", "p");
    125106    }
    126107
    127     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    128       double k = i == j ? 0.0 : GetDistance(x, x, i, j, columnIndices);
    129       k = Math.PI * k / period;
    130       k = Math.Sin(k) * inverseLength;
    131       k = k * k;
     108    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     109      double inverseLength, period, scale;
     110      GetParameterValues(p, out scale, out period, out inverseLength);
     111      // create functions
     112      var cov = new ParameterizedCovarianceFunction();
     113      cov.Covariance = (x, i, j) => {
     114        double k = i == j ? 0.0 : GetDistance(x, x, i, j, columnIndices);
     115        k = Math.PI * k / period;
     116        k = Math.Sin(k) * inverseLength;
     117        k = k * k;
    132118
    133       return scale * Math.Exp(-2.0 * k);
     119        return scale * Math.Exp(-2.0 * k);
     120      };
     121      cov.CrossCovariance = (x, xt, i, j) => {
     122        double k = GetDistance(x, xt, i, j, columnIndices);
     123        k = Math.PI * k / period;
     124        k = Math.Sin(k) * inverseLength;
     125        k = k * k;
     126
     127        return scale * Math.Exp(-2.0 * k);
     128      };
     129      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, period, inverseLength);
     130      return cov;
    134131    }
    135132
    136     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     133
     134    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double period, double inverseLength) {
    137135      double v = i == j ? 0.0 : Math.PI * GetDistance(x, x, i, j, columnIndices) / period;
    138136      double gradient = Math.Sin(v) * inverseLength;
     
    144142    }
    145143
    146     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    147       double k = GetDistance(x, xt, i, j, columnIndices);
    148       k = Math.PI * k / period;
    149       k = Math.Sin(k) * inverseLength;
    150       k = k * k;
    151 
    152       return scale * Math.Exp(-2.0 * k);
    153     }
    154 
    155     private double GetDistance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
     144    private static double GetDistance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    156145      return Math.Sqrt(Util.SqrDist(x, i, xt, j, 1, columnIndices));
    157146    }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs

    r8929 r8982  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using System.Linq.Expressions;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    6667    }
    6768
    68     public void SetParameter(double[] hyp) {
    69       if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");
     69    public void SetParameter(double[] p) {
    7070      int offset = 0;
    71       foreach (var t in factors) {
    72         var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
    73         t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
     71      foreach (var f in factors) {
     72        var numberOfParameters = f.GetNumberOfParameters(numberOfVariables);
     73        f.SetParameter(p.Skip(offset).Take(numberOfParameters).ToArray());
    7474        offset += numberOfParameters;
    7575      }
    7676    }
    7777
    78     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    79       return factors.Select(f => f.GetCovariance(x, i, j, columnIndices)).Aggregate((a, b) => a * b);
     78    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     79      if (factors.Count == 0) throw new ArgumentException("at least one factor is necessary for the product covariance function.");
     80      var functions = new List<ParameterizedCovarianceFunction>();
     81      foreach (var f in factors) {
     82        int numberOfParameters = f.GetNumberOfParameters(numberOfVariables);
     83        functions.Add(f.GetParameterizedCovarianceFunction(p.Take(numberOfParameters).ToArray(), columnIndices));
     84        p = p.Skip(numberOfParameters).ToArray();
     85      }
     86
     87
     88      var product = new ParameterizedCovarianceFunction();
     89      product.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Aggregate((a, b) => a * b);
     90      product.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Aggregate((a, b) => a * b);
     91      product.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, functions);
     92      return product;
    8093    }
    8194
    82     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    83       var covariances = factors.Select(f => f.GetCovariance(x, i, j, columnIndices)).ToArray();
    84       for (int ii = 0; ii < factors.Count; ii++) {
    85         foreach (var g in factors[ii].GetGradient(x, i, j, columnIndices)) {
     95    public static IEnumerable<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {
     96      var covariances = factorFunctions.Select(f => f.Covariance(x, i, j)).ToArray();
     97      for (int ii = 0; ii < factorFunctions.Count; ii++) {
     98        foreach (var g in factorFunctions[ii].CovarianceGradient(x, i, j)) {
    8699          double res = g;
    87100          for (int jj = 0; jj < covariances.Length; jj++)
     
    91104      }
    92105    }
    93 
    94     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    95       return factors.Select(f => f.GetCrossCovariance(x, xt, i, j, columnIndices)).Aggregate((a, b) => a * b);
    96     }
    97106  }
    98107}
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticArd.cs

    r8933 r8982  
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
     
    3334    Description = "Rational quadratic covariance function with automatic relevance determination for Gaussian processes.")]
    3435  public sealed class CovarianceRationalQuadraticArd : ParameterizedNamedItem, ICovarianceFunction {
    35     [Storable]
    36     private double sf2;
    37     [Storable]
    38     private readonly HyperParameter<DoubleValue> scaleParameter;
    3936    public IValueParameter<DoubleValue> ScaleParameter {
    40       get { return scaleParameter; }
     37      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    4138    }
    4239
    43     [Storable]
    44     private double[] inverseLength;
    45     [Storable]
    46     private readonly HyperParameter<DoubleArray> inverseLengthParameter;
    4740    public IValueParameter<DoubleArray> InverseLengthParameter {
    48       get { return inverseLengthParameter; }
     41      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
    4942    }
    5043
    51     [Storable]
    52     private double shape;
    53     [Storable]
    54     private readonly HyperParameter<DoubleValue> shapeParameter;
    5544    public IValueParameter<DoubleValue> ShapeParameter {
    56       get { return shapeParameter; }
     45      get { return (IValueParameter<DoubleValue>)Parameters["Shape"]; }
    5746    }
    5847
     
    6453    private CovarianceRationalQuadraticArd(CovarianceRationalQuadraticArd original, Cloner cloner)
    6554      : 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();
    7955    }
    8056
     
    8460      Description = ItemDescription;
    8561
    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();
     62      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the rational quadratic covariance function with ARD."));
     63      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination."));
     64      Parameters.Add(new OptionalValueParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the rational quadratic covariance function with ARD."));
    9565    }
    9666
     
    9969    }
    10070
    101     [StorableHook(HookType.AfterDeserialization)]
    102     private void AfterDeserialization() {
    103       RegisterEvents();
     71    public int GetNumberOfParameters(int numberOfVariables) {
     72      return
     73        (ScaleParameter.Value != null ? 0 : 1) +
     74        (ShapeParameter.Value != null ? 0 : 1) +
     75        (InverseLengthParameter.Value != null ? 0 : numberOfVariables);
    10476    }
    10577
    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(); });
     78    public void SetParameter(double[] p) {
     79      double scale, shape;
     80      double[] inverseLength;
     81      GetParameterValues(p, out scale, out shape, out inverseLength);
     82      ScaleParameter.Value = new DoubleValue(scale);
     83      ShapeParameter.Value = new DoubleValue(shape);
     84      InverseLengthParameter.Value = new DoubleArray(inverseLength);
    11085    }
    11186
    112     public int GetNumberOfParameters(int numberOfVariables) {
    113       return
    114         (scaleParameter.Fixed ? 0 : 1) +
    115         (shapeParameter.Fixed ? 0 : 1) +
    116         (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
     87    private void GetParameterValues(double[] p, out double scale, out double shape, out double[] inverseLength) {
     88      int c = 0;
     89      // gather parameter values
     90      if (ScaleParameter.Value != null) {
     91        scale = ScaleParameter.Value.Value;
     92      } else {
     93        scale = Math.Exp(2 * p[c]);
     94        c++;
     95      }
     96      if (ShapeParameter.Value != null) {
     97        shape = ShapeParameter.Value.Value;
     98      } else {
     99        shape = Math.Exp(p[c]);
     100        c++;
     101      }
     102      if (InverseLengthParameter.Value != null) {
     103        inverseLength = InverseLengthParameter.Value.ToArray();
     104      } else {
     105        inverseLength = p.Skip(2).Select(e => 1.0 / Math.Exp(e)).ToArray();
     106        c += inverseLength.Length;
     107      }
     108      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticArd", "p");
    117109    }
    118110
    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");
     111    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     112      double scale, shape;
     113      double[] inverseLength;
     114      GetParameterValues(p, out scale, out shape, out inverseLength);
     115      // create functions
     116      var cov = new ParameterizedCovarianceFunction();
     117      cov.Covariance = (x, i, j) => {
     118        double d = i == j
     119                    ? 0.0
     120                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
     121        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
     122      };
     123      cov.CrossCovariance = (x, xt, i, j) => {
     124        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
     125        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
     126      };
     127      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, shape, inverseLength);
     128      return cov;
    134129    }
    135130
    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) {
     131    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double shape, double[] inverseLength) {
    145132      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
    146133      double d = i == j
     
    150137      int k = 0;
    151138      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]);
     139        yield return scale * Math.Pow(b, -shape - 1) * Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
    153140        k++;
    154141      }
    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);
     142      yield return 2 * scale * Math.Pow(b, -shape);
     143      yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
    162144    }
    163145  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceRationalQuadraticIso.cs

    r8929 r8982  
    2525using HeuristicLab.Core;
    2626using HeuristicLab.Data;
     27using HeuristicLab.Parameters;
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2829
     
    3233    Description = "Isotropic rational quadratic covariance function for Gaussian processes.")]
    3334  public sealed class CovarianceRationalQuadraticIso : ParameterizedNamedItem, ICovarianceFunction {
    34     [Storable]
    35     private double sf2;
    36     [Storable]
    37     private readonly HyperParameter<DoubleValue> scaleParameter;
    38     public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
     35    public IValueParameter<DoubleValue> ScaleParameter {
     36      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     37    }
    3938
    40     [Storable]
    41     private double inverseLength;
    42     [Storable]
    43     private readonly HyperParameter<DoubleValue> inverseLengthParameter;
    44     public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
     39    public IValueParameter<DoubleValue> InverseLengthParameter {
     40      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
     41    }
    4542
    46     [Storable]
    47     private double shape;
    48     [Storable]
    49     private readonly HyperParameter<DoubleValue> shapeParameter;
    50     public IValueParameter<DoubleValue> ShapeParameter { get { return shapeParameter; } }
    51 
     43    public IValueParameter<DoubleValue> ShapeParameter {
     44      get { return (IValueParameter<DoubleValue>)Parameters["Shape"]; }
     45    }
    5246    [StorableConstructor]
    5347    private CovarianceRationalQuadraticIso(bool deserializing)
     
    5751    private CovarianceRationalQuadraticIso(CovarianceRationalQuadraticIso original, Cloner cloner)
    5852      : base(original, cloner) {
    59       this.sf2 = original.sf2;
    60       this.scaleParameter = cloner.Clone(original.scaleParameter);
    61 
    62       this.inverseLength = original.inverseLength;
    63       this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
    64 
    65       this.shape = original.shape;
    66       this.shapeParameter = cloner.Clone(original.shapeParameter);
    67 
    68       RegisterEvents();
    6953    }
    7054
     
    7458      Description = ItemDescription;
    7559
    76       this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric rational quadratic covariance function.");
    77       this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric rational quadratic covariance function.");
    78       this.shapeParameter = new HyperParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the isometric rational quadratic covariance function.");
    79 
    80       Parameters.Add(scaleParameter);
    81       Parameters.Add(inverseLengthParameter);
    82       Parameters.Add(shapeParameter);
    83 
    84       RegisterEvents();
     60      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the isometric rational quadratic covariance function."));
     61      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric rational quadratic covariance function."));
     62      Parameters.Add(new OptionalValueParameter<DoubleValue>("Shape", "The shape parameter (alpha) of the isometric rational quadratic covariance function."));
    8563    }
    8664
     
    8967    }
    9068
    91     [StorableHook(HookType.AfterDeserialization)]
    92     private void AfterDeserialization() {
    93       RegisterEvents();
     69    public int GetNumberOfParameters(int numberOfVariables) {
     70      return (ScaleParameter.Value != null ? 0 : 1) +
     71        (ShapeParameter.Value != null ? 0 : 1) +
     72        (InverseLengthParameter.Value != null ? 0 : 1);
    9473    }
    9574
    96     private void RegisterEvents() {
    97       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
    98       Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
    99       Util.AttachValueChangeHandler<DoubleValue, double>(shapeParameter, () => { shape = shapeParameter.Value.Value; });
     75    public void SetParameter(double[] p) {
     76      double scale, shape, inverseLength;
     77      GetParameterValues(p, out scale, out shape, out inverseLength);
     78      ScaleParameter.Value = new DoubleValue(scale);
     79      ShapeParameter.Value = new DoubleValue(shape);
     80      InverseLengthParameter.Value = new DoubleValue(inverseLength);
    10081    }
    10182
    102     public int GetNumberOfParameters(int numberOfVariables) {
    103       return
    104         (scaleParameter.Fixed ? 0 : 1) +
    105         (inverseLengthParameter.Fixed ? 0 : 1) +
    106         (shapeParameter.Fixed ? 0 : 1);
     83    private void GetParameterValues(double[] p, out double scale, out double shape, out double inverseLength) {
     84      int c = 0;
     85      // gather parameter values
     86      if (ScaleParameter.Value != null) {
     87        scale = ScaleParameter.Value.Value;
     88      } else {
     89        scale = Math.Exp(2 * p[c]);
     90        c++;
     91      }
     92      if (ShapeParameter.Value != null) {
     93        shape = ShapeParameter.Value.Value;
     94      } else {
     95        shape = Math.Exp(p[c]);
     96        c++;
     97      }
     98      if (InverseLengthParameter.Value != null) {
     99        inverseLength = InverseLengthParameter.Value.Value;
     100      } else {
     101        inverseLength = 1.0 / Math.Exp(p[c]);
     102        c++;
     103      }
     104      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticIso", "p");
    107105    }
    108106
    109     public void SetParameter(double[] hyp) {
    110       int i = 0;
    111       if (!scaleParameter.Fixed) {
    112         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
    113         i++;
    114       }
    115       if (!shapeParameter.Fixed) {
    116         shapeParameter.SetValue(new DoubleValue(Math.Exp(hyp[i])));
    117         i++;
    118       }
    119       if (!inverseLengthParameter.Fixed) {
    120         inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
    121         i++;
    122       }
    123       if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceRationalQuadraticIso", "hyp");
     107    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     108      double scale, shape, inverseLength;
     109      GetParameterValues(p, out scale, out shape, out inverseLength);
     110      // create functions
     111      var cov = new ParameterizedCovarianceFunction();
     112      cov.Covariance = (x, i, j) => {
     113        double d = i == j
     114                    ? 0.0
     115                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
     116        return shape * Math.Pow(1 + 0.5 * d / shape, -shape);
     117      };
     118      cov.CrossCovariance = (x, xt, i, j) => {
     119        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
     120        return scale * Math.Pow(1 + 0.5 * d / shape, -shape);
     121      };
     122      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, shape, inverseLength);
     123      return cov;
    124124    }
    125125
    126 
    127     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    128       double d = i == j
    129                    ? 0.0
    130                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
    131       return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
    132     }
    133 
    134     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     126    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double shape, double inverseLength) {
    135127      double d = i == j
    136128                   ? 0.0
     
    138130
    139131      double b = 1 + 0.5 * d / shape;
    140       yield return sf2 * Math.Pow(b, -shape - 1) * d;
    141       yield return 2 * sf2 * Math.Pow(b, -shape);
    142       yield return sf2 * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
    143     }
    144 
    145     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    146       double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
    147       return sf2 * Math.Pow(1 + 0.5 * d / shape, -shape);
     132      yield return scale * Math.Pow(b, -shape - 1) * d;
     133      yield return 2 * scale * Math.Pow(b, -shape);
     134      yield return scale * Math.Pow(b, -shape) * (0.5 * d / b - shape * Math.Log(b));
    148135    }
    149136  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceScale.cs

    r8929 r8982  
    3434    Description = "Scale covariance function for Gaussian processes.")]
    3535  public sealed class CovarianceScale : ParameterizedNamedItem, ICovarianceFunction {
    36     [Storable]
    37     private double sf2;
    38     [Storable]
    39     private readonly HyperParameter<DoubleValue> scaleParameter;
    4036    public IValueParameter<DoubleValue> ScaleParameter {
    41       get { return scaleParameter; }
     37      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
    4238    }
    4339
    44     [Storable]
    45     private ICovarianceFunction cov;
    46     [Storable]
    47     private readonly ValueParameter<ICovarianceFunction> covParameter;
    4840    public IValueParameter<ICovarianceFunction> CovarianceFunctionParameter {
    49       get { return covParameter; }
     41      get { return (IValueParameter<ICovarianceFunction>)Parameters["CovarianceFunction"]; }
    5042    }
    5143
     
    5749    private CovarianceScale(CovarianceScale original, Cloner cloner)
    5850      : base(original, cloner) {
    59       this.scaleParameter = cloner.Clone(original.scaleParameter);
    60       this.sf2 = original.sf2;
    61 
    62       this.covParameter = cloner.Clone(original.covParameter);
    63       this.cov = cloner.Clone(original.cov);
    64       RegisterEvents();
    6551    }
    6652
     
    7056      Description = ItemDescription;
    7157
    72       this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter.");
    73       this.covParameter = new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso());
    74       cov = covParameter.Value;
    75 
    76       Parameters.Add(this.scaleParameter);
    77       Parameters.Add(covParameter);
    78 
    79       RegisterEvents();
     58      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter."));
     59      Parameters.Add(new ValueParameter<ICovarianceFunction>("CovarianceFunction", "The covariance function that should be scaled.", new CovarianceSquaredExponentialIso()));
    8060    }
    8161
     
    8464    }
    8565
    86     [StorableHook(HookType.AfterDeserialization)]
    87     private void AfterDeserialization() {
    88       RegisterEvents();
     66    public int GetNumberOfParameters(int numberOfVariables) {
     67      return (ScaleParameter.Value != null ? 0 : 1) + CovarianceFunctionParameter.Value.GetNumberOfParameters(numberOfVariables);
    8968    }
    9069
    91     private void RegisterEvents() {
    92       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
    93       covParameter.ValueChanged += (sender, args) => { cov = covParameter.Value; };
     70    public void SetParameter(double[] p) {
     71      double scale;
     72      GetParameterValues(p, out scale);
     73      ScaleParameter.Value = new DoubleValue(scale);
     74      CovarianceFunctionParameter.Value.SetParameter(p.Skip(1).ToArray());
    9475    }
    9576
    96     public int GetNumberOfParameters(int numberOfVariables) {
    97       return (scaleParameter.Fixed ? 0 : 1) + cov.GetNumberOfParameters(numberOfVariables);
     77    private void GetParameterValues(double[] p, out double scale) {
     78      // gather parameter values
     79      if (ScaleParameter.Value != null) {
     80        scale = ScaleParameter.Value.Value;
     81      } else {
     82        scale = Math.Exp(2 * p[0]);
     83      }
    9884    }
    9985
    100     public void SetParameter(double[] hyp) {
    101       int i = 0;
    102       if (!scaleParameter.Fixed) {
    103         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
    104         i++;
    105       }
    106       cov.SetParameter(hyp.Skip(i).ToArray());
     86    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     87      double scale;
     88      GetParameterValues(p, out scale);
     89      var subCov = CovarianceFunctionParameter.Value.GetParameterizedCovarianceFunction(p.Skip(1).ToArray(), columnIndices);
     90      // create functions
     91      var cov = new ParameterizedCovarianceFunction();
     92      cov.Covariance = (x, i, j) => scale * subCov.Covariance(x, i, j);
     93      cov.CrossCovariance = (x, xt, i, j) => scale * subCov.CrossCovariance(x, xt, i, j);
     94      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, subCov);
     95      return cov;
    10796    }
    10897
    109     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    110       return sf2 * cov.GetCovariance(x, i, j, columnIndices);
    111     }
    112 
    113     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    114       yield return 2 * sf2 * cov.GetCovariance(x, i, j, columnIndices);
    115       foreach (var g in cov.GetGradient(x, i, j, columnIndices))
    116         yield return sf2 * g;
    117     }
    118 
    119     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    120       return sf2 * cov.GetCrossCovariance(x, xt, i, j, columnIndices);
     98    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, ParameterizedCovarianceFunction cov) {
     99      yield return 2 * scale * cov.Covariance(x, i, j);
     100      foreach (var g in cov.CovarianceGradient(x, i, j))
     101        yield return scale * g;
    121102    }
    122103  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialArd.cs

    r8933 r8982  
    2626using HeuristicLab.Core;
    2727using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2829using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2930
     
    3233  [Item(Name = "CovarianceSquaredExponentialArd", Description = "Squared exponential covariance function with automatic relevance determination for Gaussian processes.")]
    3334  public sealed class CovarianceSquaredExponentialArd : ParameterizedNamedItem, ICovarianceFunction {
    34     [Storable]
    35     private double sf2;
    36     [Storable]
    37     private readonly HyperParameter<DoubleValue> scaleParameter;
    38     public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
     35    public IValueParameter<DoubleValue> ScaleParameter {
     36      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     37    }
    3938
    40     [Storable]
    41     private double[] inverseLength;
    42     [Storable]
    43     private readonly HyperParameter<DoubleArray> inverseLengthParameter;
    44     public IValueParameter<DoubleArray> InverseLengthParameter { get { return inverseLengthParameter; } }
     39    public IValueParameter<DoubleArray> InverseLengthParameter {
     40      get { return (IValueParameter<DoubleArray>)Parameters["InverseLength"]; }
     41    }
    4542
    4643    [StorableConstructor]
     
    4845    private CovarianceSquaredExponentialArd(CovarianceSquaredExponentialArd original, Cloner cloner)
    4946      : 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();
    6047    }
    6148    public CovarianceSquaredExponentialArd()
     
    6451      Description = ItemDescription;
    6552
    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();
     53      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the squared exponential covariance function with ARD."));
     54      Parameters.Add(new OptionalValueParameter<DoubleArray>("InverseLength", "The inverse length parameter for automatic relevance determination."));
    7355    }
    7456
     
    7759    }
    7860
    79     [StorableHook(HookType.AfterDeserialization)]
    80     private void AfterDeserialization() {
    81       RegisterEvents();
     61    public int GetNumberOfParameters(int numberOfVariables) {
     62      return
     63        (ScaleParameter.Value != null ? 0 : 1) +
     64        (InverseLengthParameter.Value != null ? 0 : numberOfVariables);
    8265    }
    8366
    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       });
     67    public void SetParameter(double[] p) {
     68      double scale;
     69      double[] inverseLength;
     70      GetParameterValues(p, out scale, out inverseLength);
     71      ScaleParameter.Value = new DoubleValue(scale);
     72      InverseLengthParameter.Value = new DoubleArray(inverseLength);
    9073    }
    9174
    92     public int GetNumberOfParameters(int numberOfVariables) {
    93       return
    94         (scaleParameter.Fixed ? 0 : 1) +
    95         (inverseLengthParameter.Fixed ? 0 : numberOfVariables);
     75    private void GetParameterValues(double[] p, out double scale, out double[] inverseLength) {
     76      int c = 0;
     77      // gather parameter values
     78      if (ScaleParameter.Value != null) {
     79        scale = ScaleParameter.Value.Value;
     80      } else {
     81        scale = Math.Exp(2 * p[c]);
     82        c++;
     83      }
     84      if (InverseLengthParameter.Value != null) {
     85        inverseLength = InverseLengthParameter.Value.ToArray();
     86      } else {
     87        inverseLength = p.Skip(1).Select(e => 1.0 / Math.Exp(e)).ToArray();
     88        c += inverseLength.Length;
     89      }
     90      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialArd", "p");
     91    }
     92
     93    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     94      double scale;
     95      double[] inverseLength;
     96      GetParameterValues(p, out scale, out inverseLength);
     97      // create functions
     98      var cov = new ParameterizedCovarianceFunction();
     99      cov.Covariance = (x, i, j) => {
     100        double d = i == j
     101                 ? 0.0
     102                 : Util.SqrDist(x, i, j, inverseLength, columnIndices);
     103        return scale * Math.Exp(-d / 2.0);
     104      };
     105      cov.CrossCovariance = (x, xt, i, j) => {
     106        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
     107        return scale * Math.Exp(-d / 2.0);
     108      };
     109      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, columnIndices, scale, inverseLength);
     110      return cov;
    96111    }
    97112
    98113
    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 CovarianceSquaredExponentialArd", "hyp");
    110     }
    111 
    112     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    113       double d = i == j
    114                    ? 0.0
    115                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
    116       return sf2 * Math.Exp(-d / 2.0);
    117     }
    118 
    119     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     114    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices, double scale, double[] inverseLength) {
    120115      if (columnIndices == null) columnIndices = Enumerable.Range(0, x.GetLength(1));
    121116      double d = i == j
     
    125120      foreach (var columnIndex in columnIndices) {
    126121        double sqrDist = Util.SqrDist(x[i, columnIndex] * inverseLength[k], x[j, columnIndex] * inverseLength[k]);
    127         yield return sf2 * Math.Exp(-d / 2.0) * sqrDist;
     122        yield return scale * Math.Exp(-d / 2.0) * sqrDist;
    128123        k++;
    129124      }
    130125
    131       yield return 2.0 * sf2 * Math.Exp(-d / 2.0);
    132     }
    133 
    134     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    135       double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
    136       return sf2 * Math.Exp(-d / 2.0);
     126      yield return 2.0 * scale * Math.Exp(-d / 2.0);
    137127    }
    138128  }
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSquaredExponentialIso.cs

    r8929 r8982  
    2222using System;
    2323using System.Collections.Generic;
     24using System.Linq.Expressions;
    2425using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    2627using HeuristicLab.Data;
     28using HeuristicLab.Parameters;
    2729using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2830
     
    3234    Description = "Isotropic squared exponential covariance function for Gaussian processes.")]
    3335  public sealed class CovarianceSquaredExponentialIso : ParameterizedNamedItem, ICovarianceFunction {
    34     [Storable]
    35     private double sf2;
    36     [Storable]
    37     private readonly HyperParameter<DoubleValue> scaleParameter;
    38     public IValueParameter<DoubleValue> ScaleParameter { get { return scaleParameter; } }
     36    public IValueParameter<DoubleValue> ScaleParameter {
     37      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
     38    }
    3939
    40     [Storable]
    41     private double inverseLength;
    42     [Storable]
    43     private readonly HyperParameter<DoubleValue> inverseLengthParameter;
    44     public IValueParameter<DoubleValue> InverseLengthParameter { get { return inverseLengthParameter; } }
     40    public IValueParameter<DoubleValue> InverseLengthParameter {
     41      get { return (IValueParameter<DoubleValue>)Parameters["InverseLength"]; }
     42    }
    4543
    4644    [StorableConstructor]
     
    5149    private CovarianceSquaredExponentialIso(CovarianceSquaredExponentialIso original, Cloner cloner)
    5250      : base(original, cloner) {
    53       this.sf2 = original.sf2;
    54       this.scaleParameter = cloner.Clone(original.scaleParameter);
    55 
    56       this.inverseLength = original.inverseLength;
    57       this.inverseLengthParameter = cloner.Clone(original.inverseLengthParameter);
    58 
    59       RegisterEvents();
    6051    }
    6152
     
    6556      Description = ItemDescription;
    6657
    67       this.scaleParameter = new HyperParameter<DoubleValue>("Scale", "The scale parameter of the isometric squared exponential covariance function.");
    68       this.inverseLengthParameter = new HyperParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric squared exponential covariance function.");
    69 
    70       Parameters.Add(scaleParameter);
    71       Parameters.Add(inverseLengthParameter);
    72 
    73       RegisterEvents();
     58      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the isometric squared exponential covariance function."));
     59      Parameters.Add(new OptionalValueParameter<DoubleValue>("InverseLength", "The inverse length parameter of the isometric squared exponential covariance function."));
    7460    }
    7561
     
    7864    }
    7965
    80     [StorableHook(HookType.AfterDeserialization)]
    81     private void AfterDeserialization() {
    82       RegisterEvents();
     66    public int GetNumberOfParameters(int numberOfVariables) {
     67      return
     68        (ScaleParameter.Value != null ? 0 : 1) +
     69        (InverseLengthParameter.Value != null ? 0 : 1);
    8370    }
    8471
    85     private void RegisterEvents() {
    86       Util.AttachValueChangeHandler<DoubleValue, double>(scaleParameter, () => { sf2 = scaleParameter.Value.Value; });
    87       Util.AttachValueChangeHandler<DoubleValue, double>(inverseLengthParameter, () => { inverseLength = inverseLengthParameter.Value.Value; });
    88     }
    89 
    90     public int GetNumberOfParameters(int numberOfVariables) {
    91       return
    92         (scaleParameter.Fixed ? 0 : 1) +
    93         (inverseLengthParameter.Fixed ? 0 : 1);
    94     }
    95 
    96     public void SetParameter(double[] hyp) {
    97       int i = 0;
    98       if (!inverseLengthParameter.Fixed) {
    99         inverseLengthParameter.SetValue(new DoubleValue(1.0 / Math.Exp(hyp[i])));
    100         i++;
    101       }
    102       if (!scaleParameter.Fixed) {
    103         scaleParameter.SetValue(new DoubleValue(Math.Exp(2 * hyp[i])));
    104         i++;
    105       }
    106       if (hyp.Length != i) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialIso", "hyp");
     72    public void SetParameter(double[] p) {
     73      double scale, inverseLength;
     74      GetParameterValues(p, out scale, out inverseLength);
     75      ScaleParameter.Value = new DoubleValue(scale);
     76      InverseLengthParameter.Value = new DoubleValue(inverseLength);
    10777    }
    10878
    10979
    110     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    111       double d = i == j
    112                    ? 0.0
    113                    : Util.SqrDist(x, i, j, inverseLength, columnIndices);
    114       return sf2 * Math.Exp(-d / 2.0);
     80    private void GetParameterValues(double[] p, out double scale, out double inverseLength) {
     81      // gather parameter values
     82      int c = 0;
     83      if (InverseLengthParameter.Value != null) {
     84        inverseLength = InverseLengthParameter.Value.Value;
     85      } else {
     86        inverseLength = 1.0 / Math.Exp(p[c]);
     87        c++;
     88      }
     89
     90      if (ScaleParameter.Value != null) {
     91        scale = ScaleParameter.Value.Value;
     92      } else {
     93        scale = Math.Exp(2 * p[c]);
     94        c++;
     95      }
     96      if (p.Length != c) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovarianceSquaredExponentialIso", "p");
    11597    }
    11698
    117     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
     99    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     100      double inverseLength, scale;
     101      GetParameterValues(p, out scale, out inverseLength);
     102      // create functions
     103      var cov = new ParameterizedCovarianceFunction();
     104      cov.Covariance = (x, i, j) => {
     105        double d = i == j
     106                ? 0.0
     107                : Util.SqrDist(x, i, j, inverseLength, columnIndices);
     108        return scale * Math.Exp(-d / 2.0);
     109      };
     110      cov.CrossCovariance = (x, xt, i, j) => {
     111        double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
     112        return scale * Math.Exp(-d / 2.0);
     113      };
     114      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, scale, inverseLength, columnIndices);
     115      return cov;
     116    }
     117
     118    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double sf2, double inverseLength, IEnumerable<int> columnIndices) {
    118119      double d = i == j
    119120                   ? 0.0
     
    123124      yield return 2.0 * sf2 * g;
    124125    }
    125 
    126     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    127       double d = Util.SqrDist(x, i, xt, j, inverseLength, columnIndices);
    128       return sf2 * Math.Exp(-d / 2.0);
    129     }
    130126  }
    131127}
  • trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs

    r8929 r8982  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using System.Linq.Expressions;
    2526using HeuristicLab.Common;
    2627using HeuristicLab.Core;
     
    6667    }
    6768
    68     public void SetParameter(double[] hyp) {
    69       if (terms.Count == 0) throw new ArgumentException("At least one term is needed for sum covariance function.");
     69    public void SetParameter(double[] p) {
    7070      int offset = 0;
    7171      foreach (var t in terms) {
    7272        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
    73         t.SetParameter(hyp.Skip(offset).Take(numberOfParameters).ToArray());
     73        t.SetParameter(p.Skip(offset).Take(numberOfParameters).ToArray());
    7474        offset += numberOfParameters;
    7575      }
    7676    }
    7777
    78     public double GetCovariance(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    79       return terms.Select(t => t.GetCovariance(x, i, j, columnIndices)).Sum();
    80     }
     78    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, IEnumerable<int> columnIndices) {
     79      if (terms.Count == 0) throw new ArgumentException("at least one term is necessary for the product covariance function.");
     80      var functions = new List<ParameterizedCovarianceFunction>();
     81      foreach (var t in terms) {
     82        var numberOfParameters = t.GetNumberOfParameters(numberOfVariables);
     83        functions.Add(t.GetParameterizedCovarianceFunction(p.Take(numberOfParameters).ToArray(), columnIndices));
     84        p = p.Skip(numberOfParameters).ToArray();
     85      }
    8186
    82     public IEnumerable<double> GetGradient(double[,] x, int i, int j, IEnumerable<int> columnIndices) {
    83       return terms.Select(t => t.GetGradient(x, i, j, columnIndices)).Aggregate(Enumerable.Concat);
    84     }
    85 
    86     public double GetCrossCovariance(double[,] x, double[,] xt, int i, int j, IEnumerable<int> columnIndices) {
    87       return terms.Select(t => t.GetCrossCovariance(x, xt, i, j, columnIndices)).Sum();
     87      var sum = new ParameterizedCovarianceFunction();
     88      sum.Covariance = (x, i, j) => functions.Select(e => e.Covariance(x, i, j)).Sum();
     89      sum.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Sum();
     90      sum.CovarianceGradient = (x, i, j) => functions.Select(e => e.CovarianceGradient(x, i, j)).Aggregate(Enumerable.Concat);
     91      return sum;
    8892    }
    8993  }
Note: See TracChangeset for help on using the changeset viewer.