Statismo  0.10.1
 All Classes Namespaces Functions Typedefs
KernelCombinators.h
1 
13 #ifndef KERNELCOMBINATORS_H
14 #define KERNELCOMBINATORS_H
15 
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/thread/mutex.hpp>
18 #include <boost/unordered_map.hpp>
19 
20 #include "CommonTypes.h"
21 #include "Kernels.h"
22 #include "Nystrom.h"
23 #include "Representer.h"
24 
25 namespace statismo {
26 
30 template<class TPoint>
31 class SumKernel: public MatrixValuedKernel<TPoint> {
32  public:
33 
35 
36 
38  const MatrixValuedKernelType* rhs) :
40  m_lhs(lhs),
41  m_rhs(rhs) {
42  if (lhs->GetDimension() != rhs->GetDimension()) {
44  "Kernels in SumKernel must have the same dimensionality");
45  }
46  }
47 
48  MatrixType operator()(const TPoint& x, const TPoint& y) const {
49  return (*m_lhs)(x, y) + (*m_rhs)(x, y);
50  }
51 
52  std::string GetKernelInfo() const {
53  std::ostringstream os;
54  os << m_lhs->GetKernelInfo() << " + " << m_rhs->GetKernelInfo();
55  return os.str();
56  }
57 
58  private:
59  const MatrixValuedKernelType* m_lhs;
60  const MatrixValuedKernelType* m_rhs;
61 };
62 
63 
64 
69 template<class TPoint>
70 class ProductKernel: public MatrixValuedKernel<TPoint> {
71 
72  public:
73 
75 
77  const MatrixValuedKernelType* rhs) :
78  MatrixValuedKernelType(lhs->GetDimension()), m_lhs(lhs), m_rhs(
79  rhs) {
80  if (lhs->GetDimension() != rhs->GetDimension()) {
82  "Kernels in SumKernel must have the same dimensionality");
83  }
84 
85  }
86 
87  MatrixType operator()(const TPoint& x, const TPoint& y) const {
88  return (*m_lhs)(x, y) * (*m_rhs)(x, y);
89  }
90 
91  std::string GetKernelInfo() const {
92  std::ostringstream os;
93  os << m_lhs->GetKernelInfo() << " * " << m_rhs->GetKernelInfo();
94  return os.str();
95  }
96 
97  private:
98  const MatrixValuedKernelType* m_lhs;
99  const MatrixValuedKernelType* m_rhs;
100 };
101 
102 
107 template<class TPoint>
108 class ScaledKernel: public MatrixValuedKernel<TPoint> {
109  public:
110 
111 
113 
114 
115  ScaledKernel(const MatrixValuedKernelType* kernel,
116  double scalingFactor) :
117  MatrixValuedKernelType(kernel->GetDimension()), m_kernel(kernel), m_scalingFactor(scalingFactor) {
118  }
119 
120  MatrixType operator()(const TPoint& x, const TPoint& y) const {
121  return (*m_kernel)(x, y) * m_scalingFactor;
122  }
123  std::string GetKernelInfo() const {
124  std::ostringstream os;
125  os << (*m_kernel).GetKernelInfo() << " * " << m_scalingFactor;
126  return os.str();
127  }
128 
129  private:
130  const MatrixValuedKernelType* m_kernel;
131  double m_scalingFactor;
132 };
133 
134 
140 template<class TPoint>
142  public:
143 
145 
147  const ScalarValuedKernel<TPoint>* scalarKernel,
148  unsigned dimension) :
149  MatrixValuedKernelType( dimension), m_kernel(scalarKernel),
150  m_ident(MatrixType::Identity(dimension, dimension)) {
151  }
152 
153  MatrixType operator()(const TPoint& x, const TPoint& y) const {
154 
155  return m_ident * (*m_kernel)(x, y);
156  }
157 
158  virtual ~UncorrelatedMatrixValuedKernel() {
159  }
160 
161  std::string GetKernelInfo() const {
162  std::ostringstream os;
163  os << "UncorrelatedMatrixValuedKernel(" << (*m_kernel).GetKernelInfo()
164  << ", " << this->m_dimension << ")";
165  return os.str();
166  }
167 
168  private:
169 
170  const ScalarValuedKernel<TPoint>* m_kernel;
171  MatrixType m_ident;
172 
173 };
174 
175 
179 template <class TPoint>
181  public:
182  virtual double operator()(const TPoint& pt) const = 0;
183  virtual ~TemperingFunction() {}
184 };
185 
193 template<class T>
194 class SpatiallyVaryingKernel : public MatrixValuedKernel<typename Representer<T>::PointType> {
195 
196  typedef boost::unordered_map<statismo::VectorType, statismo::MatrixType> CacheType;
197 
198  public:
199 
200  typedef Representer<T> RepresenterType;
201  typedef typename RepresenterType::PointType PointType;
202 
203 
213  SpatiallyVaryingKernel(const RepresenterType* representer, const MatrixValuedKernel<PointType>& kernel, const TemperingFunction<PointType>& eta, unsigned numEigenfunctions, unsigned numberOfPointsForApproximation = 0, bool cacheValues = true)
214  : m_representer(representer),
215  m_eta(eta),
216  m_nystrom(Nystrom<T>::Create(representer, kernel, numEigenfunctions, numberOfPointsForApproximation == 0 ? numEigenfunctions * 2 : numberOfPointsForApproximation)),
217  m_eigenvalues(m_nystrom->getEigenvalues()),
218  m_cacheValues(cacheValues),
219  MatrixValuedKernel<PointType>(kernel.GetDimension()) {
220  }
221 
222  inline MatrixType operator()(const PointType& x, const PointType& y) const {
223 
224  MatrixType sum = MatrixType::Zero(this->m_dimension, this->m_dimension);
225 
226  float eta_x = m_eta(x);
227  float eta_y = m_eta(y);
228 
229 
230  statismo::MatrixType phisAtX = phiAtPoint(x);
231  statismo::MatrixType phisAtY = phiAtPoint(y);
232 
233  double largestTemperedEigenvalue = std::pow(m_eigenvalues(0), (eta_x + eta_y)/2);
234 
235  for (unsigned i = 0; i < m_eigenvalues.size(); ++i) {
236 
237  float temperedEigenvalue = std::pow(m_eigenvalues(i), (eta_x + eta_y)/2);
238 
239  // ignore too small eigenvalues, as they don't contribute much.
240  // (the eigenvalues are ordered, all the following are smaller and can also be ignored)
241  if (temperedEigenvalue / largestTemperedEigenvalue < 1e-6) {
242  break;
243  } else {
244  sum += phisAtX.col(i) * phisAtY.col(i).transpose() * temperedEigenvalue;
245  }
246  }
247  // normalize such that the largest eigenvalue is unaffected by the tempering
248  float normalizationFactor = largestTemperedEigenvalue / m_eigenvalues(0);
249  sum *= 1.0 / normalizationFactor;
250  return sum;
251  }
252 
253 
254  virtual ~SpatiallyVaryingKernel() {
255  }
256 
257  std::string GetKernelInfo() const {
258  std::ostringstream os;
259  os << "SpatiallyVaryingKernel";
260  return os.str();
261  }
262 
263 
264 
265 
266  private:
267 
268  // returns a d x n matrix holding the value of all n eigenfunctions evaluated at the given point.
269  const statismo::MatrixType phiAtPoint(const PointType& pt) const {
270 
271  statismo::MatrixType v;
272  if (m_cacheValues) {
273  // we need to convert the point to a vector, as the function hash_value (required by boost)
274  // is not defined for an arbitrary point.
275  const VectorType ptAsVec = this->m_representer->PointToVector(pt);
276  _phiCacheLock.lock();
277  typename CacheType::const_iterator got = m_phiCache.find (ptAsVec);
278  _phiCacheLock.unlock();
279  if (got == m_phiCache.end()) {
280  v = m_nystrom->computeEigenfunctionsAtPoint(pt);
281  _phiCacheLock.lock();
282  m_phiCache.insert(std::make_pair(ptAsVec, v));
283  _phiCacheLock.unlock();
284  } else {
285  v = got->second;
286  }
287  } else {
288  v = m_nystrom->computeEigenfunctionsAtPoint(pt);
289  }
290  return v;
291  }
292 
293 
294  //
295  // members
296 
297  const RepresenterType* m_representer;
298  boost::scoped_ptr<Nystrom<T> > m_nystrom;
299  statismo::VectorType m_eigenvalues;
300  const TemperingFunction<PointType>& m_eta;
301  bool m_cacheValues;
302  mutable CacheType m_phiCache;
303  mutable boost::mutex _phiCacheLock;
304 };
305 
306 
307 
308 }
309 
310 #endif // KERNELCOMBINATORS_H
Definition: KernelCombinators.h:194
Definition: Nystrom.h:30
virtual unsigned GetDimension() const
Definition: Kernels.h:82
Definition: KernelCombinators.h:70
Definition: Kernels.h:63
A trivial representer, that does no representation at all, but works directly with vectorial data...
Definition: TrivialVectorialRepresenter.h:83
std::string GetKernelInfo() const
Definition: KernelCombinators.h:257
virtual std::string GetKernelInfo() const =0
MatrixType operator()(const TPoint &x, const TPoint &y) const
Definition: KernelCombinators.h:87
Generic Exception class for the statismo Library.
Definition: Exceptions.h:68
MatrixType operator()(const TPoint &x, const TPoint &y) const
Definition: KernelCombinators.h:120
MatrixType operator()(const TPoint &x, const TPoint &y) const
Definition: KernelCombinators.h:153
Definition: KernelCombinators.h:141
SpatiallyVaryingKernel(const RepresenterType *representer, const MatrixValuedKernel< PointType > &kernel, const TemperingFunction< PointType > &eta, unsigned numEigenfunctions, unsigned numberOfPointsForApproximation=0, bool cacheValues=true)
Make a given kernel spatially varying according to the given tempering function.
Definition: KernelCombinators.h:213
MatrixType operator()(const TPoint &x, const TPoint &y) const
Definition: KernelCombinators.h:48
std::string GetKernelInfo() const
Definition: KernelCombinators.h:91
Definition: KernelCombinators.h:180
Definition: Kernels.h:35
std::string GetKernelInfo() const
Definition: KernelCombinators.h:123
std::string GetKernelInfo() const
Definition: KernelCombinators.h:52
Definition: KernelCombinators.h:108
std::string GetKernelInfo() const
Definition: KernelCombinators.h:161
Definition: KernelCombinators.h:31