Numerical integration/Gauss-Legendre Quadrature: Difference between revisions
Numerical integration/Gauss-Legendre Quadrature (view source)
Revision as of 15:07, 10 April 2024
, 1 month agoAdded FreeBASIC
SqrtNegInf (talk | contribs) m (→{{header|Perl}}: Fix link: Perl 6 --> Raku) |
(Added FreeBASIC) |
||
(26 intermediate revisions by 15 users not shown) | |||
Line 47:
<big><big><math>\int_{-3}^{3} \exp(x) \, dx \approx \sum_{i=1}^5 w_i \; \exp(x_i) \approx 20.036</math></big></big>
<br><br>
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">F legendreIn(x, n)
F prev1(idx, pn1)
R (2 * idx - 1) * @x * pn1
F prev2(idx, pn2)
R (idx - 1) * pn2
I n == 0
R 1.0
E I n == 1
R x
E
V result = 0.0
V p1 = x
V p2 = 1.0
L(i) 2 .. n
result = (prev1(i, p1) - prev2(i, p2)) / i
p2 = p1
p1 = result
R result
F deriveLegendreIn(x, n)
F calcresult(curr, prev)
R Float(@n) / (@x ^ 2 - 1) * (@x * curr - prev)
R calcresult(legendreIn(x, n), legendreIn(x, n - 1))
F guess(n, i)
R cos(math:pi * (i - 0.25) / (n + 0.5))
F nodes(n)
V result = [(0.0, 0.0)] * n
F calc(x)
R legendreIn(x, @n) / deriveLegendreIn(x, @n)
L(i) 0 .< n
V x = guess(n, i + 1)
V x0 = x
x -= calc(x)
L abs(x - x0) > 1e-12
x0 = x
x -= calc(x)
result[i] = (x, 2 / ((1.0 - x ^ 2) * (deriveLegendreIn(x, n)) ^ 2))
R result
F integ(f, ns, p1, p2)
F dist()
R (@p2 - @p1) / 2
F avg()
R (@p1 + @p2) / 2
V result = dist()
V sum = 0.0
V thenodes = [0.0] * ns
V weights = [0.0] * ns
L(nw) nodes(ns)
sum += nw[1] * f(dist() * nw[0] + avg())
thenodes[L.index] = nw[0]
weights[L.index] = nw[1]
print(‘ nodes:’, end' ‘’)
L(n) thenodes
print(‘ #.5’.format(n), end' ‘’)
print()
print(‘ weights:’, end' ‘’)
L(w) weights
print(‘ #.5’.format(w), end' ‘’)
print()
R result * sum
print(‘integral: ’integ(x -> exp(x), 5, -3, 3))</syntaxhighlight>
{{out}}
<pre>
nodes: 0.90618 0.53847 0.00000 -0.53847 -0.90618
weights: 0.23693 0.47863 0.56889 0.47863 0.23693
integral: 20.035577718
</pre>
=={{header|ATS}}==
{{trans|Common Lisp}}
This is a very close translation of the Common Lisp.
(A lot of the "ATS-ism" is completely optional. For instance, you can use <code>arrszref</code> instead of <code>arrayref</code>, if you want bounds checking at runtime instead of compile-time. But then debugging and regression-prevention become harder, and in that particular case the code will almost surely be slower.
And, if I may grumble a bit: ''Some'' of us ''do not'' think "turning off bounds checking for production" is acceptable. It is at best something to tolerate grudgingly.)
<syntaxhighlight lang="ats">
#include "share/atspre_staload.hats"
%{^
#include <float.h>
#include <math.h>
%}
extern fn {tk : tkind} g0float_pi : () -<> g0float tk
extern fn {tk : tkind} g0float_cos : g0float tk -<> g0float tk
extern fn {tk : tkind} g0float_exp : g0float tk -<> g0float tk
implement g0float_pi<dblknd> () = $extval (double, "M_PI")
implement g0float_cos<dblknd> x = $extfcall (double, "cos", x)
implement g0float_exp<dblknd> x = $extfcall (double, "exp", x)
macdef PI = g0float_pi ()
overload cos with g0float_cos
overload exp with g0float_exp
macdef NAN = g0f2f ($extval (float, "NAN"))
macdef Zero = g0i2f 0
macdef One = g0i2f 1
macdef Two = g0i2f 2
(* Computes the initial guess for the root i of a n-order Legendre
polynomial. *)
fn {tk : tkind}
guess {n, i : int | 1 <= i; i <= n}
(n : int n, i : int i) :<> g0float tk =
cos (PI * ((g0i2f i - g0f2f 0.25) / (g0i2f n + g0f2f 0.5)))
(* Computes and evaluates the degree-n Legendre polynomial at the
point x. *)
fn {tk : tkind}
legpoly {n : pos}
(n : int n, x : g0float tk) :<> g0float tk =
let
fun
loop {i : int | 2 <= i; i <= n + 1} .<n + 1 - i>.
(i : int i, pa : g0float tk, pb : g0float tk)
:<> g0float tk =
if i = succ n then
pb
else
let
val iflt = (g0i2f i) : g0float tk
val pn = (((iflt + iflt - One) / iflt) * x * pb)
- (((iflt - One) / iflt) * pa)
in
loop (succ i, pb, pn)
end
in
if n = 0 then
One
else if n = 1 then
x
else
loop (2, One, x)
end
(* Computes and evaluates the derivative of an n-order Legendre
polynomial at point x. *)
fn {tk : tkind}
legdiff {n : int | 2 <= n}
(n : int n, x : g0float tk) :<> g0float tk =
(g0i2f n / ((x * x) - One))
* ((x * legpoly<tk> (n, x)) - legpoly<tk> (pred n, x))
(* Computes the n nodes for an n-point quadrature rule (the n roots of
a degree-n polynomial). *)
fn {tk : tkind}
nodes {n : int | 2 <= n}
(n : int n) :<!refwrt> arrayref (g0float tk, n) =
let
val x = arrayref_make_elt<g0float tk> (i2sz n, Zero)
fn
v_update (v : g0float tk) :<> g0float tk =
v - (legpoly<tk> (n, v) / legdiff<tk> (n, v))
var i : Int
in
for* {i : nat | i <= n} .<n - i>.
(i : int i) =>
(i := 0; i <> n; i := succ i)
let
val v = guess<tk> (n, succ i)
val v = v_update v
val v = v_update v
val v = v_update v
val v = v_update v
val v = v_update v
in
x[i] := v
end;
x
end
(* Computes the weight for an degree-n polynomial at the node x. *)
fn {tk : tkind}
legwts {n : int | 2 <= n}
(n : int n, x : g0float tk) :<> g0float tk =
(* Here I am having slightly excessive fun with notation: *)
Two / ((One - (x * x)) * (y * y where {val y = legdiff<tk> (n, x)}))
(* Normally I would not write code in such fashion. :) Nevertheless,
it is interesting that this works. *)
(* Takes an array of nodes x and computes an array of corresponding
weights w. Note that x is an arrayref, not an arrszref, and so
(unlike in the Common Lisp) we have to tell the function the size
of the new array w. That information is not otherwise stored AT
RUNTIME. The ATS compiler, however, will force us AT COMPILE TIME
to pass the correct size. *)
fn {tk : tkind}
weights {n : int | 2 <= n}
(n : int n, x : arrayref (g0float tk, n))
:<!refwrt> arrayref (g0float tk, n) =
let
val w = arrayref_make_elt<g0float tk> (i2sz n, Zero)
var i : Int
in
for* {i : nat | i <= n} .<n - i>.
(i : int i) =>
(i := 0; i <> n; i := succ i)
w[i] := legwts (n, x[i]);
w
end
(* Estimates the definite integral of a function on [a,b], using an
n-point Gauss-Legendre quadrature rule. *)
fn {tk : tkind}
quad {n : int | 2 <= n}
(f : g0float tk -<> g0float tk,
n : int n,
a : g0float tk,
b : g0float tk) :<> g0float tk =
let
val x = $effmask_ref ($effmask_wrt (nodes<tk> n))
val w = $effmask_ref ($effmask_wrt (weights<tk> (n, x)))
val ahalf = g0f2f 0.5 * a and bhalf = g0f2f 0.5 * b
val C1 = bhalf - ahalf and C2 = ahalf + bhalf
fun
loop {i : nat | i <= n} .<n - i>.
(i : int i, sum : g0float tk) :<> g0float tk =
if i = n then
sum
else
let
val y = $effmask_ref (w[i] * f ((C1 * x[i]) + C2))
in
loop (succ i, sum + y)
end
in
C1 * loop (0, Zero)
end
implement
main () =
let
val outf = stdout_ref
in
fprintln! (outf, "nodes<dblknd> 5");
fprint_arrayref_sep<double> (outf, nodes<dblknd> (5),
i2sz 5, " ");
fprintln! (outf); fprintln! (outf);
fprintln! (outf, "weights (nodes<dblknd> 5)");
fprint_arrayref_sep<double> (outf, weights (5, nodes<dblknd> (5)),
i2sz 5, " ");
fprintln! (outf); fprintln! (outf);
fprintln! (outf, "quad (lam x => exp x, 5, ~3.0, 3.0) = ",
quad (lam x => exp x, 5, ~3.0, 3.0));
fprintln! (outf);
fprintln! (outf, "More examples, borrowed from the Common Lisp:");
fprintln! (outf, "quad (lam x => x ** 3, 5, 0.0, 1.0) = ",
quad (lam x => x ** 3, 5, 0.0, 1.0));
fprintln! (outf, "quad (lam x => 1.0 / x, 5, 1.0, 100.0) = ",
quad (lam x => 1.0 / x, 5, 1.0, 100.0));
fprintln! (outf, "quad (lam x => x, 5, 0.0, 5000.0) = ",
quad (lam x => x, 5, 0.0, 5000.0));
fprintln! (outf, "quad (lam x => x, 5, 0.0, 6000.0) = ",
quad (lam x => x, 5, 0.0, 6000.0));
0
end
</syntaxhighlight>
{{out}}
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_GCBDW gauss_legendre_task.dats -lgc -lm && ./a.out
nodes<dblknd> 5
0.906180 0.538469 0.000000 -0.538469 -0.906180
weights (nodes<dblknd> 5)
0.236927 0.478629 0.568889 0.478629 0.236927
quad (lam x => exp x, 5, ~3.0, 3.0) = 20.035578
More examples, borrowed from the Common Lisp:
quad (lam x => x ** 3, 5, 0.0, 1.0) = 0.250000
quad (lam x => 1.0 / x, 5, 1.0, 100.0) = 4.059148
quad (lam x => x, 5, 0.0, 5000.0) = 12500000.000000
quad (lam x => x, 5, 0.0, 6000.0) = 18000000.000000</pre>
=={{header|Axiom}}==
{{trans|Maxima}}
Axiom provides Legendre polynomials and related solvers.<
RECORD ==> Record(x : List Fraction Integer, w : List Fraction Integer)
Line 69 ⟶ 360:
c := (a+b)/2
h := (b-a)/2
h*reduce(+,[wi*subst(e,var=c+xi*h) for xi in u.x for wi in u.w])</
gaussIntegrate(4/(1+x^2), x=0..1, 20)
Line 76 ⟶ 367:
% - %pi
(2) - 0.3463549483_9378821092_475 E -26</
=={{header|C}}==
<
#include <math.h>
Line 162 ⟶ 453:
lege_inte(exp, -3, 3), exp(3) - exp(-3));
return 0;
}</
{{out}}
<pre>Roots: 0.90618 0.538469 0 -0.538469 -0.90618
Line 175 ⟶ 466:
Does not quite perform the task quite as specified since the node count, N, is set at compile time (to avoid heap allocation) so cannot be passed as a parameter.
<syntaxhighlight lang="cpp">#include <iostream>
#include <iomanip>
#include <cmath>
namespace Rosetta {
Line 217 ⟶ 511:
out << ' ' << legpoly.root(i);
}
out <<
out << "Weights:";
for (int i = 0; i <= eDEGREE; ++i) {
out << ' ' << legpoly.weight(i);
}
out <<
}
private:
Line 309 ⟶ 603:
gl5.print_roots_and_weights(std::cout);
std::cout << "Integrating Exp(X) over [-3, 3]: " << gl5.integrate(-3., 3., RosettaExp) <<
std::cout << "Actual value: " << RosettaExp(3) - RosettaExp(-3) <<
}</syntaxhighlight>
{{out}}
Line 321 ⟶ 614:
Actual value: 20.03574985
</pre>
=={{header|C sharp|C#}}==
Derived from the C++ and Java versions here.
<syntaxhighlight lang="csharp">
using System;
//Works in .NET 6+
//Tested using https://dotnetfiddle.net because im lazy
public class Program {
public static double[][] legeCoef(int N) {
//Initialising Jagged Array
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;
}
//..................Main...............................
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)) );
}
}</syntaxhighlight>
{{out}}
<pre>
Roots: 0.906179845938664, 0.538469310105683, 0, -0.538469310105683, -0.906179845938664
Weights: 0.236926885056189, 0.478628670499367, 0.568888888888889, 0.478628670499367, 0.236926885056189
integral: 20.0355777183856
actual: 20.0357498548198
</pre>
=={{header|Common Lisp}}==
<
(defun guess (n i)
(cos (* pi
Line 385 ⟶ 780:
(funcall f (+ (* (/ (- b a) 2.0d0)
(aref x i))
(/ (+ a b) 2.0d0))))))))</
{{out|Example}}
<
#(0.906179845938664d0 0.5384693101056831d0 2.996272867003007d-95 -0.5384693101056831d0 -0.906179845938664d0)
Line 394 ⟶ 789:
(int #'exp 5 -3 3)
20.035577718385568d0</
Comparison of the 5-point rule with simpler, but more costly methods from the task [[Numerical Integration]]:
<
0.24999999999999997d0
Line 406 ⟶ 801:
(int #'(lambda (x) x) 5 0 6000)
1.8000000000000004d7</
=={{header|D}}==
{{trans|C}}
<
immutable struct GaussLegendreQuadrature(size_t N, FP=double,
Line 483 ⟶ 878:
writefln("Compred to actual: %10.12f",
3.0.exp - exp(-3.0));
}</
{{out}}
<pre>Roots: [0.90618, 0.538469, 0, -0.538469, -0.90618]
Line 492 ⟶ 887:
=={{header|Delphi}}==
<
{$APPTYPE CONSOLE}
Line 585 ⟶ 980:
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
Readln;
end.</
<pre>
Line 595 ⟶ 990:
=={{header|Fortran}}==
<
! -assume realloc_lhs
! when compiled with Intel Fortran.
Line 646 ⟶ 1,041:
end function
end program
</syntaxhighlight>
<pre>
Line 672 ⟶ 1,067:
20 20.0357498548198037979491872388495 -.82E-28
</pre>
=={{header|FreeBASIC}}==
{{trans|Wren}}
<syntaxhighlight lang="vbnet">#define PI 4 * Atn(1)
Const As Double LIM = 5
Dim Shared As Double lroots(LIM - 1)
Dim Shared As Double weight(LIM - 1)
Dim Shared As Double lcoef(LIM, LIM)
For i As Integer = 0 To LIM
For j As Integer = 0 To LIM
lcoef(i, j) = 0
Next j
Next i
Sub legeCoef()
lcoef(0, 0) = 1
lcoef(1, 1) = 1
For n As Integer = 2 To LIM
lcoef(n, 0) = -(n - 1) * lcoef(n - 2, 0) / n
For i As Integer = 1 To n
lcoef(n, i) = ((2 * n - 1) * lcoef(n - 1, i - 1) - (n - 1) * lcoef(n - 2, i)) / n
Next i
Next n
End Sub
Function legeEval(n As Integer, x As Double) As Double
Dim As Double s = lcoef(n, n)
For i As Integer = n To 1 Step -1
s = s * x + lcoef(n, i - 1)
Next i
Return s
End Function
Function legeDiff(n As Integer, x As Double) As Double
Return n * (x * legeEval(n, x) - legeEval(n - 1, x)) / (x * x - 1)
End Function
Sub legeRoots()
Dim As Double x = 0
Dim As Double x1 = 0
For i As Integer = 1 To LIM
x = Cos(PI * (i - 0.25) / (LIM + 0.5))
Do
x1 = x
x = x - legeEval(LIM, x) / legeDiff(LIM, x)
Loop Until x = x1
lroots(i - 1) = x
x1 = legeDiff(LIM, x)
weight(i - 1) = 2 / ((1 - x * x) * x1 * x1)
Next i
End Sub
Function legeIntegrate(f As Function (As Double) As Double, a As Double, b As Double) As Double
Dim As Double c1 = (b - a) / 2
Dim As Double c2 = (b + a) / 2
Dim As Double sum = 0
For i As Integer = 0 To LIM - 1
sum = sum + weight(i) * f(c1 * lroots(i) + c2)
Next i
Return c1 * sum
End Function
legeCoef()
legeRoots()
Print "Roots: ";
For i As Integer = 0 To LIM - 1
Print Using " ##.######"; lroots(i);
Next i
Print
Print "Weight:";
For i As Integer = 0 To LIM - 1
Print Using " ##.######"; weight(i);
Next i
Print
Function f(x As Double) As Double
Return Exp(x)
End Function
Dim As Double actual = Exp(3) - Exp(-3)
Print Using !"Integrating exp(x) over [-3, 3]:\n\t########.######,\ncompared to actual\n\t########.######"; legeIntegrate(@f, -3, 3); actual
Sleep</syntaxhighlight>
{{out}}
<pre>Roots: 0.906180 0.538469 0.000000 -0.538469 -0.906180
Weight: 0.236927 0.478629 0.568889 0.478629 0.236927
Integrating exp(x) over [-3, 3]:
20.035578,
compared to actual
20.035750</pre>
=={{header|Go}}==
Implementation pretty much by the methods given in the task description.
<
import (
Line 770 ⟶ 1,259:
}
panic("no convergence")
}</
{{out}}
<pre>
Line 780 ⟶ 1,269:
=={{header|Haskell}}==
Integration formula
<
where d = (b - a)/2
m = (b + a)/2
w x = 2/(1-x^2)/(legendreP' n x)^2
roots = map (findRoot (legendreP n) (legendreP' n) . x0) [1..n]
x0 i = cos (pi*(i-1/4)/(n+1/2))</
Calculation of Legendre polynomials
<
where go 0 p2 _ = p2
go 1 _ p1 = p1
go n p2 p1 = go (n-1) p1 $ ((2*n-1)*x*p1 - (n-1)*p2)/n
legendreP' n x = n/(x^2-1)*(x*legendreP n x - legendreP (n-1) x)</
Universal auxilary functions
<
fixedPoint f x | abs (fx - x) < 1e-15 = x
| otherwise = fixedPoint f fx
where fx = f x</
Integration on a given mesh using Gauss-Legendre quadrature:
<
integrate f (m:ms) = sum $ zipWith (gaussLegendre 5 f) (m:ms) ms</
{{out}}
Line 821 ⟶ 1,310:
=={{header|J}}==
'''Solution:'''
<syntaxhighlight lang
getLegendreCoeffs=: verb define M.
if. y<:1 do. 1 {.~ - y+1 return. end.
(%~ <:@(,~ +:) -/@:* (0;'') ,&> [: getLegendreCoeffs&.> -&1 2) y
)
getPolyRoots=: 1 {:: p. NB. returns the roots of a polynomial
getGaussLegendreWeights=: 2 % -.@*:@[ * (*:@p.~ p..) NB. form: roots getGaussLegendreWeights coeffs
getGaussLegendrePoints=: (getPolyRoots ([ ,: getGaussLegendreWeights) ])@getLegendreCoeffs
NB.*integrateGaussLegendre a Integrates a function u with a n-point Gauss-Legendre quadrature rule over the interval [a,b]
NB. form: npoints function integrateGaussLegendre (a,b)
integrateGaussLegendre=: adverb define
:
)</
{{out|Example use}}
<
20.0356
-~/ ^ _3 3 NB. true value
20.0357</syntaxhighlight>
=={{header|Java}}==
{{trans|C}}
{{works with|Java|8}}
<
import java.util.function.Function;
Line 918 ⟶ 1,410:
legeInte(x -> exp(x), -3, 3), exp(3) - exp(-3));
}
}</
<pre>Roots: 0,906180 0,538469 0,000000 -0,538469 -0,906180
Weight: 0,236927 0,478629 0,568889 0,478629 0,236927
Line 927 ⟶ 1,419:
=={{header|JavaScript}}==
<
const factorial = n => n <= 1 ? 1 : n * factorial(n - 1);
const M = n => (n - (n % 2 !== 0)) / 2;
Line 947 ⟶ 1,439:
}
console.log(gaussLegendre(x => Math.exp(x), -3, 3, 5));
</syntaxhighlight>
{{output}}
<pre>
20.035577718385575
</pre>
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
'''Also works with gojq, the Go implementation of jq, and with fq'''
<syntaxhighlight lang=jq>
# output: an array
def legendreCoef($N):
{lcoef: (reduce range(0;$N+1) as $i (null; .[$i] = [range(0;$N + 1)| 0]))}
| .lcoef[0][0] = 1
| .lcoef[1][1] = 1
| reduce range(2; $N+1) as $n (.;
.lcoef[$n][0] = -($n-1) * .lcoef[$n -2][0] / $n
| reduce range (1; $n+1) as $i (.;
.lcoef[$n][$i] = ((2*$n - 1) * .lcoef[$n-1][$i-1] - ($n - 1) * .lcoef[$n-2][$i]) / $n ) )
| .lcoef ;
# input: lcoef
# output: the value
def legendreEval($n; $x):
. as $lcoef
| reduce range($n; 0 ;-1) as $i ( $lcoef[$n][$n] ; . * $x + $lcoef[$n][$i-1] ) ;
# input: lcoef
def legendreDiff($n; $x):
$n * ($x * legendreEval($n; $x) - legendreEval($n-1; $x)) / ($x*$x - 1) ;
# input: lcoef
# output: {lroots, weight}
def legendreRoots($N):
def pi: 1|atan * 4;
. as $lcoef
| { x: 0, x1: null}
| reduce range(1; 1+$N) as $i (.;
.x = ((pi * ($i - 0.25) / ($N + 0.5)) | cos )
| until (.x == .x1;
.x1 = .x
| .x as $x
| .x = .x - ($lcoef | (legendreEval($N; $x) / legendreDiff($N; $x) )) )
| .lroots[$i-1] = .x
| .x as $x
| .x1 = ($lcoef|legendreDiff($N; $x))
| .weight[$i-1] = 2 / ((1 - .x*.x) * .x1 * .x1) ) ;
# Input: {lroots, weight}
def legendreIntegrate(f; $a; $b; $N):
.lroots as $lroots
| .weight as $weight
| (($b - $a) / 2) as $c1
| (($b + $a) / 2) as $c2
| reduce range(0;$N) as $i (0; . + $weight[$i] * (($c1* $lroots[$i] + $c2)|f) )
| $c1 * .;
def task($N):
def actual: 3|exp - ((-3)|exp);
legendreCoef($N)
| legendreRoots($N)
| "Roots: ",
.lroots,
"\nWeight:",
.weight,
"\nIntegrating exp(x) over [-3, 3]: \(legendreIntegrate(exp; -3; 3; N))",
"compared to actual: \(actual)" ;
task(5)
</syntaxhighlight>
'''Invocation:'''
<pre>
jq -ncr -f gauss-legendre-quadrature.jq
</pre>
{{output}}
<pre>
Roots:
[0.906179845938664,0.5384693101056831,0,-0.5384693101056831,-0.906179845938664]
Weight:
[0.23692688505618922,0.4786286704993667,0.5688888888888889,0.4786286704993667,0.23692688505618922]
Integrating exp(x) over [-3, 3]: 20.035577718385575
compared to actual: 20.035749854819805
</pre>
=={{header|Julia}}==
This function computes the points and weights of an ''N''-point Gauss–Legendre quadrature rule on the interval (''a'',''b''). It uses the O(''N''<sup>2</sup>) algorithm described in Trefethen & Bau, ''Numerical Linear Algebra'', which finds the points and weights by computing the eigenvalues and eigenvectors of a real-symmetric tridiagonal matrix:
<
function gauss(a, b, N)
λ, Q = eigen(SymTridiagonal(zeros(N), [n / sqrt(4n^2 - 1) for n = 1:N-1]))
@. (λ + 1) * (b - a) / 2 + a, [2Q[1, i]^2 for i = 1:N] * (b - a) / 2
end</
(This code is a simplified version of the <code>Base.gauss</code> subroutine in the Julia standard library.)
{{out}}
Line 973 ⟶ 1,548:
=={{header|Kotlin}}==
{{trans|Java}}
<
class Legendre(val N: Int) {
Line 1,030 ⟶ 1,605:
println("compared to actual:")
println("\t%10.8f".format(exp(3.0) - exp(-3.0)))
}</
{{Out}}
<pre>Roots: 0.906180 0.538469 0.000000 -0.538469 -0.906180
Line 1,040 ⟶ 1,615:
=={{header|Lua}}==
<
local legendreRoots = {}
Line 1,108 ⟶ 1,683:
do
print(gaussLegendreQuadrature(function(x) return math.exp(x) end, -3, 3, 5))
end</
{{out}}<pre>20.035577718386</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
code assumes function to be integrated has attribute Listable which is true of most built in Mathematica functions
<
Block[{nodes, x, weights},
nodes = Cases[NSolve[LegendreP[degree, x] == 0, x], _?NumericQ, Infinity];
weights = 2 (1 - nodes^2)/(degree LegendreP[degree - 1, nodes])^2;
(b - a)/2 weights.func[(b - a)/2 nodes + (b + a)/2]]
gaussLegendreQuadrature[Exp, {-3, 3}]</syntaxhighlight>
{{out}}<pre>20.0356</pre>
=={{header|MATLAB}}==
Translated from the Python solution.
<syntaxhighlight lang="matlab">
%Print the result.
disp(GLGD_int(@(x) exp(x), -3, 3, 5));
%Integration using Gauss-Legendre quad
%Does almost the same as 'integral' in MATLAB
Line 1,199 ⟶ 1,776:
end
end
</syntaxhighlight>
{{out}}<pre>20.0356</pre>
=={{header|Maxima}}==
<
p: expand(legendre_p(n, x)),
q: expand(n/2*diff(p, x)*legendre_p(n - 1, x)),
Line 1,233 ⟶ 1,810:
% - bfloat(integrate(exp(x), x, -3, 3));
/* -1.721364342416440206515136565621888185351b-4 */</
=={{header|Nim}}==
{{trans|Common Lisp}}
<
import math, strformat
Line 1,316 ⟶ 1,893:
main()
</syntaxhighlight>
{{out}}
<pre>
Line 1,325 ⟶ 1,902:
=={{header|OCaml}}==
<
| 0 -> 1.0
| 1 -> x
Line 1,360 ⟶ 1,937:
let f1 x = f ((x*.(b-.a) +. a +. b)*.0.5) in
let eval s (x,w) = s +. w*.(f1 x) in
0.5*.(b-.a)*.(List.fold_left eval 0.0 (nodes n));;</
which can be used in:
<
Printf.printf
"Gauss-Legendre %2d-point quadrature for exp over [-3..3] = %.16f\n"
Line 1,370 ⟶ 1,947:
calc 10;;
calc 15;;
calc 20;;</
{{out}}
<pre>
Line 1,379 ⟶ 1,956:
</pre>
This shows convergence to the correct double-precision value of the integral
<
20.0357498548198052</
although going beyond 20 points starts reducing the accuracy, due to accumulated rounding errors.
=={{header|ooRexx}}==
<
* 31.10.2013 Walter Pachl Translation from REXX (from PL/I)
* using ooRexx' rxmath package
Line 1,453 ⟶ 2,030:
Return
::requires 'rxmath' LIBRARY</
Output:
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
Line 1,480 ⟶ 2,057:
{{works with|PARI/GP|2.4.2 and above}}
This task is easy in GP thanks to built-in support for Legendre polynomials and efficient (Schonhage-Gourdon) polynomial root finding.
<
my(P=pollegendre(n),Pp=P',x=polroots(P));
(b-a)*sum(i=1,n,f((b-a)*x[i]/2+(a+b)/2)/(1-x[i]^2)/subst(Pp,'x,x[i])^2)
};
# \\ Turn on timer
GLq(x->exp(x), -3, 3, 5) \\ As of version 2.4.4, this can be written GLq(exp, -3, 3, 5)</
{{out}}
<pre>time = 0 ms.
Line 1,492 ⟶ 2,069:
{{works with|PARI/GP|2.9.0 and above}}
Gauss-Legendre quadrature is built-in from 2.9 forward.
<
intnumgauss(x=-3, 3, exp(x)) \\ determine number of points automatically; all digits shown should be accurate</
{{out}}
<pre>%1 = 20.035746975092343883065457558549925374
Line 1,499 ⟶ 2,076:
=={{header|Pascal}}==
{{trans|Delphi}}
{{works with|Free Pascal|3.0.4}}
{{works with|Multics Pascal|8.0.4a}}
<syntaxhighlight lang="pascal">program Legendre(output);
const Order = 5;
Order1 = Order - 1;
Epsilon = 1E-12;
Pi = 3.1415926;
var Roots : array[0..Order1] of real;
Weight : array[0..Order1] of real;
LegCoef : array [0..Order,0..Order] of real;
I : integer;
function F(X:real) : real;
begin
F := Exp(X);
end;
procedure PrepCoef;
var I, N : integer;
begin
for I:=0 to Order do
for N := 0 to Order do
LegCoef[I,N] := 0;
LegCoef[0,0] := 1;
LegCoef[1,1] := 1;
For N:=2 to Order do
begin
LegCoef[N,0] := -(N-1) * LegCoef[N-2,0] / N;
For I := 1 to Order do
LegCoef[N,I] := ((2*N-1) * LegCoef[N-1,I-1] - (N-1)*LegCoef[N-2,I]) / N;
end;
end;
function LegEval(N:integer; X:real) : real;
var I : integer;
Result : real;
begin
Result := LegCoef[n][n];
for I := N-1 downto 0 do
Result := Result * X + LegCoef[N][I];
LegEval := Result;
end;
function LegDiff(N:integer; X:real) : real;
begin
LegDiff := N * (X * LegEval(N,X) - LegEval(N-1,X)) / (X*X-1);
end;
procedure LegRoots;
var I : integer;
X, X1 : real;
begin
for I := 1 to Order do
begin
X := Cos(Pi * (I-0.25) / (Order+0.5));
repeat
X1 := X;
X := X - LegEval(Order,X) / LegDiff(Order, X);
until Abs (X-X1) < Epsilon;
Roots[I-1] := X;
X1 := LegDiff(Order,X);
Weight[I-1] := 2 / ((1-X*X) * X1*X1);
end;
end;
function LegInt(A,B:real) : real;
var I : integer;
C1, C2, Result : real;
begin
C1 := (B-A)/2;
C2 := (B+A)/2;
Result := 0;
For I := 0 to Order-1 do
Result := Result + Weight[I] * F(C1*Roots[I] + C2);
Result := C1 * Result;
LegInt := Result;
end;
begin
PrepCoef;
LegRoots;
Write('Roots: ');
for I := 0 to Order-1 do
Write (' ',Roots[I]:13:10);
Writeln;
Write('Weight: ');
for I := 0 to Order-1 do
Write (' ', Weight[I]:13:10);
writeln;
Writeln('Integrating Exp(x) over [-3, 3]: ',LegInt(-3,3):13:10);
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
end.</syntaxhighlight>
{{out}}
<pre>
Roots: 0.9061798459 0.5384693101 0.0000000000 -0.5384693101 -0.9061798459
Weight: 0.2369268851 0.4786286705 0.5688888889 0.4786286705 0.2369268851
Integrating Exp(x) over [-3, 3]: 20.0355777184
Actual value: 20.0357498548
</pre>
=={{header|Perl}}==
{{trans|Raku}}
<
use constant pi => 3.14159265;
Line 1,572 ⟶ 2,254:
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.13f\n", $_, quadrature($_, -3, +3) )
for 5 .. 10, 20;
</syntaxhighlight>
{{out}}
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.0355777183856
Line 1,584 ⟶ 2,266:
=={{header|Phix}}==
{{trans|Lua}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">legendreRoots</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">legendreWeights</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">z</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">z</span>
<span style="color: #008080;">else</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">((</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">term</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">z</span><span style="color: #0000FF;">*</span><span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">)-(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">))/</span><span style="color: #000000;">term</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">legendreDerivative</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">z</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
<span style="color: #008080;">or</span> <span style="color: #000000;">term</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">term</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">*</span><span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">term</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">z</span><span style="color: #0000FF;">)))/(</span><span style="color: #000000;">z</span><span style="color: #0000FF;">*</span><span style="color: #000000;">z</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">getLegendreRoots</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">legendreRoots</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">index</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">order</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cos</span><span style="color: #0000FF;">(</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">index</span><span style="color: #0000FF;">-</span><span style="color: #000000;">0.25</span><span style="color: #0000FF;">)/(</span><span style="color: #000000;">order</span><span style="color: #0000FF;">+</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">y1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span>
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">legendre</span><span style="color: #0000FF;">(</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">legendreDerivative</span><span style="color: #0000FF;">(</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">2e-16</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">legendreRoots</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">y</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">getLegendreWeights</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">legendreWeights</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">index</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">order</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">lri</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">legendreRoots</span><span style="color: #0000FF;">[</span><span style="color: #000000;">index</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">diff</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">legendreDerivative</span><span style="color: #0000FF;">(</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lri</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">weight</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span> <span style="color: #0000FF;">/</span> <span style="color: #0000FF;">((</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))*</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">diff</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">legendreWeights</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">weight</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">gaussLegendreQuadrature</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lowerLimit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">upperLimit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #000000;">getLegendreRoots</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">getLegendreWeights</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">c1</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">upperLimit</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">lowerLimit</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">2</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">c2</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">upperLimit</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">lowerLimit</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">/</span> <span style="color: #000000;">2</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">order</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">legendreWeights</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c1</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">legendreRoots</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">c2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">c1</span> <span style="color: #0000FF;">*</span> <span style="color: #000000;">s</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">machine_bits</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">32</span><span style="color: #0000FF;">?</span><span style="color: #008000;">"%.13f"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"%.14f"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">11</span> <span style="color: #008080;">by</span> <span style="color: #000000;">6</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">gaussLegendreQuadrature</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">exp</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"roots:"</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">legendreRoots</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"weights:"</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">legendreWeights</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Gauss-Legendre %2d-point quadrature for exp over [-3..3] = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">exp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)-</span><span style="color: #7060A8;">exp</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" compared to actual = %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,675 ⟶ 2,356:
=={{header|PL/I}}==
Translated from Fortran.
<
Integration_Gauss: procedure options (main);
Line 1,729 ⟶ 2,410:
end gaussquad;
end Integration_Gauss;
</syntaxhighlight>
<pre>
1 6.0000000000000000 -1.40E+0001
Line 1,758 ⟶ 2,439:
=={{header|Python}}==
{{libheader|NumPy}}
<
##################################################################
Line 1,854 ⟶ 2,535:
print "Integral : ", ans
else:
print "Integral evaluation failed"</
{{out}}
<pre>
Line 1,862 ⟶ 2,543:
Integral : 20.0355777184
</pre>
===With library routine===
One can also use the already invented wheel in NumPy:
<syntaxhighlight lang="python">import numpy as np
# func is a function that takes a list-like input values
def gauss_legendre_integrate(func, domain, deg):
x, w = np.polynomial.legendre.leggauss(deg)
s = (domain[1] - domain[0])/2
a = (domain[1] + domain[0])/2
return np.sum(s*w*func(s*x + a))
for d in range(3, 10):
print(d, gauss_legendre_integrate(np.exp, [-3, 3], d))</syntaxhighlight>
{{out}}
<pre>3 19.853691996805587
4 20.028688395290693
5 20.035577718385575
6 20.035746975092323
7 20.03574981972664
8 20.035749854494522
9 20.03574985481744</pre>
=={{header|Racket}}==
Line 1,867 ⟶ 2,569:
Computation of the Legendre polynomials and derivatives:
<
(define (LegendreP n x)
(let compute ([n n] [Pn-1 x] [Pn-2 1])
Line 1,882 ⟶ 2,584:
(- (* x (LegendreP n x))
(LegendreP (- n 1) x))))
</syntaxhighlight>
Computation of the Legendre polynomial roots:
<
(define (LegendreP-root n i)
; newton-raphson step
Line 1,900 ⟶ 2,602:
x′
(next (newton-step x′) x′)))))
</syntaxhighlight>
Computation of Gauss-Legendre nodes and weights
<
(define (Gauss-Legendre-quadrature n)
;; positive roots
Line 1,921 ⟶ 2,623:
(if (odd? n) (list (/ 2 (sqr (LegendreP′ n 0)))) '())
(reverse weights))))
</syntaxhighlight>
Integration using Gauss-Legendre quadratures:
<
(define (integrate f a b #:nodes (n 5))
(define m (/ (+ a b) 2))
Line 1,932 ⟶ 2,634:
(define (g x) (f (+ m (* d x))))
(* d (+ (apply + (map * w (map g x))))))
</syntaxhighlight>
Usage:
<
> (Gauss-Legendre-quadrature 5)
'(-0.906179845938664 -0.5384693101056831 0 0.5384693101056831 0.906179845938664)
Line 1,946 ⟶ 2,648:
> (- (exp 3) (exp -3)
20.035749854819805
</syntaxhighlight>
Accuracy of the method:
<
> (require plot)
> (parameterize ([plot-x-label "Number of Gaussian nodes"]
Line 1,959 ⟶ 2,661:
(list n (abs (- (integrate exp -3 3 #:nodes n)
(- (exp 3) (exp -3)))))))))
</syntaxhighlight>
[[File:gauss.png]]
Line 1,972 ⟶ 2,674:
Note: The calculations of Pn(x) and P'n(x) could be combined to further reduce duplicated effort. We also could cache P'n(x) from the last Newton-Raphson step for the weight calculation.
<syntaxhighlight lang="raku"
multi legendre-pair(Int $n, $x) {
my ($m1, $m2) = legendre-pair($n - 1, $x);
Line 2,026 ⟶ 2,728:
say "Gauss-Legendre $_.fmt('%2d')-point quadrature ∫₋₃⁺³ exp(x) dx ≈ ",
quadrature($_, &exp, -3, +3) for flat 5 .. 10, 20;</
{{out}}
Line 2,039 ⟶ 2,741:
=={{header|REXX}}==
===version 1===
<
* 31.10.2013 Walter Pachl Translation from PL/I
* 01.11.2014 -"- see Version 2 for improvements
Line 2,152 ⟶ 2,854:
End
Numeric Digits (prec)
Return r+0</
Output:
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
Line 2,204 ⟶ 2,906:
<br>where there's practically no space on the right side of the REXX source statements. It presents a good
<br>visual indication of what's what, but it's the dickens to pay when updating the source code.
<
pi= pi(); digs= length(pi) -
!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs
trueV= exp(b)-exp(a); bpa= b + a; bpaH= bpa / 2
Line 2,212 ⟶ 2,915:
sep='──────' copies("─", digs+3) '─────────────'; say sep /* " sep*/
do #=1 until dif>0;
/*█*/ do k=2 to #; km= k - 1
/*█*/
/*█*/
/*█*/
/*█*/
/*█*/ p1z= p1z + 1; do p=1 for p1z; p1.p= T.p ; end /*p*/
/*█*/ end /*k*/
/*▓*/
/*▓*/ /*░*/ do reps until abs(dx) <= tiny
/*▓*/ /*░*/ f= p1.1; df=
/*▓*/ /*░*/
/*▓*/
/*▓*/
/*▓*/
/*▓*/ r.1.!=
/*▓*/
/*▓*/ end
$= 0
/*▒*/
z= bmaH * $ /*calculate target value (Z)*/
dif= z - trueV;
Ndif= translate( format(dif, 3, 4, 2, 0), 'e', "E")
if #\==1 then say center(#, 6) z' ' Ndif /*no display if not computed*/
Line 2,242 ⟶ 2,945:
say 'Using ' digs " digit precision, the" ,
'N-point Gauss─Legendre quadrature (GLQ) had an accuracy of ' xdif-2 " digits."
exit
/*───────────────────────────────────────────────────────────────────────────────────────────*/
e: return 2.718281828459045235360287471352662497757247093699959574966967627724076630353547595
Line 2,251 ⟶ 2,954:
/*───────────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1
_=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix</
{{out|output|text= when using the default inputs:}}
<pre>
Line 2,295 ⟶ 2,998:
===version 3, more precision===
This REXX version is almost an exact copy of REXX version 2, but with
It is about twice as slow as version 2, due to the
<
pi= pi(); digs= length(pi) -
!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs
trueV= exp(b)-exp(a); bpa= b + a; bpaH= bpa / 2
Line 2,306 ⟶ 3,009:
sep='──────' copies("─", digs+3) '─────────────'; say sep /* " sep*/
do #=1 until dif>0;
/*█*/ do k=2 to #; km= k - 1
/*█*/
/*█*/
/*█*/
/*█*/
/*█*/ p1z= p1z + 1; do p=1 for p1z; p1.p= T.p ; end /*p*/
/*█*/ end /*k*/
/*▓*/
/*▓*/ /*░*/ do reps until abs(dx) <= tiny
/*▓*/ /*░*/ f= p1.1; df=
/*▓*/ /*░*/
/*▓*/
/*▓*/
/*▓*/
/*▓*/ r.1.!=
/*▓*/
/*▓*/ end
$= 0
/*▒*/
z= bmaH * $ /*calculate target value (Z)*/
dif= z - trueV;
Ndif= translate( format(dif, 3, 4, 3, 0), 'e', "E")
if #\==1 then say center(#, 6) z' ' Ndif /*no display if not computed*/
Line 2,336 ⟶ 3,039:
say 'Using ' digs " digit precision, the" ,
'N-point Gauss─Legendre quadrature (GLQ) had an accuracy of ' xdif-2 " digits."
exit
/*───────────────────────────────────────────────────────────────────────────────────────────*/
e: return 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759,
||457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794
/*───────────────────────────────────────────────────────────────────────────────────────────*/
pi: return 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899,
||862803482534211706798214808651328230664709384460955058223172535940812848111745028410270194
/*───────────────────────────────────────────────────────────────────────────────────────────*/
cos: procedure expose !.; parse arg x; if !.x\==. then return !.x; _= 1; z=1; y= x*x
Line 2,354 ⟶ 3,051:
/*───────────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1
_=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix</
{{out|output|text= when using the default inputs:}}
(Shown at about two-thirds size.)
<pre style="font-size:67%">
step iterate value (with
────── ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ─────────────
2 17.4874646410555689643606840462449458421154284179349135091487247059537916662378882444064336021640614626063744948781912964250403870127054497392082425535068464109311173377377 -2.5483
3 19.8536919968055821921309108927158495960774667319753888929050027075848592516449832906645902758379575999249091274157148988582792112906526877518087112700785494497813902725450 -1.8206e-001
4 20.0286883952907008527738054439857661647073363250481518077257887668521514648379218096268747927750038360903142778646220077613647092768733641727539206268833693587721944236294 -7.0615e-003
5 20.0355777183855621539285357252750939315016272074471283081673242529514166130221254213250349496939691709537643294259047823350162410908440808868981982394287542087129417151006 -1.7214e-004
6 20.0357469750923438830654575585499253741529947892197512571761670590022501037527117346339483928363770582109285164930728028479549289382406446621705905363209981936742762651248 -2.8797e-006
7 20.0357498197266007755718729372891903369400657532378489130759167634362318526784010016150667027038415189719144094529764766032097831604495667799067330556673881537789420232152 -3.5093e-008
8 20.0357498544945172882260918041683132616236752579944055100693304551390338045262089091194019302017562870527315644307417688383478919210145963055448428522264642589709805903057 -3.2529e-010
9 20.0357498548174338368864419454858704839263168086955797931292590585320198342940085570553927472311015418220675609961921140415760514983040167737226050690228927266115828876520 -2.3700e-012
10 20.0357498548197898711175766908543458234008349625446568080936795730938134205900980645938318794902592556558231569959762420203929344018773329199723457149763574278017459859529 -1.3927e-014
11 20.0357498548198037305529147159697031241993516306485175808291929207610544866584568009626862857221858328844106864371425322111609007302709732793823163103980149601875492907998 -6.7396e-017
12 20.0357498548198037976759531014454017742327138984429607438017578771715767588391691509175808718708593063121709896967107496243434245185896147055314894150234262032514577087792 -2.7323e-019
13 20.0357498548198037979482458119092690701862659228785307035583081473361900008835808932495328864420024278695427964698380448330606714160259282675390182203803538192726572599929 -9.4143e-022
14 20.0357498548198037979491844483599375945130148356706886332919441446027039132743905494286471338717783707421873433644754993992655580745072286831502363474798170771121237677390 -2.7906e-024
15 20.0357498548198037979491872317401917248452734118643091749897281356338832738714150881537113815780435230011480697467170623887897830301712412973655748924184136940242004265158 -7.1915e-027
16 20.0357498548198037979491872389153958789316129464894982848020715833786709121310547889685984881568546203564135185474792767674806869872650180714616455691318785641503320488704 -1.6260e-029
17 20.0357498548198037979491872389316236038179252557440453906282250905385221873347716826354198555233437240574026019817833907372014036252533047705435353247648512336234642790641 -3.2517e-032
18 20.0357498548198037979491872389316560624360571301484111974244019477736095885421361807599231231543821951618639462965984321643251022835234451110049047608124964855646728491571 -5.7920e-035
19 20.0357498548198037979491872389316561202637283172074241556158972833578634894365092635000776399956033063018069653085902399896542171129596405210008317497301938111107401607602 -9.2480e-038
20 20.0357498548198037979491872389316561203560751340857503751994442223163866912408434007886096643419528065940077022083150476496426837665378721283432879108630829513249759484353 -1.3311e-040
21 20.0357498548198037979491872389316561203562080727616463861143647576984994047530870779393715057751591887673397688454357985082021265151278191050057935329724914648356586984041 -1.7360e-043
22 20.0357498548198037979491872389316561203562082461596244537077863602238433892612703628843743785373313737563806457244053157873973239947461987202443878362980281616080907191625 -2.0610e-046
23 20.0357498548198037979491872389316561203562082463655032534484950691669880046406047078766996078695370527223056578914332723730363863326194707715142045831095238426102807682133 -2.2368e-049
24 20.0357498548198037979491872389316561203562082463657267060509015976314523758814742624773428457390528961843568960502876896215809857825164102337905868347722728364661655423691 -2.2276e-052
25 20.0357498548198037979491872389316561203562082463657269286070017882824923688080311511389836619043005851350331110867389220628954338053656628671036072512304656757933297348289 -2.0430e-055
26 20.0357498548198037979491872389316561203562082463657269288111333795426189423729667519158562143832977811003145168351321839626313132075697513253761673496847193697358302206599 -1.7312e-058
27 20.0357498548198037979491872389316561203562082463657269288113063661454822050198926197665008333893008724687497228278730367375441075263700413282548634210893951621431572014401 -1.3595e-061
28 20.0357498548198037979491872389316561203562082463657269288113065019935786483820352375621786828318969009163053743757325024448325026804644277866300802833735429200407643132066 -9.9207e-065
29 20.0357498548198037979491872389316561203562082463657269288113065020927177593233999249852447888627901300469719564790181325442944469692690797774430312247184030485560959159838 -6.7451e-068
30 20.0357498548198037979491872389316561203562082463657269288113065020927851675301934062025341716601075750412806887227020916063849030412480955063639628314158527843447097540104 -4.2832e-071
31 20.0357498548198037979491872389316561203562082463657269288113065020927852103363148863217394106431702791915956948972366384835732103508918001327415359845732098066185095970907 -2.5459e-074
32 20.0357498548198037979491872389316561203562082463657269288113065020927852103617599854934274435013875248206413049448382025586066461615726348079942124358556139880490254984356 -1.4196e-077
33 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741736109635347323907131494641377410353985987829217992622815976248321175867964752131506800051 -7.4395e-081
34 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810467715704772209566910717933633388969835872983190631663850670877761750073036465167190394 -3.6713e-084
35 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504412069378446854036859408497315019337333762510854198446941961781825098514532469683329 -1.7091e-087
36 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429152646383719980280460795167918691617029439367737607466797188696985999193933984760 -7.5175e-091
37 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160160714391043273984198489693834991216803247954607301723484371150995472545047773 -3.1292e-094
38 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163842341789925349746540298990681930753381942866562579916746319742876113289347 -1.2345e-097
39 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843575809851614709658383098559963930599249691243551258257666303808499450058 -4.6221e-101
40 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576271898405984614568086424291240202255560215708382127745410021921505433 -1.6447e-104
41 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062816325200556739918251890227721352129417700490117766374046259608 -5.5685e-108
42 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062871992591098295378332977741979460337046289653292852558991470138 -1.7962e-111
43 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010547683152388008632372342584044010171728180146818963258851 -5.5262e-115
44 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553207686109280576604524821212783897594720674601807871384 -1.6234e-118
45 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309007883789778553235095566868388697120439100484887 -4.5581e-122
46 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463568475856093621234235103013989004662708710524 -1.2245e-125
47 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690894669420459180906124959094321731281026582 -3.1504e-129
48 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926165554457660180369582395139692931382774 -7.7695e-133
49 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173322092766618204788515060681700867922 -1.8383e-136
50 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323930673674948485214173181944866992 -4.1766e-140
51 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091242430000931491744551038314 -9.1189e-144
52 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091333599358956493201909187002 -1.9148e-147
53 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091333618502674999936415396203 -3.9287e-151
54 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091333618506574837300809273433 -2.8877e-153
55 20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091333618507014523492331476840 4.1081e-152
────── ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ─────────────
↑
20.0357498548198037979491872389316561203562082463657269288113065020927852103617741810504429160163843576272062872010553209309463690926173323931091333618506603713959668429768 {exact value}
Using
</pre>
=={{header|Scala}}==
{{Out}}Best seen in running your browser either by [https://scalafiddle.io/sf/rrvzhH1/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/yYqRqizfSZip2DhYbdfZ2w Scastie (remote JVM)].
<
object GaussLegendreQuadrature extends App {
Line 2,470 ⟶ 3,169:
println(f"compared to actual%n\t${exp(3) - exp(-3)}%10.8f")
}</
=={{header|Sidef}}==
{{trans|
<
func legendre_pair( n, x) {
var (m1, m2) = legendre_pair(n - 1, x)
Line 2,533 ⟶ 3,232:
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.15f\n",
i, quadrature(i, {.exp}, -3, +3))
}</
{{out}}
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.035577718385561
Line 2,548 ⟶ 3,247:
{{tcllib|math::polynomials}}
{{tcllib|math::special}}
<
package require math::special
package require math::polynomials
Line 2,610 ⟶ 3,309:
}
expr {$sum * $rangesize2}
}</
Demonstrating:
<
puts "weights(5) = [weights [nodes 5]]"
set exp {x {expr {exp($x)}}}
puts "int(exp,-3,3) = [gausslegendreintegrate $exp 5 -3 3]"</
{{out}}
<pre>
Line 2,625 ⟶ 3,324:
=={{header|Ursala}}==
using arbitrary precision arithmetic
<
#import nat
Line 2,658 ⟶ 3,357:
mp..shrink^/~& difference\"p"+ mp..prec,
mp..mul^|/~& mp..add:-0E0+ * mp..mul^/~&rr ^H/~&ll mp..add^\~&lrr mp..mul@lrPrXl,
^(~&rl,-*nodes("p","n"))^|/~& mp..vid~~G/2E0+ ^/mp..bus mp..add+-</
demonstration program:<
demo =
Line 2,665 ⟶ 3,364:
~&lNrCT (
^|lNrCT(:/'nodes:',:/'weights:')@lSrSX ..mp2str~~* nodes/160 5,
:/'integral:' ~&iNC ..mp2str integral(160,5) (mp..exp,-3E0,3E0))</
{{out}}
<pre>
Line 2,684 ⟶ 3,383:
integral:
2.0035577718385562153928535725275093931501627207110E+01</pre>
=={{header|Wren}}==
{{trans|C}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
var N = 5
var lroots = List.filled(N, 0)
var weight = List.filled(N, 0)
var lcoef = List.filled(N+1, null)
for (i in 0..N) lcoef[i] = List.filled(N + 1, 0)
var legeCoef = Fn.new {
lcoef[0][0] = lcoef[1][1] = 1
for (n in 2..N) {
lcoef[n][0] = -(n-1) * lcoef[n -2][0] / n
for (i in 1..n) {
lcoef[n][i] = ((2*n - 1) * lcoef[n-1][i-1] - (n - 1) * lcoef[n-2][i]) / n
}
}
}
var legeEval = Fn.new { |n, x| (n..1).reduce(lcoef[n][n]) { |s, i| s*x + lcoef[n][i-1] } }
var legeDiff = Fn.new { |n, x|
return n * (x * legeEval.call(n, x) - legeEval.call(n-1, x)) / (x*x - 1)
}
var legeRoots = Fn.new {
var x = 0
var x1 = 0
for (i in 1..N) {
x = (Num.pi * (i - 0.25) / (N + 0.5)).cos
while (true) {
x1 = x
x = x - legeEval.call(N, x) / legeDiff.call(N, x)
if (x == x1) break
}
lroots[i-1] = x
x1 = legeDiff.call(N, x)
weight[i-1] = 2 / ((1 - x*x) * x1 * x1)
}
}
var legeIntegrate = Fn.new { |f, a, b|
var c1 = (b - a) / 2
var c2 = (b + a) / 2
var sum = 0
for (i in 0...N) sum = sum + weight[i] * f.call(c1*lroots[i] + c2)
return c1 * sum
}
legeCoef.call()
legeRoots.call()
System.write("Roots: ")
for (i in 0...N) Fmt.write(" $f", lroots[i])
System.write("\nWeight:")
for (i in 0...N) Fmt.write(" $f", weight[i])
var f = Fn.new { |x| x.exp }
var actual = 3.exp - (-3).exp
Fmt.print("\nIntegrating exp(x) over [-3, 3]:\n\t$10.8f,\n" +
"compared to actual\n\t$10.8f", legeIntegrate.call(f, -3, 3), actual)</syntaxhighlight>
{{out}}
<pre>
Roots: 0.906180 0.538469 0.000000 -0.538469 -0.906180
Weight: 0.236927 0.478629 0.568889 0.478629 0.236927
Integrating exp(x) over [-3, 3]:
20.03557772,
compared to actual
20.03574985
</pre>
=={{header|zkl}}==
{{trans|
<
if(n==1) return(x,1.0);
m1,m2:=legendrePair(n-1,x);
Line 2,731 ⟶ 3,505:
scale:='wrap(x){ (x*(b - a) + a + b) / 2 };
nds.reduce('wrap(p,[(r,w)]){ p + w*f(scale(r)) },0.0) * (b - a)/2
}</
<
("Gauss-Legendre %2d-point quadrature "
"\U222B;\U208B;\U2083;\U207A;\UB3; exp(x) dx = %.13f")
.fmt(n,quadrature(n, fcn(x){ x.exp() }, -3, 3))
})</
{{out}}
<pre>
|