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
1.4.6