Skip to content

karlo0/gauss_christoffel

Repository files navigation

Gauß-Christoffel quadrature

The function gauss_christoffel(N, w, x, total_weight, L, nodes, weights) performs a Gauß-Christoffel quadrature rule to calculate for an arbitrary weight function w(x) (w(x) >= 0, ∀ x) L nodes ( nodes[0] (=x1), ..., nodes[L-1] (=xL) ) and weights ( weights[0] (=w1), ..., weights[L-1] (=wL) ). The weight function is given to gauss_christoffel in discretized form by the N-dimensional array w with corresponding sampling arguments stored in the array x. The calculated weights conserve the first L moments of the given weight function w(x). The correct scaling of all the moments is ensured by giving to the function the total_weight (=∫ w(x) dx) as an input parameter. For more informations about the Gauß-Christoffel quadrature rule, see https://dlmf.nist.gov/3.5#v.

The Gauß-Christoffel quadrature rule can be used to:

(1) obtain a downsampling of any positive function that needs to conserve the first L moments of the function:

  • 0th moment: Σi=1,...,L wi = ∫ w(x) dx,
  • 1st moment: Σi=1,...,L wi xi = ∫ w(x)x dx,

  • Lth moment: Σi=1,...,L wi xiL = ∫ w(x)xL dx.

(2) calculate integrals of the form: ∫ w(x) f(x) dx, with w(x) the weight function and f(x) an arbitray function. The nodes xi and weights wi obtained from the Gauß-Christoffel quadrature are then used to calculate Σi=1,...,L wi f(xi) that is a numerical approximation to the integral.


Usage

The following example performs a Gauß-Christoffel quadrature for a Gaussian with variance 2 centered around x = 0. An extended version of this example is gauss.c.
Compiling requires linking against a blas and lapack.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "gauss_christoffel.h"


int main(){

    int NN = 1000;                                                          // length of the weight function w
    double sigma2 = 2;                                                      // the variance of the gaussian
    double x0 = 0;                                                          // the mean value of the gaussian
    double x[NN+1], w[NN+1];                                                // allocate arrays for the arguments and the weight function
    for(int k=0; k<=NN; k++){                                               
        x[k] = 5.*((double)k/NN - 0.5);                                     // assign argument values
        w[k] = exp(-(x[k]-x0)*(x[k]-x0)/2./sigma2)/sqrt(2*M_PI*sigma2);     // assign function values for a gaussian
    }

    FILE *F;

    F = fopen("gauss_sample_1000.txt","w+");                                // output the gaussian in the file "gauss_sample_1000.txt"
    for(int k=0; k<=NN; k++)                                                
        fprintf(F, "%f\t%f\n", x[k], w[k]);                                 // write in the first column the arguments and in the second column the values of the weight function
    fclose(F);


    // perform Gauß-Christoffel quadrature with 5 sampling points
    int dim = 5;
    double nodes[dim], weights[dim];

    // call the the Gauß-Christoffel quadrature rule function
    gauss_christoffel(NN+1, w, x, 1., dim, nodes, weights);

    F = fopen("gauss_downsample_N5.txt","w+");                              // output the gaussian in the file "gauss_downsample_N5.txt"
    for(int k=0; k<dim; k++)
        fprintf(F, "%f\t%f\n", nodes[k], weights[k]);                       // write in the first column the nodes and in the second column the weights of the downsampled weight function
    fclose(F);

    return 0;
}

About

perfoms Gauß-Christoffel quadrature

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published