Numerical integration/Gauss-Legendre Quadrature: Difference between revisions

Content added Content deleted
(→‎{{header|Python}}: added new code using numpy polynomial library)
m (syntax highlighting fixup automation)
Line 51: Line 51:
{{trans|Nim}}
{{trans|Nim}}


<lang 11l>F legendreIn(x, n)
<syntaxhighlight lang="11l">F legendreIn(x, n)
F prev1(idx, pn1)
F prev1(idx, pn1)
R (2 * idx - 1) * @x * pn1
R (2 * idx - 1) * @x * pn1
Line 120: Line 120:
R result * sum
R result * sum


print(‘integral: ’integ(x -> exp(x), 5, -3, 3))</lang>
print(‘integral: ’integ(x -> exp(x), 5, -3, 3))</syntaxhighlight>


{{out}}
{{out}}
Line 131: Line 131:
=={{header|Axiom}}==
=={{header|Axiom}}==
{{trans|Maxima}}
{{trans|Maxima}}
Axiom provides Legendre polynomials and related solvers.<lang Axiom>NNI ==> NonNegativeInteger
Axiom provides Legendre polynomials and related solvers.<syntaxhighlight lang="axiom">NNI ==> NonNegativeInteger
RECORD ==> Record(x : List Fraction Integer, w : List Fraction Integer)
RECORD ==> Record(x : List Fraction Integer, w : List Fraction Integer)


Line 150: Line 150:
c := (a+b)/2
c := (a+b)/2
h := (b-a)/2
h := (b-a)/2
h*reduce(+,[wi*subst(e,var=c+xi*h) for xi in u.x for wi in u.w])</lang>Example:<lang Axiom>digits(50)
h*reduce(+,[wi*subst(e,var=c+xi*h) for xi in u.x for wi in u.w])</syntaxhighlight>Example:<syntaxhighlight lang="axiom">digits(50)
gaussIntegrate(4/(1+x^2), x=0..1, 20)
gaussIntegrate(4/(1+x^2), x=0..1, 20)


Line 157: Line 157:
% - %pi
% - %pi


(2) - 0.3463549483_9378821092_475 E -26</lang>
(2) - 0.3463549483_9378821092_475 E -26</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
<lang C>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
#include <math.h>


Line 243: Line 243:
lege_inte(exp, -3, 3), exp(3) - exp(-3));
lege_inte(exp, -3, 3), exp(3) - exp(-3));
return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Roots: 0.90618 0.538469 0 -0.538469 -0.90618
<pre>Roots: 0.90618 0.538469 0 -0.538469 -0.90618
Line 256: Line 256:


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.
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.
<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <iomanip>
#include <iomanip>
#include <cmath>
#include <cmath>
Line 395: Line 395:
std::cout << "Integrating Exp(X) over [-3, 3]: " << gl5.integrate(-3., 3., RosettaExp) << std::endl;
std::cout << "Integrating Exp(X) over [-3, 3]: " << gl5.integrate(-3., 3., RosettaExp) << std::endl;
std::cout << "Actual value: " << RosettaExp(3) - RosettaExp(-3) << std::endl;
std::cout << "Actual value: " << RosettaExp(3) - RosettaExp(-3) << std::endl;
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 408: Line 408:
Derived from the C++ and Java versions here.
Derived from the C++ and Java versions here.


<lang csharp>
<syntaxhighlight lang="csharp">
using System;
using System;
//Works in .NET 6+
//Works in .NET 6+
Line 495: Line 495:




}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 508: Line 508:


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>;; Computes the initial guess for the root i of a n-order Legendre polynomial.
<syntaxhighlight lang="lisp">;; Computes the initial guess for the root i of a n-order Legendre polynomial.
(defun guess (n i)
(defun guess (n i)
(cos (* pi
(cos (* pi
Line 570: Line 570:
(funcall f (+ (* (/ (- b a) 2.0d0)
(funcall f (+ (* (/ (- b a) 2.0d0)
(aref x i))
(aref x i))
(/ (+ a b) 2.0d0))))))))</lang>
(/ (+ a b) 2.0d0))))))))</syntaxhighlight>
{{out|Example}}
{{out|Example}}
<lang lisp>(nodes 5)
<syntaxhighlight lang="lisp">(nodes 5)
#(0.906179845938664d0 0.5384693101056831d0 2.996272867003007d-95 -0.5384693101056831d0 -0.906179845938664d0)
#(0.906179845938664d0 0.5384693101056831d0 2.996272867003007d-95 -0.5384693101056831d0 -0.906179845938664d0)


Line 579: Line 579:


(int #'exp 5 -3 3)
(int #'exp 5 -3 3)
20.035577718385568d0</lang>
20.035577718385568d0</syntaxhighlight>
Comparison of the 5-point rule with simpler, but more costly methods from the task [[Numerical Integration]]:
Comparison of the 5-point rule with simpler, but more costly methods from the task [[Numerical Integration]]:
<lang lisp>(int #'(lambda (x) (expt x 3)) 5 0 1)
<syntaxhighlight lang="lisp">(int #'(lambda (x) (expt x 3)) 5 0 1)
0.24999999999999997d0
0.24999999999999997d0


Line 591: Line 591:


(int #'(lambda (x) x) 5 0 6000)
(int #'(lambda (x) x) 5 0 6000)
1.8000000000000004d7</lang>
1.8000000000000004d7</syntaxhighlight>


=={{header|D}}==
=={{header|D}}==
{{trans|C}}
{{trans|C}}
<lang d>import std.stdio, std.math;
<syntaxhighlight lang="d">import std.stdio, std.math;


immutable struct GaussLegendreQuadrature(size_t N, FP=double,
immutable struct GaussLegendreQuadrature(size_t N, FP=double,
Line 668: Line 668:
writefln("Compred to actual: %10.12f",
writefln("Compred to actual: %10.12f",
3.0.exp - exp(-3.0));
3.0.exp - exp(-3.0));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Roots: [0.90618, 0.538469, 0, -0.538469, -0.90618]
<pre>Roots: [0.90618, 0.538469, 0, -0.538469, -0.90618]
Line 677: Line 677:
=={{header|Delphi}}==
=={{header|Delphi}}==


<lang Delphi>program Legendre;
<syntaxhighlight lang="delphi">program Legendre;


{$APPTYPE CONSOLE}
{$APPTYPE CONSOLE}
Line 770: Line 770:
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
Readln;
Readln;
end.</lang>
end.</syntaxhighlight>


<pre>
<pre>
Line 780: Line 780:


=={{header|Fortran}}==
=={{header|Fortran}}==
<lang Fortran>! Works with gfortran but needs the option
<syntaxhighlight lang="fortran">! Works with gfortran but needs the option
! -assume realloc_lhs
! -assume realloc_lhs
! when compiled with Intel Fortran.
! when compiled with Intel Fortran.
Line 831: Line 831:
end function
end function
end program
end program
</syntaxhighlight>
</lang>


<pre>
<pre>
Line 860: Line 860:
=={{header|Go}}==
=={{header|Go}}==
Implementation pretty much by the methods given in the task description.
Implementation pretty much by the methods given in the task description.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 955: Line 955:
}
}
panic("no convergence")
panic("no convergence")
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 965: Line 965:
=={{header|Haskell}}==
=={{header|Haskell}}==
Integration formula
Integration formula
<lang haskell>gaussLegendre n f a b = d*sum [ w x*f(m + d*x) | x <- roots ]
<syntaxhighlight lang="haskell">gaussLegendre n f a b = d*sum [ w x*f(m + d*x) | x <- roots ]
where d = (b - a)/2
where d = (b - a)/2
m = (b + a)/2
m = (b + a)/2
w x = 2/(1-x^2)/(legendreP' n x)^2
w x = 2/(1-x^2)/(legendreP' n x)^2
roots = map (findRoot (legendreP n) (legendreP' n) . x0) [1..n]
roots = map (findRoot (legendreP n) (legendreP' n) . x0) [1..n]
x0 i = cos (pi*(i-1/4)/(n+1/2))</lang>
x0 i = cos (pi*(i-1/4)/(n+1/2))</syntaxhighlight>


Calculation of Legendre polynomials
Calculation of Legendre polynomials
<lang haskell>legendreP n x = go n 1 x
<syntaxhighlight lang="haskell">legendreP n x = go n 1 x
where go 0 p2 _ = p2
where go 0 p2 _ = p2
go 1 _ p1 = p1
go 1 _ p1 = p1
go n p2 p1 = go (n-1) p1 $ ((2*n-1)*x*p1 - (n-1)*p2)/n
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)</lang>
legendreP' n x = n/(x^2-1)*(x*legendreP n x - legendreP (n-1) x)</syntaxhighlight>


Universal auxilary functions
Universal auxilary functions
<lang haskell>findRoot f df = fixedPoint (\x -> x - f x / df x)
<syntaxhighlight lang="haskell">findRoot f df = fixedPoint (\x -> x - f x / df x)


fixedPoint f x | abs (fx - x) < 1e-15 = x
fixedPoint f x | abs (fx - x) < 1e-15 = x
| otherwise = fixedPoint f fx
| otherwise = fixedPoint f fx
where fx = f x</lang>
where fx = f x</syntaxhighlight>


Integration on a given mesh using Gauss-Legendre quadrature:
Integration on a given mesh using Gauss-Legendre quadrature:
<lang haskell>integrate _ [] = 0
<syntaxhighlight lang="haskell">integrate _ [] = 0
integrate f (m:ms) = sum $ zipWith (gaussLegendre 5 f) (m:ms) ms</lang>
integrate f (m:ms) = sum $ zipWith (gaussLegendre 5 f) (m:ms) ms</syntaxhighlight>


{{out}}
{{out}}
Line 1,006: Line 1,006:
=={{header|J}}==
=={{header|J}}==
'''Solution:'''
'''Solution:'''
<lang j>NB. returns coefficents for yth-order Legendre polynomial
<syntaxhighlight lang="j">NB. returns coefficents for yth-order Legendre polynomial
getLegendreCoeffs=: verb define M.
getLegendreCoeffs=: verb define M.
if. y<:1 do. 1 {.~ - y+1 return. end.
if. y<:1 do. 1 {.~ - y+1 return. end.
Line 1,022: Line 1,022:
'nodes wgts'=. getGaussLegendrePoints x
'nodes wgts'=. getGaussLegendrePoints x
-: (-~/ y) * wgts +/@:* u -: nodes p.~ (+/ , -~/) y
-: (-~/ y) * wgts +/@:* u -: nodes p.~ (+/ , -~/) y
)</lang>
)</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang j> 5 ^ integrateGaussLegendre _3 3
<syntaxhighlight lang="j"> 5 ^ integrateGaussLegendre _3 3
20.0356
20.0356
-~/ ^ _3 3 NB. true value
-~/ ^ _3 3 NB. true value
20.0357</lang>
20.0357</syntaxhighlight>


=={{header|Java}}==
=={{header|Java}}==
{{trans|C}}
{{trans|C}}
{{works with|Java|8}}
{{works with|Java|8}}
<lang java>import static java.lang.Math.*;
<syntaxhighlight lang="java">import static java.lang.Math.*;
import java.util.function.Function;
import java.util.function.Function;


Line 1,106: Line 1,106:
legeInte(x -> exp(x), -3, 3), exp(3) - exp(-3));
legeInte(x -> exp(x), -3, 3), exp(3) - exp(-3));
}
}
}</lang>
}</syntaxhighlight>
<pre>Roots: 0,906180 0,538469 0,000000 -0,538469 -0,906180
<pre>Roots: 0,906180 0,538469 0,000000 -0,538469 -0,906180
Weight: 0,236927 0,478629 0,568889 0,478629 0,236927
Weight: 0,236927 0,478629 0,568889 0,478629 0,236927
Line 1,115: Line 1,115:


=={{header|JavaScript}}==
=={{header|JavaScript}}==
<lang javascript>
<syntaxhighlight lang="javascript">
const factorial = n => n <= 1 ? 1 : n * factorial(n - 1);
const factorial = n => n <= 1 ? 1 : n * factorial(n - 1);
const M = n => (n - (n % 2 !== 0)) / 2;
const M = n => (n - (n % 2 !== 0)) / 2;
Line 1,135: Line 1,135:
}
}
console.log(gaussLegendre(x => Math.exp(x), -3, 3, 5));
console.log(gaussLegendre(x => Math.exp(x), -3, 3, 5));
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 1,143: Line 1,143:
=={{header|Julia}}==
=={{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:
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:
<lang julia>using LinearAlgebra
<syntaxhighlight lang="julia">using LinearAlgebra


function gauss(a, b, N)
function gauss(a, b, N)
λ, Q = eigen(SymTridiagonal(zeros(N), [n / sqrt(4n^2 - 1) for n = 1:N-1]))
λ, 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
@. (λ + 1) * (b - a) / 2 + a, [2Q[1, i]^2 for i = 1:N] * (b - a) / 2
end</lang>
end</syntaxhighlight>
(This code is a simplified version of the <code>Base.gauss</code> subroutine in the Julia standard library.)
(This code is a simplified version of the <code>Base.gauss</code> subroutine in the Julia standard library.)
{{out}}
{{out}}
Line 1,161: Line 1,161:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<lang scala>import java.lang.Math.*
<syntaxhighlight lang="scala">import java.lang.Math.*


class Legendre(val N: Int) {
class Legendre(val N: Int) {
Line 1,218: Line 1,218:
println("compared to actual:")
println("compared to actual:")
println("\t%10.8f".format(exp(3.0) - exp(-3.0)))
println("\t%10.8f".format(exp(3.0) - exp(-3.0)))
}</lang>
}</syntaxhighlight>
{{Out}}
{{Out}}
<pre>Roots: 0.906180 0.538469 0.000000 -0.538469 -0.906180
<pre>Roots: 0.906180 0.538469 0.000000 -0.538469 -0.906180
Line 1,228: Line 1,228:


=={{header|Lua}}==
=={{header|Lua}}==
<lang Lua>local order = 0
<syntaxhighlight lang="lua">local order = 0


local legendreRoots = {}
local legendreRoots = {}
Line 1,296: Line 1,296:
do
do
print(gaussLegendreQuadrature(function(x) return math.exp(x) end, -3, 3, 5))
print(gaussLegendreQuadrature(function(x) return math.exp(x) end, -3, 3, 5))
end</lang>
end</syntaxhighlight>
{{out}}<pre>20.035577718386</pre>
{{out}}<pre>20.035577718386</pre>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
code assumes function to be integrated has attribute Listable which is true of most built in Mathematica functions
code assumes function to be integrated has attribute Listable which is true of most built in Mathematica functions
<lang Mathematica>gaussLegendreQuadrature[func_, {a_, b_}, degree_: 5] :=
<syntaxhighlight lang="mathematica">gaussLegendreQuadrature[func_, {a_, b_}, degree_: 5] :=
Block[{nodes, x, weights},
Block[{nodes, x, weights},
nodes = Cases[NSolve[LegendreP[degree, x] == 0, x], _?NumericQ, Infinity];
nodes = Cases[NSolve[LegendreP[degree, x] == 0, x], _?NumericQ, Infinity];
weights = 2 (1 - nodes^2)/(degree LegendreP[degree - 1, nodes])^2;
weights = 2 (1 - nodes^2)/(degree LegendreP[degree - 1, nodes])^2;
(b - a)/2 weights.func[(b - a)/2 nodes + (b + a)/2]]
(b - a)/2 weights.func[(b - a)/2 nodes + (b + a)/2]]
gaussLegendreQuadrature[Exp, {-3, 3}]</lang>
gaussLegendreQuadrature[Exp, {-3, 3}]</syntaxhighlight>
{{out}}<pre>20.0356</pre>
{{out}}<pre>20.0356</pre>


=={{header|MATLAB}}==
=={{header|MATLAB}}==
Translated from the Python solution.
Translated from the Python solution.
<syntaxhighlight lang="matlab">
<lang MATLAB>
%Print the result.
%Print the result.
disp(GLGD_int(@(x) exp(x), -3, 3, 5));
disp(GLGD_int(@(x) exp(x), -3, 3, 5));
Line 1,389: Line 1,389:
end
end
end
end
</syntaxhighlight>
</lang>
{{out}}<pre>20.0356</pre>
{{out}}<pre>20.0356</pre>


=={{header|Maxima}}==
=={{header|Maxima}}==
<lang maxima>gauss_coeff(n) := block([p, q, v, w],
<syntaxhighlight lang="maxima">gauss_coeff(n) := block([p, q, v, w],
p: expand(legendre_p(n, x)),
p: expand(legendre_p(n, x)),
q: expand(n/2*diff(p, x)*legendre_p(n - 1, x)),
q: expand(n/2*diff(p, x)*legendre_p(n - 1, x)),
Line 1,423: Line 1,423:
% - bfloat(integrate(exp(x), x, -3, 3));
% - bfloat(integrate(exp(x), x, -3, 3));
/* -1.721364342416440206515136565621888185351b-4 */</lang>
/* -1.721364342416440206515136565621888185351b-4 */</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
{{trans|Common Lisp}}
{{trans|Common Lisp}}
<lang nim>
<syntaxhighlight lang="nim">
import math, strformat
import math, strformat


Line 1,506: Line 1,506:


main()
main()
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,515: Line 1,515:


=={{header|OCaml}}==
=={{header|OCaml}}==
<lang OCaml>let rec leg n x = match n with (* Evaluate Legendre polynomial *)
<syntaxhighlight lang="ocaml">let rec leg n x = match n with (* Evaluate Legendre polynomial *)
| 0 -> 1.0
| 0 -> 1.0
| 1 -> x
| 1 -> x
Line 1,550: Line 1,550:
let f1 x = f ((x*.(b-.a) +. a +. b)*.0.5) in
let f1 x = f ((x*.(b-.a) +. a +. b)*.0.5) in
let eval s (x,w) = s +. w*.(f1 x) in
let eval s (x,w) = s +. w*.(f1 x) in
0.5*.(b-.a)*.(List.fold_left eval 0.0 (nodes n));;</lang>
0.5*.(b-.a)*.(List.fold_left eval 0.0 (nodes n));;</syntaxhighlight>
which can be used in:
which can be used in:
<lang OCaml>let calc n =
<syntaxhighlight lang="ocaml">let calc n =
Printf.printf
Printf.printf
"Gauss-Legendre %2d-point quadrature for exp over [-3..3] = %.16f\n"
"Gauss-Legendre %2d-point quadrature for exp over [-3..3] = %.16f\n"
Line 1,560: Line 1,560:
calc 10;;
calc 10;;
calc 15;;
calc 15;;
calc 20;;</lang>
calc 20;;</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,569: Line 1,569:
</pre>
</pre>
This shows convergence to the correct double-precision value of the integral
This shows convergence to the correct double-precision value of the integral
<lang Ocaml>Printf.printf "%.16f\n" ((exp 3.0) -.(exp (-3.0)));;
<syntaxhighlight lang="ocaml">Printf.printf "%.16f\n" ((exp 3.0) -.(exp (-3.0)));;
20.0357498548198052</lang>
20.0357498548198052</syntaxhighlight>
although going beyond 20 points starts reducing the accuracy, due to accumulated rounding errors.
although going beyond 20 points starts reducing the accuracy, due to accumulated rounding errors.


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<lang oorexx>/*---------------------------------------------------------------------
<syntaxhighlight lang="oorexx">/*---------------------------------------------------------------------
* 31.10.2013 Walter Pachl Translation from REXX (from PL/I)
* 31.10.2013 Walter Pachl Translation from REXX (from PL/I)
* using ooRexx' rxmath package
* using ooRexx' rxmath package
Line 1,643: Line 1,643:
Return
Return


::requires 'rxmath' LIBRARY</lang>
::requires 'rxmath' LIBRARY</syntaxhighlight>
Output:
Output:
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
Line 1,670: Line 1,670:
{{works with|PARI/GP|2.4.2 and above}}
{{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.
This task is easy in GP thanks to built-in support for Legendre polynomials and efficient (Schonhage-Gourdon) polynomial root finding.
<lang parigp>GLq(f,a,b,n)={
<syntaxhighlight lang="parigp">GLq(f,a,b,n)={
my(P=pollegendre(n),Pp=P',x=polroots(P));
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)
(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
# \\ 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)</lang>
GLq(x->exp(x), -3, 3, 5) \\ As of version 2.4.4, this can be written GLq(exp, -3, 3, 5)</syntaxhighlight>
{{out}}
{{out}}
<pre>time = 0 ms.
<pre>time = 0 ms.
Line 1,682: Line 1,682:
{{works with|PARI/GP|2.9.0 and above}}
{{works with|PARI/GP|2.9.0 and above}}
Gauss-Legendre quadrature is built-in from 2.9 forward.
Gauss-Legendre quadrature is built-in from 2.9 forward.
<lang parigp>intnumgauss(x=-3, 3, exp(x), intnumgaussinit(5))
<syntaxhighlight lang="parigp">intnumgauss(x=-3, 3, exp(x), intnumgaussinit(5))
intnumgauss(x=-3, 3, exp(x)) \\ determine number of points automatically; all digits shown should be accurate</lang>
intnumgauss(x=-3, 3, exp(x)) \\ determine number of points automatically; all digits shown should be accurate</syntaxhighlight>
{{out}}
{{out}}
<pre>%1 = 20.035746975092343883065457558549925374
<pre>%1 = 20.035746975092343883065457558549925374
Line 1,692: Line 1,692:
{{works with|Free Pascal|3.0.4}}
{{works with|Free Pascal|3.0.4}}
{{works with|Multics Pascal|8.0.4a}}
{{works with|Multics Pascal|8.0.4a}}
<lang Pascal>program Legendre(output);
<syntaxhighlight lang="pascal">program Legendre(output);
const Order = 5;
const Order = 5;
Line 1,787: Line 1,787:
Writeln('Integrating Exp(x) over [-3, 3]: ',LegInt(-3,3):13:10);
Writeln('Integrating Exp(x) over [-3, 3]: ',LegInt(-3,3):13:10);
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
Writeln('Actual value: ',Exp(3)-Exp(-3):13:10);
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,798: Line 1,798:
=={{header|Perl}}==
=={{header|Perl}}==
{{trans|Raku}}
{{trans|Raku}}
<lang perl>use List::Util qw(sum);
<syntaxhighlight lang="perl">use List::Util qw(sum);
use constant pi => 3.14159265;
use constant pi => 3.14159265;


Line 1,867: Line 1,867:
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.13f\n", $_, quadrature($_, -3, +3) )
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.13f\n", $_, quadrature($_, -3, +3) )
for 5 .. 10, 20;
for 5 .. 10, 20;
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.0355777183856
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.0355777183856
Line 1,879: Line 1,879:
=={{header|Phix}}==
=={{header|Phix}}==
{{trans|Lua}}
{{trans|Lua}}
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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;">integer</span> <span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
Line 1,955: Line 1,955:
<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: #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>
<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>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 1,969: Line 1,969:
=={{header|PL/I}}==
=={{header|PL/I}}==
Translated from Fortran.
Translated from Fortran.
<lang PL/I>(subscriptrange, size, fofl):
<syntaxhighlight lang="pl/i">(subscriptrange, size, fofl):
Integration_Gauss: procedure options (main);
Integration_Gauss: procedure options (main);


Line 2,023: Line 2,023:
end gaussquad;
end gaussquad;
end Integration_Gauss;
end Integration_Gauss;
</syntaxhighlight>
</lang>
<pre>
<pre>
1 6.0000000000000000 -1.40E+0001
1 6.0000000000000000 -1.40E+0001
Line 2,052: Line 2,052:
=={{header|Python}}==
=={{header|Python}}==
{{libheader|NumPy}}
{{libheader|NumPy}}
<lang Python>from numpy import *
<syntaxhighlight lang="python">from numpy import *
##################################################################
##################################################################
Line 2,148: Line 2,148:
print "Integral : ", ans
print "Integral : ", ans
else:
else:
print "Integral evaluation failed"</lang>
print "Integral evaluation failed"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,158: Line 2,158:
===With library routine===
===With library routine===
One can also use the already invented wheel in NumPy:
One can also use the already invented wheel in NumPy:
<lang python>import numpy as np
<syntaxhighlight lang="python">import numpy as np


# func is a function that takes a list-like input values
# func is a function that takes a list-like input values
Line 2,168: Line 2,168:


for d in range(3, 10):
for d in range(3, 10):
print(d, gauss_legendre_integrate(np.exp, [-3, 3], d))</lang>
print(d, gauss_legendre_integrate(np.exp, [-3, 3], d))</syntaxhighlight>
{{out}}
{{out}}
<pre>3 19.853691996805587
<pre>3 19.853691996805587
Line 2,182: Line 2,182:
Computation of the Legendre polynomials and derivatives:
Computation of the Legendre polynomials and derivatives:


<lang racket>
<syntaxhighlight lang="racket">
(define (LegendreP n x)
(define (LegendreP n x)
(let compute ([n n] [Pn-1 x] [Pn-2 1])
(let compute ([n n] [Pn-1 x] [Pn-2 1])
Line 2,197: Line 2,197:
(- (* x (LegendreP n x))
(- (* x (LegendreP n x))
(LegendreP (- n 1) x))))
(LegendreP (- n 1) x))))
</syntaxhighlight>
</lang>


Computation of the Legendre polynomial roots:
Computation of the Legendre polynomial roots:


<lang racket>
<syntaxhighlight lang="racket">
(define (LegendreP-root n i)
(define (LegendreP-root n i)
; newton-raphson step
; newton-raphson step
Line 2,215: Line 2,215:
x′
x′
(next (newton-step x′) x′)))))
(next (newton-step x′) x′)))))
</syntaxhighlight>
</lang>


Computation of Gauss-Legendre nodes and weights
Computation of Gauss-Legendre nodes and weights


<lang racket>
<syntaxhighlight lang="racket">
(define (Gauss-Legendre-quadrature n)
(define (Gauss-Legendre-quadrature n)
;; positive roots
;; positive roots
Line 2,236: Line 2,236:
(if (odd? n) (list (/ 2 (sqr (LegendreP′ n 0)))) '())
(if (odd? n) (list (/ 2 (sqr (LegendreP′ n 0)))) '())
(reverse weights))))
(reverse weights))))
</syntaxhighlight>
</lang>


Integration using Gauss-Legendre quadratures:
Integration using Gauss-Legendre quadratures:


<lang racket>
<syntaxhighlight lang="racket">
(define (integrate f a b #:nodes (n 5))
(define (integrate f a b #:nodes (n 5))
(define m (/ (+ a b) 2))
(define m (/ (+ a b) 2))
Line 2,247: Line 2,247:
(define (g x) (f (+ m (* d x))))
(define (g x) (f (+ m (* d x))))
(* d (+ (apply + (map * w (map g x))))))
(* d (+ (apply + (map * w (map g x))))))
</syntaxhighlight>
</lang>


Usage:
Usage:


<lang racket>
<syntaxhighlight lang="racket">
> (Gauss-Legendre-quadrature 5)
> (Gauss-Legendre-quadrature 5)
'(-0.906179845938664 -0.5384693101056831 0 0.5384693101056831 0.906179845938664)
'(-0.906179845938664 -0.5384693101056831 0 0.5384693101056831 0.906179845938664)
Line 2,261: Line 2,261:
> (- (exp 3) (exp -3)
> (- (exp 3) (exp -3)
20.035749854819805
20.035749854819805
</syntaxhighlight>
</lang>


Accuracy of the method:
Accuracy of the method:


<lang racket>
<syntaxhighlight lang="racket">
> (require plot)
> (require plot)
> (parameterize ([plot-x-label "Number of Gaussian nodes"]
> (parameterize ([plot-x-label "Number of Gaussian nodes"]
Line 2,274: Line 2,274:
(list n (abs (- (integrate exp -3 3 #:nodes n)
(list n (abs (- (integrate exp -3 3 #:nodes n)
(- (exp 3) (exp -3)))))))))
(- (exp 3) (exp -3)))))))))
</syntaxhighlight>
</lang>
[[File:gauss.png]]
[[File:gauss.png]]


Line 2,287: Line 2,287:
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.
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.


<lang perl6>multi legendre-pair( 1 , $x) { $x, 1 }
<syntaxhighlight lang="raku" line>multi legendre-pair( 1 , $x) { $x, 1 }
multi legendre-pair(Int $n, $x) {
multi legendre-pair(Int $n, $x) {
my ($m1, $m2) = legendre-pair($n - 1, $x);
my ($m1, $m2) = legendre-pair($n - 1, $x);
Line 2,341: Line 2,341:
say "Gauss-Legendre $_.fmt('%2d')-point quadrature ∫₋₃⁺³ exp(x) dx ≈ ",
say "Gauss-Legendre $_.fmt('%2d')-point quadrature ∫₋₃⁺³ exp(x) dx ≈ ",
quadrature($_, &exp, -3, +3) for flat 5 .. 10, 20;</lang>
quadrature($_, &exp, -3, +3) for flat 5 .. 10, 20;</syntaxhighlight>


{{out}}
{{out}}
Line 2,354: Line 2,354:
=={{header|REXX}}==
=={{header|REXX}}==
===version 1===
===version 1===
<lang rexx>/*---------------------------------------------------------------------
<syntaxhighlight lang="rexx">/*---------------------------------------------------------------------
* 31.10.2013 Walter Pachl Translation from PL/I
* 31.10.2013 Walter Pachl Translation from PL/I
* 01.11.2014 -"- see Version 2 for improvements
* 01.11.2014 -"- see Version 2 for improvements
Line 2,467: Line 2,467:
End
End
Numeric Digits (prec)
Numeric Digits (prec)
Return r+0</lang>
Return r+0</syntaxhighlight>
Output:
Output:
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
<pre> 1 6.0000000000000000000000000000000000000000 -1.4036E+1
Line 2,519: Line 2,519:
<br>where there's practically no space on the right side of the REXX source statements. &nbsp; It presents a good
<br>where there's practically no space on the right side of the REXX source statements. &nbsp; It presents a good
<br>visual indication of what's what, &nbsp; but it's the dickens to pay when updating the source code.
<br>visual indication of what's what, &nbsp; but it's the dickens to pay when updating the source code.
<lang rexx>/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */
<syntaxhighlight lang="rexx">/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */
pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2
pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2


Line 2,567: Line 2,567:
/*───────────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1
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</lang>
_=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
<pre>
Line 2,614: Line 2,614:


It is about twice as slow as version 2, &nbsp; due to the doubling of the number of decimal digits &nbsp; (precision).
It is about twice as slow as version 2, &nbsp; due to the doubling of the number of decimal digits &nbsp; (precision).
<lang rexx>/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */
<syntaxhighlight lang="rexx">/*REXX program does numerical integration using an N─point Gauss─Legendre quadrature rule. */
pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2
pi= pi(); digs= length(pi) - length(.); numeric digits digs; reps= digs % 2
!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs
!.= .; b= 3; a= -b; bma= b - a; bmaH= bma / 2; tiny= '1e-'digs
Line 2,664: Line 2,664:
/*───────────────────────────────────────────────────────────────────────────────────────────*/
/*───────────────────────────────────────────────────────────────────────────────────────────*/
exp: procedure; parse arg x; ix= x % 1; if abs(x-ix)>.5 then ix= ix + sign(x); x= x-ix; z= 1
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</lang>
_=1; do j=1 until p==z; p=z; _= _*x/j; z= z+_; end; return z * e()**ix</syntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
{{out|output|text=&nbsp; when using the default inputs:}}


Line 2,734: Line 2,734:
=={{header|Scala}}==
=={{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)].
{{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)].
<lang Scala>import scala.math.{Pi, cos, exp}
<syntaxhighlight lang="scala">import scala.math.{Pi, cos, exp}


object GaussLegendreQuadrature extends App {
object GaussLegendreQuadrature extends App {
Line 2,782: Line 2,782:
println(f"compared to actual%n\t${exp(3) - exp(-3)}%10.8f")
println(f"compared to actual%n\t${exp(3) - exp(-3)}%10.8f")


}</lang>
}</syntaxhighlight>


=={{header|Sidef}}==
=={{header|Sidef}}==
{{trans|Raku}}
{{trans|Raku}}
<lang ruby>func legendre_pair((1), x) { (x, 1) }
<syntaxhighlight lang="ruby">func legendre_pair((1), x) { (x, 1) }
func legendre_pair( n, x) {
func legendre_pair( n, x) {
var (m1, m2) = legendre_pair(n - 1, x)
var (m1, m2) = legendre_pair(n - 1, x)
Line 2,845: Line 2,845:
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.15f\n",
printf("Gauss-Legendre %2d-point quadrature ∫₋₃⁺³ exp(x) dx ≈ %.15f\n",
i, quadrature(i, {.exp}, -3, +3))
i, quadrature(i, {.exp}, -3, +3))
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.035577718385561
<pre>Gauss-Legendre 5-point quadrature ∫₋₃⁺³ exp(x) dx ≈ 20.035577718385561
Line 2,860: Line 2,860:
{{tcllib|math::polynomials}}
{{tcllib|math::polynomials}}
{{tcllib|math::special}}
{{tcllib|math::special}}
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
package require math::special
package require math::special
package require math::polynomials
package require math::polynomials
Line 2,922: Line 2,922:
}
}
expr {$sum * $rangesize2}
expr {$sum * $rangesize2}
}</lang>
}</syntaxhighlight>
Demonstrating:
Demonstrating:
<lang tcl>puts "nodes(5) = [nodes 5]"
<syntaxhighlight lang="tcl">puts "nodes(5) = [nodes 5]"
puts "weights(5) = [weights [nodes 5]]"
puts "weights(5) = [weights [nodes 5]]"
set exp {x {expr {exp($x)}}}
set exp {x {expr {exp($x)}}}
puts "int(exp,-3,3) = [gausslegendreintegrate $exp 5 -3 3]"</lang>
puts "int(exp,-3,3) = [gausslegendreintegrate $exp 5 -3 3]"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,937: Line 2,937:
=={{header|Ursala}}==
=={{header|Ursala}}==
using arbitrary precision arithmetic
using arbitrary precision arithmetic
<lang Ursala>#import std
<syntaxhighlight lang="ursala">#import std
#import nat
#import nat


Line 2,970: Line 2,970:
mp..shrink^/~& difference\"p"+ mp..prec,
mp..shrink^/~& difference\"p"+ mp..prec,
mp..mul^|/~& mp..add:-0E0+ * mp..mul^/~&rr ^H/~&ll mp..add^\~&lrr mp..mul@lrPrXl,
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+-</lang>
^(~&rl,-*nodes("p","n"))^|/~& mp..vid~~G/2E0+ ^/mp..bus mp..add+-</syntaxhighlight>
demonstration program:<lang Ursala>#show+
demonstration program:<syntaxhighlight lang="ursala">#show+


demo =
demo =
Line 2,977: Line 2,977:
~&lNrCT (
~&lNrCT (
^|lNrCT(:/'nodes:',:/'weights:')@lSrSX ..mp2str~~* nodes/160 5,
^|lNrCT(:/'nodes:',:/'weights:')@lSrSX ..mp2str~~* nodes/160 5,
:/'integral:' ~&iNC ..mp2str integral(160,5) (mp..exp,-3E0,3E0))</lang>
:/'integral:' ~&iNC ..mp2str integral(160,5) (mp..exp,-3E0,3E0))</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,000: Line 3,000:
{{trans|C}}
{{trans|C}}
{{libheader|Wren-fmt}}
{{libheader|Wren-fmt}}
<lang ecmascript>import "/fmt" for Fmt
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt


var N = 5
var N = 5
Line 3,060: Line 3,060:
var actual = 3.exp - (-3).exp
var actual = 3.exp - (-3).exp
Fmt.print("\nIntegrating exp(x) over [-3, 3]:\n\t$10.8f,\n" +
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)</lang>
"compared to actual\n\t$10.8f", legeIntegrate.call(f, -3, 3), actual)</syntaxhighlight>


{{out}}
{{out}}
Line 3,074: Line 3,074:
=={{header|zkl}}==
=={{header|zkl}}==
{{trans|Raku}}
{{trans|Raku}}
<lang zkl>fcn legendrePair(n,x){ //-->(float,float)
<syntaxhighlight lang="zkl">fcn legendrePair(n,x){ //-->(float,float)
if(n==1) return(x,1.0);
if(n==1) return(x,1.0);
m1,m2:=legendrePair(n-1,x);
m1,m2:=legendrePair(n-1,x);
Line 3,118: Line 3,118:
scale:='wrap(x){ (x*(b - a) + a + b) / 2 };
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
nds.reduce('wrap(p,[(r,w)]){ p + w*f(scale(r)) },0.0) * (b - a)/2
}</lang>
}</syntaxhighlight>
<lang zkl>[5..10].walk().append(20).pump(Console.println,fcn(n){
<syntaxhighlight lang="zkl">[5..10].walk().append(20).pump(Console.println,fcn(n){
("Gauss-Legendre %2d-point quadrature "
("Gauss-Legendre %2d-point quadrature "
"\U222B;\U208B;\U2083;\U207A;\UB3; exp(x) dx = %.13f")
"\U222B;\U208B;\U2083;\U207A;\UB3; exp(x) dx = %.13f")
.fmt(n,quadrature(n, fcn(x){ x.exp() }, -3, 3))
.fmt(n,quadrature(n, fcn(x){ x.exp() }, -3, 3))
})</lang>
})</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>