#include //< exit #include //< assert #include //< printf #include //< cos, fabs, M_PI // COPIEZ-COLLEZ LA FONCTION SUIVANTE DANS VOTRE CODE POUR L'UTILISER. /** * \brief Construit une formule de quadrature de Gauss-Legendre à n points sur l'intervalle [-1, 1]. * * \param[out] points Stocke les n points de quadrature. * \param[out] weights Stocke les n poids de quadrature. * \param[in] n Nombre de points (doit être un entier pair strictement positif) * * En entrée, les tableaux points et weights doivent être déjà alloués à la taille n. * En sortie : * - les indices [0 : (n-1)/2] contiennent les points < 0 * - les indices [(n-1)/2+1 : (n-1)] contiennent les points > 0 * * Les points de quadrature sont les racines du polynôme de Legendre de degré n, calculées avec une * méthode de Newton. * Les poids de quadratures sont calculés avec la formule w_j = 2 / ((1 - x_j^2) * [P_n'(x_j)^2]). * Pour plus de détails, voir "Numerical Recipes, 3rd ed." par William H. Press (p. 179-184). * */ void create_gauss_legendre_quadrature(double* points, double* weights, int n) { assert(points != NULL); assert(weights != NULL); if (n <= 0 || (n % 2) != 0) { printf("ERROR : create_gauss_legendre_quadrature : n doit être > 0 et pair.\n"); exit(EXIT_FAILURE); } // On calcule seulement les racines positives car la formule est symétrique int const m = (n + 1) / 2; for (int i = 0; i < m; ++i) { // Valeur initiale pour la methode de Newton double z = cos(M_PI * (i + 0.75) / (n + 0.5)); double z1 = 0; double pp = 0; // Boucle principale de la méthode de Newton do { double p1 = 1.0; double p2 = 0.; // Calcule le polynôme de Legendre de degré n au point z en utilisant la formule de récurrence for (int j = 0; j < n; ++j) { double const p3 = p2; p2 = p1; p1 = ((2. * j + 1.) * z * p2 - j * p3) / (j + 1); } // Dérivée du polynôme de Legendre au point z pp = n * (z * p1 - p2) / (z * z - 1); z1 = z; // Formule d'ajustement de la méthode de Newton z = z1 - p1 / pp; } while (fabs(z - z1) > 1e-12); points[i] = -z; points[n - i - 1] = z; weights[i] = 2. / ((1. - z * z) * pp * pp); weights[n - i - 1] = weights[i]; } }