legendre_norm.C

00001 /*
00002  *   Copyright (c) 1999-2001 Eric Gourgoulhon
00003  *
00004  *   This file is part of LORENE.
00005  *
00006  *   LORENE is free software; you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation; either version 2 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   LORENE is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with LORENE; if not, write to the Free Software
00018  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  */
00021 
00022 
00023 char legendre_norm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/legendre_norm.C,v 1.4 2005/02/18 13:14:13 j_novak Exp $" ;
00024 
00025 /*
00026  * Calcule les valeurs des fonctions de Legendre associees 
00027  *   P_l^m(cos(theta)) normalisees de facon a ce que
00028  * 
00029  *   int_0^pi [ P_l^m(cos(theta)) ]^2  sin(theta) dtheta = 1
00030  * 
00031  * NB: Cette normalisation est differente de celle de la litterature
00032  *
00033  * Le calcul est effectue aux 2*nt-1 points  
00034  *  theta_j = pi/2 j/(2*nt-2)       0 <= j <= 2*nt-2 
00035  * qui echantillonnent uniformement l'intervalle [0, pi/2].
00036  *
00037  * 
00038  * Entree:
00039  * -------
00040  * int m    : ordre de la fonction de Legendre associee P_l^m
00041  * int nt   : nombre de points en theta
00042  * 
00043  * Sortie (valeur de retour) :
00044  * -------------------------
00045  * double* legendre_norm : ensemble des (2*nt-1-m)*(2*nt-1) valeurs 
00046  *              P_l^m(cos(theta))
00047  *          stokees comme suit:
00048  *
00049  *      legendre_norm[(2*nt-1)* (l-m) + j] = P_l^m( cos(theta_j) ) 
00050  *
00051  *          avec   m <= l <= 2*nt-2.
00052  *
00053  * NB: Cette routine effectue le calcul a chaque appel et ne renvoie pas
00054  *     un pointeur sur des valeurs precedemment calculees.
00055  */
00056 
00057 
00058 /*
00059  * $Id: legendre_norm.C,v 1.4 2005/02/18 13:14:13 j_novak Exp $
00060  * $Log: legendre_norm.C,v $
00061  * Revision 1.4  2005/02/18 13:14:13  j_novak
00062  * Changing of malloc/free to new/delete + suppression of some unused variables
00063  * (trying to avoid compilation warnings).
00064  *
00065  * Revision 1.3  2003/01/31 10:31:24  e_gourgoulhon
00066  * Suppressed the directive #include <malloc.h> for malloc is defined
00067  * in <stdlib.h>
00068  *
00069  * Revision 1.2  2002/10/16 14:36:54  j_novak
00070  * Reorganization of #include instructions of standard C++, in order to
00071  * use experimental version 3 of gcc.
00072  *
00073  * Revision 1.1.1.1  2001/11/20 15:19:29  e_gourgoulhon
00074  * LORENE
00075  *
00076  * Revision 2.0  1999/02/22  15:37:00  hyc
00077  * *** empty log message ***
00078  *
00079  *
00080  * $Header: /cvsroot/Lorene/C++/Source/Non_class_members/Coef/legendre_norm.C,v 1.4 2005/02/18 13:14:13 j_novak Exp $
00081  *
00082  */
00083 
00084 // headers du C
00085 #include <stdlib.h>
00086 #include <assert.h>
00087 #include <math.h>
00088 
00089 // Prototypage
00090 #include "headcpp.h"
00091 #include "proto.h"
00092 
00093 //******************************************************************************
00094 
00095 double* legendre_norm(int m, int nt) {
00096 
00097 int l, j ;
00098 
00099     int lmax = 2*nt - 2 ; 
00100 
00101 // Sur-echantillonnage pour calculer les carres sans aliasing:
00102     int nt2 = 2*nt - 1 ; 
00103     int nt2m1 = nt2 - 1 ; 
00104 
00105     int deg[3] ;
00106     deg[0] = 1 ;
00107     deg[1] = 1 ;
00108     deg[2] = nt2 ;
00109 
00110 // Tableau de travail
00111     double* yy = new double[nt2] ; //(double*)( malloc( nt2*sizeof(double) ) ) ;
00112     
00113 // Recherche des fonctions de legendre associees non normalisees 
00114 // -------------------------------------------------------------
00115 //  (NB: elles different de celles de la litterature par un facteur (2m-1)!!) :
00116 
00117     double* leg = legendre(m, nt2) ;
00118     
00119 // Normalisation 
00120 // -------------
00121      for (l=m; l<lmax+1; l++) {
00122      
00123     int ml = (m+1)*(l+1) ; 
00124     
00125 // On divise les fonctions de Legendre par (m+1)*(l+1) 
00126 // pour obtenir des nombres pas trop grands:
00127 
00128     for (j=0; j<nt2; j++) {
00129        leg[nt2*(l-m)+j] /= ml ;
00130     }   
00131 
00132 // Carre : 
00133     for (j=0; j<nt2; j++) { 
00134        double w = leg[nt2*(l-m)+j]  ;
00135        yy[nt2m1-j] =  w * w  ;   // le rangement est celui qui convient
00136                     // a cfrchebp
00137     }   
00138     
00139 // Developpement en polynomes de Tchebyshev pairs (x=cos(theta)) : 
00140 
00141     cfrchebp(deg, deg, yy, deg, yy) ;
00142     
00143 // Integrale sur [0,Pi] = 2 fois l'integrale sur [0,1] pour x = cos(theta) : 
00144     double integ = 2.*int1d_chebp(nt2, yy) ;
00145     
00146 // Facteur de normalisation
00147     double fact = 1. / sqrt(integ) ;
00148  
00149 /* Test: Comparaison avec le resultat analytique
00150  * 
00151  *  double fact_test = ml* factorielle2(2*m-1) * sqrt( double(2*l+1)/2.
00152  *      * factorielle(l-m) / factorielle(l+m) ) ;
00153  *  double diff = (fact - fact_test) / fact_test ; 
00154  *
00155  *  cout << "m, l : "<< m << " " << l << " : " << fact << " " << fact_test 
00156  *      << " " << diff << endl ;
00157  */
00158     
00159     for (j=0; j<nt2; j++) {
00160        leg[nt2*(l-m)+j] *= fact ;
00161     }   
00162        
00163      }      // fin de la boucle sur l
00164      
00165 // Liberation espace memoire :
00166      delete [] yy ;
00167 
00168      return leg ; 
00169 
00170 }
00171 
00172 
00173 

Generated on Tue Feb 7 01:35:17 2012 for LORENE by  doxygen 1.4.6