Task: Numerical integration_Gauss-Legendre Quadrature



C#: using System;


                    
public class Program {

    public static double[][] legeCoef(int N) {
        
        double[][] lcoef = new double[N+1][];
        for (int i=0; i < lcoef.Length; ++i) 
            lcoef[i] = new double[N+1];


        lcoef[0][0] = lcoef[1][1] = 1;
        for (int n = 2; n <= N; n++) {
            lcoef[n][0] = -(n - 1) * lcoef[n - 2][0] / n;
            for (int i = 1; i <= n; i++) 
                lcoef[n][i] = ((2*n - 1) * lcoef[n-1][i-1] 
                               - (n-1) * lcoef[n-2][i] ) / n;
        }
        return lcoef;
    }


    static double legeEval(double[][] lcoef, int N, double x) {
        double s = lcoef[N][N];
        for (int i = N; i > 0; --i)
            s = s * x + lcoef[N][i-1];
        return s;
    }

    static double legeDiff(double[][] lcoef, int N, double x) {
        return N * (x * legeEval(lcoef, N, x) - legeEval(lcoef, N-1, x)) / (x*x - 1);
    }

    static void legeRoots(double[][] lcoef, int N, out double[] lroots,  out double[] weight) {
        lroots = new double[N];
        weight = new double[N];

        double x, x1;
        for (int i = 1; i <= N; i++) {
            x = Math.Cos(Math.PI * (i - 0.25) / (N + 0.5));
            do { 
                x1 = x;
                x -= legeEval(lcoef, N, x) / legeDiff(lcoef, N, x);
            } 
            while (x != x1);
            lroots[i-1] = x;

            x1 = legeDiff(lcoef, N, x);
            weight[i-1] = 2 / ((1 - x*x) * x1*x1);
        }
    }
    
    

    static double legeInte(Func<Double, Double> f, int N, double[] weights, double[] lroots, double a, double b) {
        double c1 = (b - a) / 2, c2 = (b + a) / 2, sum = 0;
        for (int i = 0; i < N; i++)
            sum += weights[i] * f.Invoke(c1 * lroots[i] + c2);
        return c1 * sum;
    }
    
    
    public static string Combine(double[] arrayD) {
        return string.Join(", ", arrayD);	
    }

    public static void Main() {
        int N = 5;
        
        var lcoeff = legeCoef(N);
        
        double[] roots;
        double[] weights;
        legeRoots(lcoeff, N, out roots, out weights);
        
        var integrateResult = legeInte(x=>Math.Exp(x), N, weights, roots, -3, 3);
        
        Console.WriteLine("Roots:   " + Combine(roots));
        Console.WriteLine("Weights: " + Combine(weights)+ "\n" );
        Console.WriteLine("integral: " + integrateResult );
        Console.WriteLine("actual:   " + (Math.Exp(3)-Math.Exp(-3)) );
    }


}





Python: from numpy import *
 


def Legendre(n,x):
	x=array(x)
	if (n==0):
		return x*0+1.0
	elif (n==1):
		return x
	else:
		return ((2.0*n-1.0)*x*Legendre(n-1,x)-(n-1)*Legendre(n-2,x))/n
 


def DLegendre(n,x):
	x=array(x)
	if (n==0):
		return x*0
	elif (n==1):
		return x*0+1.0
	else:
		return (n/(x**2-1.0))*(x*Legendre(n,x)-Legendre(n-1,x))


def LegendreRoots(polyorder,tolerance=1e-20):
	if polyorder<2:
		err=1 
	else:
		roots=[]
		
		for i in range(1,int(polyorder)/2 +1):
			x=cos(pi*(i-0.25)/(polyorder+0.5))
			error=10*tolerance
		        iters=0
		        while (error>tolerance) and (iters<1000):
		                dx=-Legendre(polyorder,x)/DLegendre(polyorder,x)
		                x=x+dx
		                iters=iters+1
		                error=abs(dx)
			roots.append(x)
		
		roots=array(roots)
		if polyorder%2==0:
			roots=concatenate( (-1.0*roots, roots[::-1]) )
		else:
			roots=concatenate( (-1.0*roots, [0.0], roots[::-1]) )
		err=0 
	return [roots, err]


def GaussLegendreWeights(polyorder):
	W=[]
	[xis,err]=LegendreRoots(polyorder)
	if err==0:
		W=2.0/( (1.0-xis**2)*(DLegendre(polyorder,xis)**2) )
		err=0
	else:
		err=1 
	return [W, xis, err]






def GaussLegendreQuadrature(func, polyorder, a, b):
	[Ws,xs, err]= GaussLegendreWeights(polyorder)
	if err==0:
		ans=(b-a)*0.5*sum( Ws*func( (b-a)*0.5*xs+ (b+a)*0.5 ) )
	else: 
		
		err=1
		ans=None
	return [ans,err]


def func(x):
	return exp(x)


 
order=5
[Ws,xs,err]=GaussLegendreWeights(order)
if err==0:
	print "Order    : ", order
	print "Roots    : ", xs
	print "Weights  : ", Ws
else:
	print "Roots/Weights evaluation failed"
 

[ans,err]=GaussLegendreQuadrature(func , order, -3,3)
if err==0:
	print "Integral : ", ans
else:
	print "Integral evaluation failed"