#include <math.h>

void rgauleg(double x1,double x2, double *x, double *w, int n)
{

/* ===purpose=== */

/**********************************************************************************************************************************/
/*********************************************  Real-Valued Gauss-Legendre quadrature  ********************************************/
/***********  Compute the Gauss points and weights needed to evaluate the 1D integral $\int\limits_{x_1}^{x_2} f(x) dx$  **********/
/******************************  $\int\limits_{x_1}^{x_2} f(x) dx = \sum\limits_{i=1}^n w_i f(x_i)$  ******************************/
/**********************************************************************************************************************************/

/* Developer: Sylvain Nintcheu Fata */
/* Version:   V.1.1                 */
/* Released:  Jun 14, 2012          */


/******************************************************/
/* Parameter list:                                    */
/******************************************************/
/*
 * n = Number of integration points.
 * x1,x2 = Respectively lower and upper limits of the integral $\int\limits_{x_1}^{x_2} f(x) dx$.
 * x,w = Respectively arrays of abscissas $x_i$ and weights $w_i$ of Gauss-Legendre quadrature.
 * $x_i$ are symmetric about the midpoint of the interval $(x_1,x_2)$.
 * Return value: None
 */


    extern double pi; /* pi = 3.1415926535897932 */

    int i,j,m;
    double p1,p2,p3,pp,xl,xm,z,z1;
//    double pi=M_PI;
    const double eps = 3.0e-14;


    m=(n+1)/2; // number of computed roots and weighting coefficients (use of symmetry)

/*** xm,xl -auxillary transformation parameters from interval $(-1,1)$ to $(x_1,x_2)$ ***/
    xm=0.5*(x2+x1); xl=0.5*(x2-x1);
    
    for (i=1; i<=m; i++) // Loop over the roots
    {
       z = cos(pi*(i-0.25)/(n+0.5)); // starting approximation of the i-th root of the Legendre polynomial
       
       do    //loop until desired accuracy
       {
          p1=1.0;  p2=0.0;
/*** value of the Legendre polynomial of degree n at point z ***/
          for (j=1; j<=n; j++)
	  {
            p3=p2;
            p2=p1;
            p1=((2.0*j-1.0)*z*p2-(j-1.0)*p3)/j; // Legendre polynomial recurrence formula
	  
	  }
/*** p1 is the value of the Legendre polynomial of degree n at point z ***/

/*** pp is the first derivative of th Legendre polynomial at z ***/
          pp = n*(z*p1-p2)/(z*z-1.0); // Legendre polynomial recurrence formula involving first derivative
          z1 = z;
          z = z1-p1/pp;  //Newton's method 
       } while ( fabs(z-z1) > eps);
/*** z is the i-th root of the Legendre polynomial ***/

/*** transformation of the root z from the interval $(-1,1)$ to the corresponding abscissa in $(x_1,x_2)$ and its symmetric counterpart ***/
        x[i-1]=xm-xl*z; x[n-i]=xm+xl*z;

       
/*** computation of weighting coefficients ***/
        w[i-1]=2.0*xl/((1.0-z*z)*pp*pp);
        w[n-i]=w[i-1];

    }

}
