source: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovariancePiecewisePolynomial.cs @ 13721

Last change on this file since 13721 was 13721, checked in by mkommend, 5 years ago

#2591: Changed all GP covariance and mean functions to use int[] for column indices instead of IEnumerable<int>. Changed GP utils, GPModel and StudentTProcessModell as well to use fewer iterators and adapted unit tests to new interface.

File size: 6.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Data;
28using HeuristicLab.Parameters;
29using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
30
31namespace HeuristicLab.Algorithms.DataAnalysis {
32  [StorableClass]
33  [Item(Name = "CovariancePiecewisePolynomial",
34    Description = "Piecewise polynomial covariance function with compact support for Gaussian processes.")]
35  public sealed class CovariancePiecewisePolynomial : ParameterizedNamedItem, ICovarianceFunction {
36    public IValueParameter<DoubleValue> LengthParameter {
37      get { return (IValueParameter<DoubleValue>)Parameters["Length"]; }
38    }
39
40    public IValueParameter<DoubleValue> ScaleParameter {
41      get { return (IValueParameter<DoubleValue>)Parameters["Scale"]; }
42    }
43
44    public IConstrainedValueParameter<IntValue> VParameter {
45      get { return (IConstrainedValueParameter<IntValue>)Parameters["V"]; }
46    }
47    private bool HasFixedLengthParameter {
48      get { return LengthParameter.Value != null; }
49    }
50    private bool HasFixedScaleParameter {
51      get { return ScaleParameter.Value != null; }
52    }
53
54    [StorableConstructor]
55    private CovariancePiecewisePolynomial(bool deserializing)
56      : base(deserializing) {
57    }
58
59    private CovariancePiecewisePolynomial(CovariancePiecewisePolynomial original, Cloner cloner)
60      : base(original, cloner) {
61    }
62
63    public CovariancePiecewisePolynomial()
64      : base() {
65      Name = ItemName;
66      Description = ItemDescription;
67
68      Parameters.Add(new OptionalValueParameter<DoubleValue>("Length", "The length parameter of the isometric piecewise polynomial covariance function."));
69      Parameters.Add(new OptionalValueParameter<DoubleValue>("Scale", "The scale parameter of the piecewise polynomial covariance function."));
70
71      var validValues = new ItemSet<IntValue>(new IntValue[] {
72        (IntValue)(new IntValue().AsReadOnly()),
73        (IntValue)(new IntValue(1).AsReadOnly()),
74        (IntValue)(new IntValue(2).AsReadOnly()),
75        (IntValue)(new IntValue(3).AsReadOnly()) });
76      Parameters.Add(new ConstrainedValueParameter<IntValue>("V", "The v parameter of the piecewise polynomial function (allowed values 0, 1, 2, 3).", validValues, validValues.First()));
77    }
78
79    public override IDeepCloneable Clone(Cloner cloner) {
80      return new CovariancePiecewisePolynomial(this, cloner);
81    }
82
83    public int GetNumberOfParameters(int numberOfVariables) {
84      return
85        (HasFixedLengthParameter ? 0 : 1) +
86        (HasFixedScaleParameter ? 0 : 1);
87    }
88
89    public void SetParameter(double[] p) {
90      double @const, scale;
91      GetParameterValues(p, out @const, out scale);
92      LengthParameter.Value = new DoubleValue(@const);
93      ScaleParameter.Value = new DoubleValue(scale);
94    }
95
96    private void GetParameterValues(double[] p, out double length, out double scale) {
97      // gather parameter values
98      int n = 0;
99      if (HasFixedLengthParameter) {
100        length = LengthParameter.Value.Value;
101      } else {
102        length = Math.Exp(p[n]);
103        n++;
104      }
105
106      if (HasFixedScaleParameter) {
107        scale = ScaleParameter.Value.Value;
108      } else {
109        scale = Math.Exp(2 * p[n]);
110        n++;
111      }
112      if (p.Length != n) throw new ArgumentException("The length of the parameter vector does not match the number of free parameters for CovariancePiecewisePolynomial", "p");
113    }
114
115    public ParameterizedCovarianceFunction GetParameterizedCovarianceFunction(double[] p, int[] columnIndices) {
116      double length, scale;
117      int v = VParameter.Value.Value;
118      GetParameterValues(p, out length, out scale);
119      var fixedLength = HasFixedLengthParameter;
120      var fixedScale = HasFixedScaleParameter;
121      int exp = (int)Math.Floor(columnIndices.Count() / 2.0) + v + 1;
122
123      Func<double, double> f;
124      Func<double, double> df;
125      switch (v) {
126        case 0:
127          f = (r) => 1.0;
128          df = (r) => 0.0;
129          break;
130        case 1:
131          f = (r) => 1 + (exp + 1) * r;
132          df = (r) => exp + 1;
133          break;
134        case 2:
135          f = (r) => 1 + (exp + 2) * r + (exp * exp + 4.0 * exp + 3) / 3.0 * r * r;
136          df = (r) => (exp + 2) + 2 * (exp * exp + 4.0 * exp + 3) / 3.0 * r;
137          break;
138        case 3:
139          f = (r) => 1 + (exp + 3) * r + (6.0 * exp * exp + 36 * exp + 45) / 15.0 * r * r +
140                     (exp * exp * exp + 9 * exp * exp + 23 * exp + 45) / 15.0 * r * r * r;
141          df = (r) => (exp + 3) + 2 * (6.0 * exp * exp + 36 * exp + 45) / 15.0 * r +
142                      (exp * exp * exp + 9 * exp * exp + 23 * exp + 45) / 5.0 * r * r;
143          break;
144        default: throw new ArgumentException();
145      }
146
147      // create functions
148      var cov = new ParameterizedCovarianceFunction();
149      cov.Covariance = (x, i, j) => {
150        double k = Math.Sqrt(Util.SqrDist(x, i, x, j, columnIndices, 1.0 / length));
151        return scale * Math.Pow(Math.Max(1 - k, 0), exp + v) * f(k);
152      };
153      cov.CrossCovariance = (x, xt, i, j) => {
154        double k = Math.Sqrt(Util.SqrDist(x, i, xt, j, columnIndices, 1.0 / length));
155        return scale * Math.Pow(Math.Max(1 - k, 0), exp + v) * f(k);
156      };
157      cov.CovarianceGradient = (x, i, j) => GetGradient(x, i, j, length, scale, v, exp, f, df, columnIndices, fixedLength, fixedScale);
158      return cov;
159    }
160
161    private static IEnumerable<double> GetGradient(double[,] x, int i, int j, double length, double scale, int v, double exp, Func<double, double> f, Func<double, double> df, int[] columnIndices,
162      bool fixedLength, bool fixedScale) {
163      double k = Math.Sqrt(Util.SqrDist(x, i, x, j, columnIndices, 1.0 / length));
164      if (!fixedLength) yield return scale * Math.Pow(Math.Max(1.0 - k, 0), exp + v - 1) * k * ((exp + v) * f(k) - Math.Max(1 - k, 0) * df(k));
165      if (!fixedScale) yield return 2.0 * scale * Math.Pow(Math.Max(1 - k, 0), exp + v) * f(k);
166    }
167  }
168}
Note: See TracBrowser for help on using the repository browser.