NiHu  2.0
covariance_kernel.hpp
Go to the documentation of this file.
1 // This file is a part of NiHu, a C++ BEM template library.
2 //
3 // Copyright (C) 2012-2015 Peter Fiala <fiala@hit.bme.hu>
4 // Copyright (C) 2012-2015 Peter Rucz <rucz@hit.bme.hu>
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
29 #ifndef COVARIANCE_KERNEL_HPP_INCLUDED
30 #define COVARIANCE_KERNEL_HPP_INCLUDED
31 
32 #include "../core/field_dimension.hpp"
33 #include "../core/global_definitions.hpp"
34 #include "../core/kernel.hpp"
35 #include "../core/gaussian_quadrature.hpp"
36 #include "location_normal.hpp"
37 
38 namespace NiHu
39 {
40 
41 template <class Space, class Dimension>
43 
45 namespace kernel_traits_ns
46 {
47  template <class Space, class Dimension>
48  struct space<exponential_covariance_kernel<Space, Dimension> > : Space {};
49 
50  template<class Space, class Dimension>
51  struct result<exponential_covariance_kernel<Space, Dimension> >
52  {
53  typedef Eigen::Matrix<typename Space::scalar_t, Dimension::value, Dimension::value> type;
54  };
55 
56  template <class Space, class Dimension>
58 
59  template <class Space, class Dimension>
60  struct is_singular<exponential_covariance_kernel<Space, Dimension> > : std::false_type {};
61 
62  template <class Space, class Dimension>
63  struct test_input<exponential_covariance_kernel<Space, Dimension> >
64  {
66  };
67 
68  template <class Space, class Dimension>
69  struct trial_input<exponential_covariance_kernel<Space, Dimension> >
70  {
72  };
73 
74  template <class Space, class Dimension>
75  struct is_symmetric<exponential_covariance_kernel<Space, Dimension> > : std::true_type {};
76 
78  template <class Space, class Dimension>
80 }
81 
82 
83 template <class Space, class Dimension>
85  public kernel_base<exponential_covariance_kernel<Space, Dimension> >
86 {
87 public:
89  typedef typename base_t::test_input_t test_input_t;
90  typedef typename base_t::trial_input_t trial_input_t;
91  typedef typename base_t::space_t space_t;
92  typedef typename space_t::scalar_t distance_t;
93  typedef typename base_t::result_t result_t;
94  typedef typename base_t::x_t location_t;
95  typedef Dimension dimension_t;
96  size_t static const field_dimension = dimension_t::value;
97  typedef Eigen::Matrix<double, field_dimension, field_dimension> field_variance_t;
98 
99  exponential_covariance_kernel(field_variance_t const &variance, double length) :
100  m_field_variance(variance), m_length(length)
101  {
102  }
103 
104  static distance_t distance(location_t const &x, location_t const &y)
105  {
106  return (x-y).norm();
107  }
108 
109  static distance_t distance_sph(location_t const &x, location_t const &y)
110  {
111  result_t v = x.normalized().dot(y.normalized());
112  v = std::min(v, 1.0);
113  v = std::max(v, -1.0);
114  return std::acos(v);
115  }
116 
117  result_t operator()(location_t const &x, location_t const &y) const
118  {
119  auto r = distance(x, y);
120  return get_variance() * std::exp(-r / get_correlation_length());
121  }
122 
123  result_t operator()(
124  test_input_t const &x,
125  trial_input_t const &y) const
126  {
127  return (*this)(x.get_x(), y.get_x());
128  }
129 
130  field_variance_t const &get_variance(void) const
131  {
132  return m_field_variance;
133  }
134 
135  double get_correlation_length(void) const
136  {
137  return m_length;
138  }
139 
140 private:
141  field_variance_t m_field_variance;
142  double m_length;
143 };
144 
145 
146 
147 template <class Space, class Dimension>
149 
151 namespace kernel_traits_ns
152 {
153 template <class Space, class Dimension>
154 struct space<gaussian_covariance_kernel<Space, Dimension> > : Space {};
155 
156 template<class Space, class Dimension>
157 struct result<gaussian_covariance_kernel<Space, Dimension> >
158 {
159  typedef Eigen::Matrix<typename Space::scalar_t, Dimension::value, Dimension::value> type;
160 };
161 
162 #if 0
163 // Specialisation
164 template<class Space>
165 struct result<gaussian_covariance_kernel<Space, field_dimension::_1d> >
166 {
167  typedef typename Space::scalar_t type;
168 };
169 #endif
170 
171 template <class Space, class Dimension>
173 
174 template <class Space, class Dimension>
175 struct is_singular<gaussian_covariance_kernel<Space, Dimension> > : std::false_type {};
176 
177 template <class Space, class Dimension>
178 struct test_input<gaussian_covariance_kernel<Space, Dimension> >
179 {
180  typedef location_input<Space> type;
181 };
182 
183 template <class Space, class Dimension>
184 struct trial_input<gaussian_covariance_kernel<Space, Dimension> >
185 {
186  typedef location_input<Space> type;
187 };
188 
189 template <class Space, class Dimension>
190 struct is_symmetric<gaussian_covariance_kernel<Space, Dimension> > : std::true_type {};
191 
193 template <class Space, class Dimension>
195 }
196 
197 template <class Space>
199 {
200 public:
201  typedef Space space_t;
202  typedef typename space_t::scalar_t scalar_t;
203  static size_t const space_dimension = Space::dimension;
204  typedef typename space_t::location_t location_t;
205 
206  typedef Eigen::Matrix<scalar_t, space_dimension, space_dimension> result_t;
207 
208  ConstVariance(result_t const &variance)
209  : m_variance(variance)
210  {
211  }
212 
213  result_t const &get_variance(location_t const&) const
214  {
215  return m_variance;
216  }
217 
218 private:
219  result_t m_variance;
220 };
221 
222 template <class Space, class Dimension>
224  public kernel_base<gaussian_covariance_kernel<Space, Dimension> >
225 {
226 public:
228  typedef typename base_t::test_input_t test_input_t;
229  typedef typename base_t::trial_input_t trial_input_t;
230  typedef typename base_t::space_t space_t;
231  typedef typename space_t::scalar_t distance_t;
232  typedef typename base_t::result_t result_t;
233  typedef typename base_t::x_t location_t;
234  typedef Dimension dimension_t;
235  size_t static const field_dimension = dimension_t::value;
236  size_t static const space_dimension = Space::dimension;
237  typedef Eigen::Matrix<double, space_dimension, space_dimension> space_variance_t;
238  typedef Eigen::Matrix<double, field_dimension, field_dimension> field_variance_t;
239 
241  field_variance_t const &field_variance,
242  space_variance_t const &space_variance
243  )
244  : m_field_variance(field_variance)
245  , m_space_variance(space_variance)
246  , m_inv_space_variance(m_space_variance.inverse())
247  {
248  }
249 
250  result_t operator()(location_t const &x, location_t const &y) const
251  {
252  location_t d = x - y;
253  double Q = d.transpose() * m_inv_space_variance * d;
254  return get_field_variance() * std::exp(-Q);
255  }
256 
257  result_t operator()(
258  test_input_t const &x,
259  trial_input_t const &y) const
260  {
261  return (*this)(x.get_x(), y.get_x());
262  }
263 
264  field_variance_t const &get_field_variance(void) const
265  {
266  return m_field_variance;
267  }
268 
269  space_variance_t const &get_space_variance(void) const
270  {
271  return m_space_variance;
272  }
273 
274 private:
275  field_variance_t m_field_variance;
276  space_variance_t m_space_variance;
277  space_variance_t m_inv_space_variance;
278 };
279 
280 #if 0
281 // NOTE: NON-STATIONARY STARTED HERE
282 
283 template <class SpaceVariance, class FieldVariance>
284 class gaussian_covariance_kernel;
285 
287 namespace kernel_traits_ns
288 {
289 template <class SpaceVariance, class FieldVariance>
290 struct space<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > : typename SpaceVariance::space_t {};
291 
292 template<class SpaceVariance, class FieldVariance>
293 struct result<gaussian_covariance_kernel<SpaceVariance, FieldVariance> >
294 {
295  typedef FieldVariance::result_t type;
296 };
297 
298 template <class SpaceVariance, class FieldVariance>
299 struct quadrature_family<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > : gauss_family_tag {};
300 
301 template <class SpaceVariance, class FieldVariance>
302 struct is_singular<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > : std::false_type {};
303 
304 template <class SpaceVariance, class FieldVariance>
305 struct test_input<gaussian_covariance_kernel<SpaceVariance, FieldVariance> >
306 {
307  typedef location_input<typename SpaceVariance::space_t> type;
308 };
309 
310 template <class SpaceVariance, class FieldVariance>
311 struct trial_input<gaussian_covariance_kernel<SpaceVariance, FieldVariance> >
312 {
313  typedef location_input<typename SpaceVariance::space_t> type;
314 };
315 
316 template <class SpaceVariance, class FieldVariance>
317 struct is_symmetric<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > : std::true_type {};
318 
320 template <class SpaceVariance, class FieldVariance>
321 struct far_field_behaviour<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > : asymptotic::inverse<1> {};
322 } // end of NiHu::kernel_traits_ns
323 
324 template <class SpaceVariance, class FieldVariance>
325 class gaussian_covariance_kernel :
326  public kernel_base<gaussian_covariance_kernel<SpaceVariance, FieldVariance> >
327 {
328  typedef SpaceVariance space_variance_t;
329  typedef FieldVariance field_variance_t;
330 
331  typedef kernel_base<gaussian_covariance_kernel<SpaceVariance, FieldVariance> > base_t;
332  typedef typename base_t::test_input_t test_input_t;
333  typedef typename base_t::trial_input_t trial_input_t;
334 
335  typedef typename field_variance_t::result_t field_var_t;
336  typedef typename space_variance_t::result_t space_var_t;
337 
338  gaussian_covariance_kernel(field_variance_t const &fvar, space_variance_t const &svar)
339  : m_field_variance(fvar)
340  , m_space_variance(svar)
341  {
342  }
343 
344  result_t operator()(location_t const &x, location_t const &y) const
345  {
346  location_t d = x - y;
347  space_variance_t svar_x = get_space_variance(x);
348  space_variance_t svar_y = get_space_variance(y);
349  field_variance_t fvar = get_field_variance(x);
350 
351  space_variance_t svar = .5 * (svar_x + svar_y);
352  double Q = d.transpose() * svar.inverse() * d;
353  double scale = std::pow(svar_x.determinant(), .25) * std::pow(svar_y.determinant(), .25) / std::sqrt(svar.determinant());
354 
355  return fvar * scale * std::exp(-Q);
356  }
357 
358  field_var_t get_field_variance(location_t const &x) const
359  {
360  return m_field_variance.get_variance(x);
361  }
362 
363  space_var_t get_space_variance(location_t const &x) const
364  {
365  return m_space_variance.get_variance(x);
366  }
367 
368  result_t operator()(
369  test_input_t const &x,
370  trial_input_t const &y) const
371  {
372  return (*this)(x.get_x(), y.get_x());
373  }
374 
375 private:
376  space_variance_t m_space_variance;
377  field_variance_t m_field_variance;
378 };
379 // NOTE: NON-STATIONARY ENDS HERE
380 #endif
381 
382 } // end of namespace NiHu
383 
384 #endif // COVARIANCE_KERNEL_HPP_INCLUDED
NiHu::function_space_view
A mesh extended with a Field generating option.
Definition: function_space.hpp:116
NiHu::kernel_traits_ns::result
return the kernel's result type
Definition: kernel.hpp:47
NiHu::exponential_covariance_kernel
Definition: covariance_kernel.hpp:42
NiHu::kernel_traits_ns::is_singular
return whether the kernel is singular or not
Definition: kernel.hpp:56
NiHu::kernel_base
CRTP base class of all BEM kernels.
Definition: kernel.hpp:133
NiHu::kernel_traits_ns::far_field_behaviour
return the far field asymptotic behaviour of the kernel
Definition: kernel.hpp:51
NiHu::kernel_traits_ns::is_symmetric
return whether the kernel is symmetric or not
Definition: kernel.hpp:54
NiHu::ConstVariance
Definition: covariance_kernel.hpp:198
NiHu::asymptotic::inverse
inverse singularity with specified order
Definition: asymptotic_types.hpp:50
NiHu::kernel_traits_ns::quadrature_family
return the quadrature family the kernel is integrated with
Definition: kernel.hpp:49
NiHu::kernel_base::trial_input_t
traits_t::trial_input_t trial_input_t
type of the second (trial) kernel input
Definition: kernel.hpp:144
NiHu::kernel_base::test_input_t
traits_t::test_input_t test_input_t
type of the first (test) kernel input
Definition: kernel.hpp:142
NiHu::kernel_traits_ns::trial_input
return the kernel's trial input
Definition: kernel.hpp:45
NiHu::kernel_base::space_t
test_input_t::space_t space_t
type of the kernel's domain space
Definition: kernel.hpp:152
location_normal.hpp
implementation of location and normal kernel inputs
NiHu::kernel_traits_ns::space
return the coordinate space where the kernel is defined
Definition: kernel.hpp:41
NiHu::kernel_base::result_t
traits_t::result_t result_t
compile time check if the two kernel inputs are compatible
Definition: kernel.hpp:147
NiHu::gaussian_covariance_kernel
Definition: covariance_kernel.hpp:148
NiHu::kernel_traits_ns::test_input
return the kernel's test input
Definition: kernel.hpp:43
NiHu::location_input
a class representing a simple location
Definition: location_normal.hpp:37
NiHu::kernel_base::x_t
space_t::location_t x_t
type of a location vector in the kernel's domain
Definition: kernel.hpp:154
NiHu::gauss_family_tag
tag for the family of Gaussian quadratures
Definition: gaussian_quadrature.hpp:517