Here’s some C++ functions which evaluate Legendre polynomials:
P0(x):
double P0(double x) ;
P1(x):
double P1(double x) ;
P2(x):
double P2(double x) ;
Pn(x):
double Pn(unsigned int n, double x) ;
These are inline functions defined in the header file, legendre.h:
— start —
//================================================================== /** * legendre.h -- C++ functions to evaluate Legendre polynomials * * Copyright (C) 2005 by James A. Chappell * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * condition: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ //================================================================= /* * legendre.h: Version 0.01 * Created by James A. Chappell * Created 29 September 2005 * * History: * 29-sep-2005 created */ //============== #ifndef __LEGENDRE_H__ #define __LEGENDRE_H__ /* * Function calculates Legendre Polynomials Pn(x) */ namespace Legendre { // n = 0 inline double P0(double x) { return 1.0 ; } // n = 1 inline double P1(double x) { return x ; } // n = 2 inline double P2(double x) { return ((3.0 * x*x) - 1.0) * 0.5 ; } /* * Pn(x) */ inline double Pn(unsigned int n, double x) { if (n == 0) { return P0(x) ; } else if (n == 1) { return P1(x) ; } else if (n == 2) { return P2(x) ; } if (x == 1.0) { return 1.0 ; } if (x == -1.0) { return ((n % 2 == 0) ? 1.0 : -1.0) ; } if ((x == 0.0) && (n % 2)) { return 0.0 ; } /* We could simply do this: return (double(((2 * n) - 1)) * x * Pn(n - 1, x) - (double(n - 1)) * Pn(n - 2, x)) / (double)n ; but it could be slow for large n */ double pnm1(P2(x)) ; double pnm2(P1(x)) ; double pn(pnm1) ; for (unsigned int l = 3 ; l <= n ; l++) { pn = (((2.0 * (double)l) - 1.0) * x * pnm1 - (((double)l - 1.0) * pnm2)) / (double)l ; pnm2 = pnm1; pnm1 = pn; } return pn ; } } #endif
— end —
Here’s a sample program:
— start —
#include <iostream> #include "legendre.h" using namespace std ; using namespace Legendre ; int main() { double pn ; cout.precision(5) ; for (unsigned int n = 0 ; n <= 5 ; n++) { for (double x = -1.0 ; x <= 1.0 ; x = x + 0.1) { pn = Pn(n, x) ; cout << "P" << n << "(" << x << ") = " << pn << endl ; } cout << endl ; } return 0 ; }
— end —
UPDATE: 2014-10-01:
This project can now be found on GitHub:
– Legendre-polynomials
– HTTPS Clone URL: https://github.com/jachappell/Legendre-polynomials.git
– Download ZIP
What about the other index? The Gnu Scientific Library can do this, btw, if you are able to work compatibly with the GPL.
The Gnu Scientific Library can do this – This was more or less an academic exercise, it’s not meant to be a replacement for the Gnu Scientific Library or any other library out there.