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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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  }
Note: See TracChangeset for help on using the changeset viewer.