Commit 1d8a0519 authored by BLANCHARD Pierre's avatar BLANCHARD Pierre

HMat: Provide new geometry, new distance and Gaussian covariance (+ associated...

HMat: Provide new geometry, new distance and Gaussian covariance (+ associated matrix kernel); Resulting matrix has low rank off diagonal blocks (can be checked using testCompareClusteringRank).
parent 8669add6
......@@ -22,6 +22,7 @@
#include "Utils/FParameterNames.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp" // for kernel matrices
#include "Kernels/Interpolation/FInterpMatrixKernel_Covariance.hpp" // for kernel matrices
// not mandatory but useful to define some flags
#include "Core/FFmmAlgorithm.hpp"
......@@ -104,9 +105,12 @@ int main(int argc, char* argv[])
/// Build kernel matrix K
// Interaction kernel evaluator
typedef FInterpMatrixKernelR<FReal> MatrixKernelClass;
const MatrixKernelClass MatrixKernel;
const std::string MatrixKernelID = MatrixKernelClass::getID();//.c_str();
//typedef FInterpMatrixKernelR<FReal> MatrixKernelClass;
typedef CK_Gauss<FReal> MatrixKernelClass;
const FReal lengthScale = FReal(0.01)*FParameters::getValue(argc,argv,"-lengthscale", FReal(100.));
std::ostringstream oss; oss << 100*lengthScale;
const MatrixKernelClass MatrixKernel(lengthScale);
const std::string MatrixKernelID = MatrixKernelClass::getID() + oss.str() ;//.c_str();
// Allocate memory
FReal* K = new FReal[matrixSize*matrixSize];
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// This software is a computer program whose purpose is to compute the FMM.
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// GNU General Public and CeCILL-C Licenses for more details.
// "".
// "".
// ===================================================================================
#include <stdlib.h>
#include <math.h> // for exp
// ScalFMM includes
#include "Utils/FNoCopyable.hpp"
#include "Utils/FMath.hpp"
#include "Utils/FPoint.hpp"
// for identifiers and types
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
* @author Pierre Blanchard (
* @date March 13th, 2014
// not extendable
// bounded support correlation functions:
// * power model
// hole effect correlation (nonstrictly decreasing)
// Whittle model? (slow decay => important constraint on size of grid / length)
template <class FReal>
struct AbstractCorrelationKernel : FNoCopyable
virtual ~AbstractCorrelationKernel(){}
virtual FReal evaluate(const FReal*, const FReal*) const = 0;
* The following classes provide the evaluators for the correlation function listed below:
* TODO Exponential decay (Matern for $\nu=1/2$): not smooth AT ALL, actually very rough. Application to Brownian motion.
* Gaussian decay (Matern for $\nu=\infty$): infinitely smooth
* TODO Spherical correlation: not smooth AT ALL, but FINITE support! It is proportionnal to the intersecting area
* of 2 disks of radius $\ell$ whose centers are separated from $r$.
* TODO Explicit version of Matern for $\nu=3/2$ and $\nu=5/2$ (application to machine learning)
* Smaller values of $\nu$ lead to rough behaviours (already covered by exponential)
* while larger $\nu$ ($\leq 7/2$) are hard to differentiate from the Gaussian decay.
* TODO Generic Matern for an arbitrary $\nu$ (evaluator involve Bessel functions and spectral density involves Gamma functions)
* @tparam NAME description \f$latex symbol\f$
/// Generic Gaussian correlation function
/// Special case of Matern function with $\nu \rightarrow \infty$
template<class FReal>
struct CK_Gauss : AbstractCorrelationKernel<FReal>
static const unsigned int NCMP = 1; //< number of components
static const unsigned int NPV = 1; //< dim of physical values
static const unsigned int NPOT = 1; //< dim of potentials
static const unsigned int NRHS = 1; //< dim of mult exp
static const unsigned int NLHS = 1; //< dim of loc exp
FReal lengthScale_;
CK_Gauss(const FReal lengthScale = FReal(1.))
: lengthScale_(lengthScale)
std::cout<< "Gaussian " << 3 <<"D"
<< ", i.e. r(x)=exp(-0.5*(x_i/l*x_i/l)) with l="
<< lengthScale_ << "." ;
// copy ctor
CK_Gauss(const CK_Gauss& other)
: lengthScale_(other.lengthScale_)
// ID accessor
static const char* getID() { return "GAUSS"; }
* r(x)=exp(-(|x|/l)^2)
FReal evaluate(const FReal* x, const FReal* y) const
FReal dist2 = FReal(0.0);
for(int d=0; d<3; ++d){
FReal distX = FMath::Abs(x[d]-y[d]) / lengthScale_;
dist2 += distX*distX;
FReal res = FMath::Exp(FReal(-0.5)*dist2);
return res;
// evaluate interaction
template <class ValueClass>
ValueClass evaluate(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2) const
const ValueClass diff[3] = {(x1-x2),(y1-y2),(z1-z2)};
ValueClass dist2 = FMath::Zero<ValueClass>();
for(int d=0; d<3; ++d){
const ValueClass distX = diff[d] / FMath::ConvertTo<ValueClass,FReal>(lengthScale_);
dist2 += distX*distX;
// TODO AVX???
return FMath::Exp(-FReal(0.5)*dist2);
// evaluate interaction (blockwise)
template <class ValueClass>
void evaluateBlock(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2, ValueClass* block) const
// evaluate interaction and derivative (blockwise)
template <class ValueClass>
void evaluateBlockAndDerivative(const ValueClass& x1, const ValueClass& y1, const ValueClass& z1,
const ValueClass& x2, const ValueClass& y2, const ValueClass& z2,
ValueClass block[1], ValueClass blockDerivative[3]) const
// derivative not needed
blockDerivative[0] = FMath::Zero<ValueClass>();
blockDerivative[1] = FMath::Zero<ValueClass>();
blockDerivative[2] = FMath::Zero<ValueClass>();
* scaling (for ScalFMM)
FReal getScaleFactor(const FReal, const int) const
// return 1 because non homogeneous kernel functions cannot be scaled!!!
return FReal(1.);
FReal getScaleFactor(const FReal) const
// return 1 because non homogeneous kernel functions cannot be scaled!!!
return FReal(1.);
// returns position in reduced storage
int getPosition(const unsigned int) const
{return 0;}
FReal evaluate(const FPoint<FReal>& p1, const FPoint<FReal>& p2) const{
return evaluate<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ());
void evaluateBlock(const FPoint<FReal>& p1, const FPoint<FReal>& p2, FReal* block) const{
evaluateBlock<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block);
void evaluateBlockAndDerivative(const FPoint<FReal>& p1, const FPoint<FReal>& p2,
FReal block[1], FReal blockDerivative[3]) const {
evaluateBlockAndDerivative<FReal>(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ(), block, blockDerivative);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment