Kernel.hpp
Go to the documentation of this file.
1 /*
2  * STRUMPACK -- STRUctured Matrices PACKage, Copyright (c) 2014, The
3  * Regents of the University of California, through Lawrence Berkeley
4  * National Laboratory (subject to receipt of any required approvals
5  * from the U.S. Dept. of Energy). All rights reserved.
6  *
7  * If you have questions about your rights to use or distribute this
8  * software, please contact Berkeley Lab's Technology Transfer
9  * Department at TTD@lbl.gov.
10  *
11  * NOTICE. This software is owned by the U.S. Department of Energy. As
12  * such, the U.S. Government has been granted for itself and others
13  * acting on its behalf a paid-up, nonexclusive, irrevocable,
14  * worldwide license in the Software to reproduce, prepare derivative
15  * works, and perform publicly and display publicly. Beginning five
16  * (5) years after the date permission to assert copyright is obtained
17  * from the U.S. Department of Energy, and subject to any subsequent
18  * five (5) year renewals, the U.S. Government is granted for itself
19  * and others acting on its behalf a paid-up, nonexclusive,
20  * irrevocable, worldwide license in the Software to reproduce,
21  * prepare derivative works, distribute copies to the public, perform
22  * publicly and display publicly, and to permit others to do so.
23  *
24  * Developers: Pieter Ghysels, Francois-Henry Rouet, Xiaoye S. Li.
25  * (Lawrence Berkeley National Lab, Computational Research
26  * Division).
27  *
28  */
36 #ifndef STRUMPACK_KERNEL_HPP
37 #define STRUMPACK_KERNEL_HPP
38 
39 #include "Metrics.hpp"
40 #include "HSS/HSSOptions.hpp"
41 #include "dense/DenseMatrix.hpp"
42 #if defined(STRUMPACK_USE_MPI)
43 #include "dense/DistributedMatrix.hpp"
44 #if defined(STRUMPACK_USE_BPACK)
45 #include "HODLR/HODLROptions.hpp"
46 #endif
47 #endif
48 
49 namespace strumpack {
50 
54  namespace kernel {
55 
73  template<typename scalar_t> class Kernel {
74  using real_t = typename RealType<scalar_t>::value_type;
77 #if defined(STRUMPACK_USE_MPI)
79 #endif
80 
81  public:
92  Kernel(DenseM_t& data, scalar_t lambda)
93  : data_(data), lambda_(lambda) { }
94 
98  virtual ~Kernel() = default;
99 
106  std::size_t n() const { return data_.cols(); }
107 
113  std::size_t d() const { return data_.rows(); }
114 
122  virtual scalar_t eval(std::size_t i, std::size_t j) const {
123  return eval_kernel_function(data_.ptr(0, i), data_.ptr(0, j))
124  + ((i == j) ? lambda_ : scalar_t(0.));
125  }
126 
138  void operator()(const std::vector<std::size_t>& I,
139  const std::vector<std::size_t>& J,
140  DenseMatrix<real_t>& B) const {
141  assert(B.rows() == I.size() && B.cols() == J.size());
142  for (std::size_t j=0; j<J.size(); j++)
143  for (std::size_t i=0; i<I.size(); i++) {
144  assert(I[i] < n() && J[j] < n());
145  B(i, j) = eval(I[i], J[j]);
146  }
147  }
148 
160  void operator()(const std::vector<std::size_t>& I,
161  const std::vector<std::size_t>& J,
162  DenseMatrix<std::complex<real_t>>& B) const {
163  assert(B.rows() == I.size() && B.cols() == J.size());
164  for (std::size_t j=0; j<J.size(); j++)
165  for (std::size_t i=0; i<I.size(); i++) {
166  assert(I[i] < n() && J[j] < n());
167  B(i, j) = eval(I[i], J[j]);
168  }
169  }
170 
190  (std::vector<scalar_t>& labels, const HSS::HSSOptions<scalar_t>& opts);
191 
203  std::vector<scalar_t> predict
204  (const DenseM_t& test, const DenseM_t& weights) const;
205 
206 #if defined(STRUMPACK_USE_MPI)
228  (const BLACSGrid& grid, std::vector<scalar_t>& labels,
229  const HSS::HSSOptions<scalar_t>& opts);
230 
242  std::vector<scalar_t> predict
243  (const DenseM_t& test, const DistM_t& weights) const;
244 
245 #if defined(STRUMPACK_USE_BPACK)
265  (const MPIComm& c, std::vector<scalar_t>& labels,
266  const HODLR::HODLROptions<scalar_t>& opts);
267 #endif
268 #endif
269 
276  const DenseM_t& data() const { return data_; }
282  DenseM_t& data() { return data_; }
283 
284  std::vector<int>& permutation() { return perm_; }
285  const std::vector<int>& permutation() const { return perm_; }
286 
287  virtual void permute() {}
288 
289  protected:
290  DenseM_t& data_;
291  scalar_t lambda_;
292  std::vector<int> perm_;
293 
308  virtual scalar_t eval_kernel_function
309  (const scalar_t* x, const scalar_t* y) const = 0;
310  };
311 
312 
330  template<typename scalar_t>
331  class GaussKernel : public Kernel<scalar_t> {
332  public:
343  GaussKernel(DenseMatrix<scalar_t>& data, scalar_t h, scalar_t lambda)
344  : Kernel<scalar_t>(data, lambda), h_(h) {}
345 
346  protected:
347  scalar_t h_; // kernel width parameter
348 
349  scalar_t eval_kernel_function
350  (const scalar_t* x, const scalar_t* y) const override {
351  return std::exp
352  (-Euclidean_distance_squared(this->d(), x, y)
353  / (scalar_t(2.) * h_ * h_));
354  }
355  };
356 
357 
375  template<typename scalar_t>
376  class LaplaceKernel : public Kernel<scalar_t> {
377  public:
388  LaplaceKernel(DenseMatrix<scalar_t>& data, scalar_t h, scalar_t lambda)
389  : Kernel<scalar_t>(data, lambda), h_(h) {}
390 
391  protected:
392  scalar_t h_; // kernel width parameter
393 
394  scalar_t eval_kernel_function
395  (const scalar_t* x, const scalar_t* y) const override {
396  return std::exp(-norm1_distance(this->d(), x, y) / h_);
397  }
398  };
399 
421  template<typename scalar_t>
422  class ANOVAKernel : public Kernel<scalar_t> {
423  public:
436  (DenseMatrix<scalar_t>& data, scalar_t h, scalar_t lambda, int p=1)
437  : Kernel<scalar_t>(data, lambda), h_(h), p_(p) {
438  assert(p >= 1 && p <= int(this->d()));
439  }
440 
441  protected:
442  scalar_t h_; // kernel width parameter
443  int p_; // kernel degree parameter 1 <= p_ <= this->d()
444 
445  scalar_t eval_kernel_function
446  (const scalar_t* x, const scalar_t* y) const override {
447  std::vector<scalar_t> Ks(p_), Kss(p_), Kpp(p_+1);
448  Kpp[0] = 1;
449  for (int j=0; j<p_; j++) Kss[j] = 0;
450  for (std::size_t i=0; i<this->d(); i++) {
451  scalar_t tmp = std::exp
452  (-Euclidean_distance_squared(1, x+i, y+i)
453  / (scalar_t(2.) * h_ * h_));
454  Ks[0] = tmp;
455  Kss[0] += Ks[0];
456  for (int j=1; j<p_; j++) {
457  Ks[j] = Ks[j-1]*tmp;
458  Kss[j] += Ks[j];
459  }
460  }
461  for (int i=1; i<=p_; i++) {
462  Kpp[i] = 0;
463  for (int s=1; s<=i; s++)
464  Kpp[i] += std::pow(-1,s+1)*Kpp[i-s]*Kss[s-1];
465  Kpp[i] /= i;
466  }
467  return Kpp[p_];
468  }
469  };
470 
471 
483  template<typename scalar_t>
484  class DenseKernel : public Kernel<scalar_t> {
485  public:
497  DenseMatrix<scalar_t>& A, scalar_t lambda)
498  : Kernel<scalar_t>(data, lambda), A_(A) {}
499 
500  scalar_t eval(std::size_t i, std::size_t j) const override {
501  return A_(i, j) + ((i == j) ? this->lambda_ : scalar_t(0.));
502  }
503 
504  void permute() override {
505  A_.lapmt(this->perm_, true);
506  A_.lapmr(this->perm_, true);
507  }
508 
509  protected:
510  DenseMatrix<scalar_t>& A_; // kernel matrix
511 
512  scalar_t eval_kernel_function
513  (const scalar_t* x, const scalar_t* y) const override {
514  assert(false);
515  }
516  };
517 
518 
523  enum class KernelType {
524  DENSE,
525  GAUSS,
526  LAPLACE,
527  ANOVA
528  };
529 
533  inline std::string get_name(KernelType k) {
534  switch (k) {
535  case KernelType::DENSE: return "dense"; break;
536  case KernelType::GAUSS: return "Gauss"; break;
537  case KernelType::LAPLACE: return "Laplace"; break;
538  case KernelType::ANOVA: return "ANOVA"; break;
539  default: return "UNKNOWN";
540  }
541  }
542 
548  inline KernelType kernel_type(const std::string& k) {
549  if (k == "dense") return KernelType::DENSE;
550  else if (k == "Gauss") return KernelType::GAUSS;
551  else if (k == "Laplace") return KernelType::LAPLACE;
552  else if (k == "ANOVA") return KernelType::ANOVA;
553  std::cerr << "ERROR: Kernel type not recogonized, "
554  << " setting kernel type to Gauss."
555  << std::endl;
556  return KernelType::GAUSS;
557  }
558 
571  template<typename scalar_t>
572  std::unique_ptr<Kernel<scalar_t>> create_kernel
574  scalar_t h, scalar_t lambda, int p=1) {
575  switch (k) {
576  // case KernelType::DENSE:
577  // return std::unique_ptr<Kernel<scalar_t>>
578  // (new DenseKernel<scalar_t>(args ...));
579  case KernelType::GAUSS:
580  return std::unique_ptr<Kernel<scalar_t>>
581  (new GaussKernel<scalar_t>(data, h, lambda));
582  case KernelType::LAPLACE:
583  return std::unique_ptr<Kernel<scalar_t>>
584  (new LaplaceKernel<scalar_t>(data, h, lambda));
585  case KernelType::ANOVA:
586  return std::unique_ptr<Kernel<scalar_t>>
587  (new ANOVAKernel<scalar_t>(data, h, lambda, p));
588  default:
589  return std::unique_ptr<Kernel<scalar_t>>
590  (new GaussKernel<scalar_t>(data, h, lambda));
591  }
592  }
593 
594  } // end namespace kernel
595 
596 } // end namespace strumpack
597 
598 #endif // STRUMPACK_KERNEL_HPP
Contains the DenseMatrix and DenseMatrixWrapper classes, simple wrappers around BLAS/LAPACK style den...
Contains the class holding HODLR matrix options.
Contains the HSSOptions class as well as general routines for HSS options.
Definitions of distance metrics.
This is a small wrapper class around a BLACS grid and a BLACS context.
Definition: BLACSGrid.hpp:66
Like DenseMatrix, this class represents a matrix, stored in column major format, to allow direct use ...
Definition: DenseMatrix.hpp:1015
This class represents a matrix, stored in column major format, to allow direct use of BLAS/LAPACK rou...
Definition: DenseMatrix.hpp:138
std::size_t cols() const
Definition: DenseMatrix.hpp:230
const scalar_t * ptr(std::size_t i, std::size_t j) const
Definition: DenseMatrix.hpp:282
std::size_t rows() const
Definition: DenseMatrix.hpp:227
Definition: DistributedMatrix.hpp:52
Class containing several options for the HODLR code and data-structures.
Definition: HODLROptions.hpp:117
Class containing several options for the HSS code and data-structures.
Definition: HSSOptions.hpp:118
Wrapper class around an MPI_Comm object.
Definition: MPIWrapper.hpp:190
ANOVA kernel.
Definition: Kernel.hpp:422
ANOVAKernel(DenseMatrix< scalar_t > &data, scalar_t h, scalar_t lambda, int p=1)
Definition: Kernel.hpp:436
Arbitrary dense matrix, with underlying geometry.
Definition: Kernel.hpp:484
DenseKernel(DenseMatrix< scalar_t > &data, DenseMatrix< scalar_t > &A, scalar_t lambda)
Definition: Kernel.hpp:496
scalar_t eval(std::size_t i, std::size_t j) const override
Definition: Kernel.hpp:500
Gaussian or radial basis function kernel.
Definition: Kernel.hpp:331
GaussKernel(DenseMatrix< scalar_t > &data, scalar_t h, scalar_t lambda)
Definition: Kernel.hpp:343
Representation of a kernel matrix.
Definition: Kernel.hpp:73
virtual ~Kernel()=default
DenseM_t fit_HODLR(const MPIComm &c, std::vector< scalar_t > &labels, const HODLR::HODLROptions< scalar_t > &opts)
virtual scalar_t eval(std::size_t i, std::size_t j) const
Definition: Kernel.hpp:122
std::size_t n() const
Definition: Kernel.hpp:106
std::size_t d() const
Definition: Kernel.hpp:113
void operator()(const std::vector< std::size_t > &I, const std::vector< std::size_t > &J, DenseMatrix< std::complex< real_t >> &B) const
Definition: Kernel.hpp:160
DenseM_t & data()
Definition: Kernel.hpp:282
void operator()(const std::vector< std::size_t > &I, const std::vector< std::size_t > &J, DenseMatrix< real_t > &B) const
Definition: Kernel.hpp:138
DistM_t fit_HSS(const BLACSGrid &grid, std::vector< scalar_t > &labels, const HSS::HSSOptions< scalar_t > &opts)
const DenseM_t & data() const
Definition: Kernel.hpp:276
DenseM_t fit_HSS(std::vector< scalar_t > &labels, const HSS::HSSOptions< scalar_t > &opts)
Kernel(DenseM_t &data, scalar_t lambda)
Definition: Kernel.hpp:92
std::vector< scalar_t > predict(const DenseM_t &test, const DistM_t &weights) const
std::vector< scalar_t > predict(const DenseM_t &test, const DenseM_t &weights) const
Laplace kernel.
Definition: Kernel.hpp:376
LaplaceKernel(DenseMatrix< scalar_t > &data, scalar_t h, scalar_t lambda)
Definition: Kernel.hpp:388
std::string get_name(KernelType k)
Definition: Kernel.hpp:533
std::unique_ptr< Kernel< scalar_t > > create_kernel(KernelType k, DenseMatrix< scalar_t > &data, scalar_t h, scalar_t lambda, int p=1)
Definition: Kernel.hpp:573
KernelType
Definition: Kernel.hpp:523
KernelType kernel_type(const std::string &k)
Definition: Kernel.hpp:548
Definition: StrumpackOptions.hpp:42
real_t norm1_distance(std::size_t d, const scalar_t *x, const scalar_t *y)
Definition: Metrics.hpp:91
real_t Euclidean_distance_squared(std::size_t d, const scalar_t *x, const scalar_t *y)
Definition: Metrics.hpp:53