Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovariancePeriodic.cs @ 8455

Last change on this file since 8455 was 8455, checked in by gkronber, 12 years ago

#1902 changed calculation of gradients for covariance functions to reduce allocations of arrays

File size: 5.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2012 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 HeuristicLab.Common;
24using HeuristicLab.Core;
25using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
26
27namespace HeuristicLab.Algorithms.DataAnalysis {
28  [StorableClass]
29  [Item(Name = "CovariancePeriodic", Description = "Periodic covariance function for Gaussian processes.")]
30  public class CovariancePeriodic : Item, ICovarianceFunction {
31    [Storable]
32    private double[,] x;
33    [Storable]
34    private double[,] xt;
35    [Storable]
36    private double sf2;
37    [Storable]
38    private double l;
39    [Storable]
40    private double p;
41
42    private bool symmetric;
43
44    private double[,] sd;
45    public int GetNumberOfParameters(int numberOfVariables) {
46      return 3;
47    }
48    [StorableConstructor]
49    protected CovariancePeriodic(bool deserializing) : base(deserializing) { }
50    protected CovariancePeriodic(CovariancePeriodic original, Cloner cloner)
51      : base(original, cloner) {
52      if (original.x != null) {
53        x = new double[original.x.GetLength(0), original.x.GetLength(1)];
54        Array.Copy(original.x, x, x.Length);
55        xt = new double[original.xt.GetLength(0), original.xt.GetLength(1)];
56        Array.Copy(original.xt, xt, xt.Length);
57      }
58      sf2 = original.sf2;
59      l = original.l;
60      p = original.p;
61      symmetric = original.symmetric;
62    }
63    public CovariancePeriodic()
64      : base() {
65    }
66
67    public override IDeepCloneable Clone(Cloner cloner) {
68      return new CovariancePeriodic(this, cloner);
69    }
70
71    public void SetParameter(double[] hyp) {
72      if (hyp.Length != 3) throw new ArgumentException();
73      this.l = Math.Exp(hyp[0]);
74      this.p = Math.Exp(hyp[1]);
75      this.sf2 = Math.Exp(2 * hyp[2]);
76
77      sf2 = Math.Min(10E6, sf2); // upper limit for the scale
78
79      sd = null;
80    }
81    public void SetData(double[,] x) {
82      SetData(x, x);
83      this.symmetric = true;
84    }
85
86    public void SetData(double[,] x, double[,] xt) {
87      this.x = x;
88      this.xt = xt;
89      this.symmetric = false;
90
91      sd = null;
92    }
93
94    public double GetCovariance(int i, int j) {
95      if (sd == null) CalculateSquaredDistances();
96      double k = sd[i, j];
97      k = Math.PI * k / p;
98      k = Math.Sin(k) / l;
99      k = k * k;
100
101      return sf2 * Math.Exp(-2.0 * k);
102    }
103
104
105    public double[] GetDiagonalCovariances() {
106      if (x != xt) throw new InvalidOperationException();
107      int rows = x.GetLength(0);
108      var cov = new double[rows];
109      for (int i = 0; i < rows; i++) {
110        double k = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(xt, i)));
111        k = Math.PI * k / p;
112        k = Math.Sin(k) / l;
113        k = k * k;
114        cov[i] = sf2 * Math.Exp(-2.0 * k);
115      }
116      return cov;
117    }
118
119    public double GetGradient(int i, int j, int k) {
120      double v = Math.PI * sd[i, j] / p;
121      switch (k) {
122        case 0: {
123            double newK = Math.Sin(v) / l;
124            newK = newK * newK;
125            return 4 * sf2 * Math.Exp(-2 * newK) * newK;
126          }
127        case 1: {
128            double r = Math.Sin(v) / l;
129            return 4 * sf2 / l * Math.Exp(-2 * r * r) * r * Math.Cos(v) * v;
130          }
131        case 2: {
132            double newK = Math.Sin(v) / l;
133            newK = newK * newK;
134            return 2 * sf2 * Math.Exp(-2 * newK);
135
136          }
137        default: {
138            throw new ArgumentException("CovariancePeriodic only has three hyperparameters.", "k");
139          }
140      }
141    }
142
143    private void CalculateSquaredDistances() {
144      if (x.GetLength(1) != xt.GetLength(1)) throw new InvalidOperationException();
145      int rows = x.GetLength(0);
146      int cols = xt.GetLength(0);
147      sd = new double[rows, cols];
148
149      if (symmetric) {
150        for (int i = 0; i < rows; i++) {
151          for (int j = i; j < cols; j++) {
152            sd[i, j] = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(x, j)));
153            sd[j, i] = sd[i, j];
154          }
155        }
156      } else {
157        for (int i = 0; i < rows; i++) {
158          for (int j = 0; j < cols; j++) {
159            sd[i, j] = Math.Sqrt(Util.SqrDist(Util.GetRow(x, i), Util.GetRow(xt, j)));
160          }
161        }
162      }
163    }
164  }
165}
Note: See TracBrowser for help on using the repository browser.