laguerreTransform.h 4.53 KB
Newer Older
1 2
#ifndef LAGUERRETRANSFORM_SEEN
#define LAGUERRETRANSFORM_SEEN
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
/*
 *  This file is part of LagSHT.
 *
 *  LagSHT is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  LagSHT is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with libsharp; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 *  LagSHT is being developed at the Linear Accelerateur Laboratory (LAL)
 *  91898 ORSAY CEDEX - FRANCE
 *  main author: J.E Campagne
 */


28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#include <complex>

#include "laguerreBuilder.h"


namespace LagSHT {
class BaseLaguerreTransform {
 public:
  //! Creator
  BaseLaguerreTransform(int n, int alpha=2): N_(n), alpha_(alpha) {}
  //! Destructor
  virtual ~BaseLaguerreTransform() {}
  //! Getters
  int GetOrder() { return N_; }
  int GetAlpha() { return alpha_;}

protected:
  int N_; //!< Order of the Generalized Lagurerre polynomial
  int alpha_;  //!< second parameter of the generalized Laguerre polynomial 

};//BaseLaguerreTransform


///////////////////////////////////////////////////////////////////////
//// ------------------- Class LaguerreTransform   ----------------- //
//// Perform single or multiple 1D-Laguerre Transform and Inverse    //
//// using generalized Laguerre Polynomials except for T:double      //
//// where in this case the generalized Laguerre functions are used  //
///////////////////////////////////////////////////////////////////////
//! Laguerre Transform Syntheis/Analysis
class LaguerreTransform : public BaseLaguerreTransform {
 public:
  //! Creator
61
  LaguerreTransform(int N, r_8 R, int alpha=2, bool R2tau=true);
62 63 64 65
  //! Destructor
  virtual ~LaguerreTransform() {}

  //! Getters
66 67
  vector<r_8> GetNodes()   const { return nodes_; }
  vector<r_8> GetWeights() const { return weights_; }
68
  r_8         GetTau()     const { return tau_; }
69

70 71 72 73
  //! Find the closest nodes: no boundchecking
  int R2Index(r_8 r) const;
  //! return the nodes position: no boundchecking
  r_8 Index2R(int k) const { 
74 75 76
    //    return nodes_[k]*R_/nodes_[N_-1];
    //JEC 22/9/15
    return nodes_[k]*tau_;
77 78 79
  }
  
  
80 81 82 83 84 85 86 87 88 89 90


  //! Multi Analysis at once (Values -> Coefficients)
  /*!
    \param fi: values f(r_i) with r_i zero L^(alpha)_N
    \param fn : result
    \param stride : step between 2 conscecutive bunches of fi & fn 
  */
  void MultiAnalysis(const vector< complex<r_8> >& fi, vector< complex<r_8> >& fn, int stride);


91 92 93 94 95 96 97 98 99 100 101

  //! Multi Analysis at once (Values -> Coefficients)
  /*!
    \param fi: values f(r_i) with r_i zero L^(alpha)_N (Real case)
    \param fn : result
    \param stride : step between 2 conscecutive bunches of fi & fn 
  */
  void MultiAnalysisR(const vector<r_8>& fi, vector<r_8>& fn, int stride);



102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
  //! Multiple Synthesis at once (Coefficientss -> Values)
  /*!
  \param fn: (input) complex coefficients of Laguerre Transform
  \param stride: (input) is the size of the non-radial dimension (eg. Y"lm" index range size = number of alm)
  \param fi: (output) complex values of the Inverse Laguerre Transform
  */
  void MultiSynthesis(const vector< complex<r_8> >& fn, vector< complex<r_8> >& fi, int stride);

  //! Single Analysis (Values -> Coefs)
  /*!
    \param fi: values f(r_i) with r_i zero L^(alpha)_N
    \param fn : result
  */
  void Analysis(const vector< complex<r_8> >& fi, vector< complex<r_8> >& fn) {
    MultiAnalysis(fi,fn,1);
  }//Analysis

  //! Single Inverse Laguerre Transform (Coefficientss -> Values)
  void Synthesis(const vector< complex<r_8> >& fn, vector< complex<r_8> >& fi) {
    MultiSynthesis(fn,fi,1);
  }//Synthesis

protected:

  r_8 alphaFact_; //!< sqrt(alpha!)
127
  r_8 R_;         //!< maximal radius
128

129 130
  vector<r_8> nodes_;    //!< nodes   of the Gauss-Laguerre quadrature used
  vector<r_8> weights_;  //!< weights of the Gauss-Laguerre quadrature used
131

132 133 134
  r_8 tau_;              //!< a scaling factor = R/nodes[N-1] JEC 22/9/15
  r_8 tau3sqrt_;         // tau^(3/2)
  r_8 tau3sqrtinv_;      // tau^(-3/2)
135 136 137 138 139 140 141 142 143
 public:
  class distance {
  public: 
    distance(r_8 r0): r0_(r0) {}
    r_8 operator()(r_8 x){ r_8 xn=x-r0_; return xn*xn;}
  private:
    r_8 r0_;
  };//distance

144 145 146 147 148 149
};//LaguerreTransform



}//end namespace
#endif