tasks a-s

This commit is contained in:
Ingy döt Net 2013-04-10 23:57:08 -07:00
parent 47bf37c096
commit b83f433714
12433 changed files with 156208 additions and 123 deletions

View file

@ -0,0 +1,24 @@
Write functions to calculate the definite integral of a function (<span style="font-family: serif">''f(x)''</span>) using [[wp:Rectangle_method|rectangular]] (left, right, and midpoint), [[wp:Trapezoidal_rule|trapezium]], and [[wp:Simpson%27s_rule|Simpson's]] methods. Your functions should take in the upper and lower bounds (<span style="font-family: serif">''a''</span> and <span style="font-family: serif">''b''</span>) and the number of approximations to make in that range (<span style="font-family: serif">''n''</span>). Assume that your example already has a function that gives values for <span style="font-family: serif">''f(x)''</span>.
Simpson's method is defined by the following pseudocode:
<pre>
h := (b - a) / n
sum1 := f(a + h/2)
sum2 := 0
loop on i from 1 to (n - 1)
sum1 := sum1 + f(a + h * i + h/2)
sum2 := sum2 + f(a + h * i)
answer := (h / 6) * (f(a) + f(b) + 4*sum1 + 2*sum2)
</pre>
Demonstrate your function by showing the results for:
* f(x) = x^3, where x is [0,1], with 100 approximations. The exact result is 1/4, or 0.25.
* f(x) = 1/x, where x is [1,100], with 1,000 approximations. The exact result is the natural log of 100, or about 4.605170
* f(x) = x, where x is [0,5000], with 5,000,000 approximations. The exact result is 12,500,000.
* f(x) = x, where x is [0,6000], with 6,000,000 approximations. The exact result is 18,000,000.
'''See also'''
* [[Active object]] for integrating a function of real time.
* [[Numerical integration/Gauss-Legendre Quadrature]] for another integration method.

View file

@ -0,0 +1,2 @@
---
note: Arithmetic operations

View file

@ -0,0 +1,85 @@
MODE F = PROC(LONG REAL)LONG REAL;
###############
## left rect ##
###############
PROC left rect = (F f, LONG REAL a, b, INT n) LONG REAL:
BEGIN
LONG REAL h= (b - a) / n;
LONG REAL sum:= 0;
LONG REAL x:= a;
WHILE x <= b - h DO
sum := sum + (h * f(x));
x +:= h
OD;
sum
END # left rect #;
#################
## right rect ##
#################
PROC right rect = (F f, LONG REAL a, b, INT n) LONG REAL:
BEGIN
LONG REAL h= (b - a) / n;
LONG REAL sum:= 0;
LONG REAL x:= a + h;
WHILE x <= b DO
sum := sum + (h * f(x));
x +:= h
OD;
sum
END # right rect #;
###############
## mid rect ##
###############
PROC mid rect = (F f, LONG REAL a, b, INT n) LONG REAL:
BEGIN
LONG REAL h= (b - a) / n;
LONG REAL sum:= 0;
LONG REAL x:= a;
WHILE x <= b - h DO
sum := sum + h * f(x + h / 2);
x +:= h
OD;
sum
END # mid rect #;
###############
## trapezium ##
###############
PROC trapezium = (F f, LONG REAL a, b, INT n) LONG REAL:
BEGIN
LONG REAL h= (b - a) / n;
LONG REAL sum:= f(a) + f(b);
LONG REAL x:= 1;
WHILE x <= n - 1 DO
sum := sum + 2 * f(a + x * h );
x +:= 1
OD;
(b - a) / (2 * n) * sum
END # trapezium #;
#############
## simpson ##
#############
PROC simpson = (F f, LONG REAL a, b, INT n) LONG REAL:
BEGIN
LONG REAL h= (b - a) / n;
LONG REAL sum1:= 0;
LONG REAL sum2:= 0;
INT limit:= n - 1;
FOR i FROM 0 TO limit DO
sum1 := sum1 + f(a + h * LONG REAL(i) + h / 2)
OD;
FOR i FROM 1 TO limit DO
sum2 +:= f(a + h * LONG REAL(i))
OD;
h / 6 * (f(a) + f(b) + 4 * sum1 + 2 * sum2)
END # simpson #;
SKIP

View file

@ -0,0 +1,51 @@
function leftRect(f:Function, a:Number, b:Number, n:uint):Number
{
var sum:Number = 0;
var dx:Number = (b-a)/n;
for (var x:Number = a; n > 0; n--, x += dx)
sum += f(x);
return sum * dx;
}
function rightRect(f:Function, a:Number, b:Number, n:uint):Number
{
var sum:Number = 0;
var dx:Number = (b-a)/n;
for (var x:Number = a + dx; n > 0; n--, x += dx)
sum += f(x);
return sum * dx;
}
function midRect(f:Function, a:Number, b:Number, n:uint):Number
{
var sum:Number = 0;
var dx:Number = (b-a)/n;
for (var x:Number = a + (dx / 2); n > 0; n--, x += dx)
sum += f(x);
return sum * dx;
}
function trapezium(f:Function, a:Number, b:Number, n:uint):Number
{
var dx:Number = (b-a)/n;
var x:Number = a;
var sum:Number = f(a);
for(var i:uint = 1; i < n; i++)
{
a += dx;
sum += f(a)*2;
}
sum += f(b);
return 0.5 * dx * sum;
}
function simpson(f:Function, a:Number, b:Number, n:uint):Number
{
var dx:Number = (b-a)/n;
var sum1:Number = f(a + dx/2);
var sum2:Number = 0;
for(var i:uint = 1; i < n; i++)
{
sum1 += f(a + dx*i + dx/2);
sum2 += f(a + dx*i);
}
return (dx/6) * (f(a) + f(b) + 4*sum1 + 2*sum2);
}

View file

@ -0,0 +1,8 @@
function f1(n:Number):Number {
return (2/(1+ 4*(n*n)));
}
trace(leftRect(f1, -1, 2, 4));
trace(rightRect(f1, -1, 2, 4));
trace(midRect(f1, -1, 2, 4));
trace(trapezium(f1, -1, 2 ,4 ));
trace(simpson(f1, -1, 2 ,4 ));

View file

@ -0,0 +1,10 @@
generic
type Scalar is digits <>;
with function F (X : Scalar) return Scalar;
package Integrate is
function Left_Rectangular (A, B : Scalar; N : Positive) return Scalar;
function Right_Rectangular (A, B : Scalar; N : Positive) return Scalar;
function Midpoint_Rectangular (A, B : Scalar; N : Positive) return Scalar;
function Trapezium (A, B : Scalar; N : Positive) return Scalar;
function Simpsons (A, B : Scalar; N : Positive) return Scalar;
end Integrate;

View file

@ -0,0 +1,61 @@
package body Integrate is
function Left_Rectangular (A, B : Scalar; N : Positive) return Scalar is
H : constant Scalar := (B - A) / Scalar (N);
Sum : Scalar := 0.0;
X : Scalar;
begin
for I in 0 .. N - 1 loop
X := A + Scalar (I) * H;
Sum := Sum + H * F (X);
end loop;
return Sum;
end Left_Rectangular;
function Right_Rectangular (A, B : Scalar; N : Positive) return Scalar is
H : constant Scalar := (B - A) / Scalar (N);
Sum : Scalar := 0.0;
X : Scalar;
begin
for I in 1 .. N loop
X := A + Scalar (I) * H;
Sum := Sum + H * F (X);
end loop;
return Sum;
end Right_Rectangular;
function Midpoint_Rectangular (A, B : Scalar; N : Positive) return Scalar is
H : constant Scalar := (B - A) / Scalar (N);
Sum : Scalar := 0.0;
X : Scalar;
begin
for I in 1 .. N loop
X := A + Scalar (I) * H - 0.5 * H;
Sum := Sum + H * F (X);
end loop;
return Sum;
end Midpoint_Rectangular;
function Trapezium (A, B : Scalar; N : Positive) return Scalar is
H : constant Scalar := (B - A) / Scalar (N);
Sum : Scalar := F(A) + F(B);
X : Scalar := 1.0;
begin
while X <= Scalar (N) - 1.0 loop
Sum := Sum + 2.0 * F (A + X * (B - A) / Scalar (N));
X := X + 1.0;
end loop;
return (B - A) / (2.0 * Scalar (N)) * Sum;
end Trapezium;
function Simpsons (A, B : Scalar; N : Positive) return Scalar is
H : constant Scalar := (B - A) / Scalar (N);
Sum_1 : Scalar := 0.0;
Sum_2 : Scalar := 0.0;
begin
for I in 0 .. N - 1 loop
Sum_1 := Sum_1 + F (A + H * Scalar (I) + 0.5 * H);
Sum_2 := Sum_2 + F (A + H * Scalar (I));
end loop;
return H / 6.0 * (F (A) + F (B) + 4.0 * Sum_1 + 2.0 * Sum_2);
end Simpsons;
end Integrate;

View file

@ -0,0 +1,104 @@
with Ada.Text_IO, Ada.Integer_Text_IO;
with Integrate;
procedure Numerical_Integration is
type Scalar is digits 18;
package Scalar_Text_IO is new Ada.Text_IO.Float_IO (Scalar);
generic
with function F (X : Scalar) return Scalar;
Name : String;
From, To : Scalar;
Steps : Positive;
procedure Test;
procedure Test is
package Integrate_Scalar_F is new Integrate (Scalar, F);
use Ada.Text_IO, Ada.Integer_Text_IO, Integrate_Scalar_F, Scalar_Text_IO;
begin
Put (Name & " integrated from ");
Put (From);
Put (" to ");
Put (To);
Put (" in ");
Put (Steps);
Put_Line (" steps:");
Put ("Rectangular (left): ");
Put (Left_Rectangular (From, To, Steps));
New_Line;
Put ("Rectangular (right): ");
Put (Right_Rectangular (From, To, Steps));
New_Line;
Put ("Rectangular (midpoint): ");
Put (Midpoint_Rectangular (From, To, Steps));
New_Line;
Put ("Trapezium: ");
Put (Trapezium (From, To, Steps));
New_Line;
Put ("Simpson's: ");
Put (Simpsons (From, To, Steps));
New_Line;
New_Line;
end Test;
begin
Ada.Integer_Text_IO.Default_Width := 0;
Scalar_Text_IO.Default_Fore := 0;
Scalar_Text_IO.Default_Exp := 0;
Cubed:
declare
function F (X : Scalar) return Scalar is
begin
return X ** 3;
end F;
procedure Run is new Test (F => F,
Name => "x^3",
From => 0.0,
To => 1.0,
Steps => 100);
begin
Run;
end Cubed;
One_Over_X:
declare
function F (X : Scalar) return Scalar is
begin
return 1.0 / X;
end F;
procedure Run is new Test (F => F,
Name => "1/x",
From => 1.0,
To => 100.0,
Steps => 1_000);
begin
Run;
end One_Over_X;
X:
declare
function F (X : Scalar) return Scalar is
begin
return X;
end F;
procedure Run_1 is new Test (F => F,
Name => "x",
From => 0.0,
To => 5_000.0,
Steps => 5_000_000);
procedure Run_2 is new Test (F => F,
Name => "x",
From => 0.0,
To => 6_000.0,
Steps => 6_000_000);
begin
Run_1;
Run_2;
end X;
end Numerical_Integration;

View file

@ -0,0 +1,35 @@
MsgBox % Rect("fun", 0, 1, 10,-1) ; 0.45 left
MsgBox % Rect("fun", 0, 1, 10) ; 0.50 mid
MsgBox % Rect("fun", 0, 1, 10, 1) ; 0.55 right
MsgBox % Trapez("fun", 0, 1, 10) ; 0.50
MsgBox % Simpson("fun", 0, 1, 10) ; 0.50
Rect(f,a,b,n,side=0) { ; side: -1=left, 0=midpoint, 1=right
h := (b - a) / n
sum := 0, a += (side-1)*h/2
Loop %n%
sum += %f%(a + h*A_Index)
Return h*sum
}
Trapez(f,a,b,n) {
h := (b - a) / n
sum := 0
Loop % n-1
sum += %f%(a + h*A_Index)
Return h/2 * (%f%(a) + %f%(b) + 2*sum)
}
Simpson(f,a,b,n) {
h := (b - a) / n
sum1 := sum2 := 0, ah := a - h/2
Loop %n%
sum1 += %f%(ah + h*A_Index)
Loop % n-1
sum2 += %f%(a + h*A_Index)
Return h/6 * (%f%(a) + %f%(b) + 4*sum1 + 2*sum2)
}
fun(x) { ; linear test function
Return x
}

View file

@ -0,0 +1,51 @@
FUNCTION leftRect(a, b, n)
h = (b - a) / n
sum = 0
FOR x = a TO b - h STEP h
sum = sum + h * (f(x))
NEXT x
leftRect = sum
END FUNCTION
FUNCTION rightRect(a, b, n)
h = (b - a) / n
sum = 0
FOR x = a + h TO b STEP h
sum = sum + h * (f(x))
NEXT x
rightRect = sum
END FUNCTION
FUNCTION midRect(a, b, n)
h = (b - a) / n
sum = 0
FOR x = a TO b - h STEP h
sum = sum + (h / 2) * (f(x) + f(x + h))
NEXT x
midRect = sum
END FUNCTION
FUNCTION trap(a, b, n)
h = (b - a) / n
sum = f(a) + f(b)
FOR i = 1 TO n-1
sum = sum + 2 * f((a + i * h))
NEXT i
trap = h / 2 * sum
END FUNCTION
FUNCTION simpson(a, b, n)
h = (b - a) / n
sum1 = 0
sum2 = 0
FOR i = 0 TO n-1
sum1 = sum + f(a + h * i + h / 2)
NEXT i
FOR i = 1 TO n - 1
sum2 = sum2 + f(a + h * i)
NEXT i
simpson = h / 6 * (f(a) + f(b) + 4 * sum1 + 2 * sum2)
END FUNCTION

View file

@ -0,0 +1,71 @@
*FLOAT64
@% = 12 : REM Column width
PRINT "Function Range L-Rect R-Rect M-Rect Trapeze Simpson"
FOR func% = 1 TO 4
READ x$, l, h, s%
PRINT x$, ; l " - " ; h, FNlrect(x$, l, h, s%) FNrrect(x$, l, h, s%) ;
PRINT FNmrect(x$, l, h, s%) FNtrapeze(x$, l, h, s%) FNsimpson(x$, l, h, s%)
NEXT
END
DATA "x^3", 0, 1, 100
DATA "1/x", 1, 100, 1000
DATA "x", 0, 5000, 5000000
DATA "x", 0, 6000, 6000000
DEF FNlrect(x$, a, b, n%)
LOCAL i%, d, s, x
d = (b - a) / n%
x = a
FOR i% = 1 TO n%
s += d * EVAL(x$)
x += d
NEXT
= s
DEF FNrrect(x$, a, b, n%)
LOCAL i%, d, s, x
d = (b - a) / n%
x = a
FOR i% = 1 TO n%
x += d
s += d * EVAL(x$)
NEXT
= s
DEF FNmrect(x$, a, b, n%)
LOCAL i%, d, s, x
d = (b - a) / n%
x = a
FOR i% = 1 TO n%
x += d/2
s += d * EVAL(x$)
x += d/2
NEXT
= s
DEF FNtrapeze(x$, a, b, n%)
LOCAL i%, d, f, s, x
d = (b - a) / n%
x = b : f = EVAL(x$)
x = a : s = d * (f + EVAL(x$)) / 2
FOR i% = 1 TO n%-1
x += d
s += d * EVAL(x$)
NEXT
= s
DEF FNsimpson(x$, a, b, n%)
LOCAL i%, d, f, s1, s2, x
d = (b - a) / n%
x = b : f = EVAL(x$)
x = a + d/2 : s1 = EVAL(x$)
FOR i% = 1 TO n%-1
x += d/2
s2 += EVAL(x$)
x += d/2
s1 += EVAL(x$)
NEXT
x = a
= (d / 6) * (f + EVAL(x$) + 4 * s1 + 2 * s2)

View file

@ -0,0 +1,63 @@
// the integration routine
template<typename Method, typename F, typename Float>
double integrate(F f, Float a, Float b, int steps, Method m)
{
double s = 0;
double h = (b-a)/steps;
for (int i = 0; i < steps; ++i)
s += m(f, a + h*i, h);
return h*s;
}
// methods
class rectangular
{
public:
enum position_type { left, middle, right };
rectangular(position_type pos): position(pos) {}
template<typename F, typename Float>
double operator()(F f, Float x, Float h) const
{
switch(position)
{
case left:
return f(x);
case middle:
return f(x+h/2);
case right:
return f(x+h);
}
}
private:
const position_type position;
};
class trapezium
{
public:
template<typename F, typename Float>
double operator()(F f, Float x, Float h) const
{
return (f(x) + f(x+h))/2;
}
};
class simpson
{
public:
template<typename F, typename Float>
double operator()(F f, Float x, Float h) const
{
return (f(x) + 4*f(x+h/2) + f(x+h))/6;
}
};
// sample usage
double f(double x) { return x*x; )
// inside a function somewhere:
double rl = integrate(f, 0.0, 1.0, 10, rectangular(rectangular::left));
double rm = integrate(f, 0.0, 1.0, 10, rectangular(rectangular::middle));
double rr = integrate(f, 0.0, 1.0, 10, rectangular(rectangular::right));
double t = integrate(f, 0.0, 1.0, 10, trapezium());
double s = integrate(f, 0.0, 1.0, 10, simpson());

View file

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double int_leftrect(double from, double to, double n, double (*func)())
{
double h = (to-from)/n;
double sum = 0.0, x;
for(x=from; x <= (to-h); x += h)
sum += func(x);
return h*sum;
}
double int_rightrect(double from, double to, double n, double (*func)())
{
double h = (to-from)/n;
double sum = 0.0, x;
for(x=from; x <= (to-h); x += h)
sum += func(x+h);
return h*sum;
}
double int_midrect(double from, double to, double n, double (*func)())
{
double h = (to-from)/n;
double sum = 0.0, x;
for(x=from; x <= (to-h); x += h)
sum += func(x+h/2.0);
return h*sum;
}
double int_trapezium(double from, double to, double n, double (*func)())
{
double h = (to - from) / n;
double sum = func(from) + func(to);
int i;
for(i = 1;i < n;i++)
sum += 2.0*func(from + i * h);
return h * sum / 2.0;
}
double int_simpson(double from, double to, double n, double (*func)())
{
double h = (to - from) / n;
double sum1 = 0.0;
double sum2 = 0.0;
int i;
double x;
for(i = 0;i < n;i++)
sum1 += func(from + h * i + h / 2.0);
for(i = 1;i < n;i++)
sum2 += func(from + h * i);
return h / 6.0 * (func(from) + func(to) + 4.0 * sum1 + 2.0 * sum2);
}

View file

@ -0,0 +1,71 @@
/* test */
double f3(double x)
{
return x;
}
double f3a(double x)
{
return x*x/2.0;
}
double f2(double x)
{
return 1.0/x;
}
double f2a(double x)
{
return log(x);
}
double f1(double x)
{
return x*x*x;
}
double f1a(double x)
{
return x*x*x*x/4.0;
}
typedef double (*pfunc)(double, double, double, double (*)());
typedef double (*rfunc)(double);
#define INTG(F,A,B) (F((B))-F((A)))
int main()
{
int i, j;
double ic;
pfunc f[5] = {
int_leftrect, int_rightrect,
int_midrect, int_trapezium,
int_simpson
};
const char *names[5] = {
"leftrect", "rightrect", "midrect",
"trapezium", "simpson"
};
rfunc rf[] = { f1, f2, f3, f3 };
rfunc If[] = { f1a, f2a, f3a, f3a };
double ivals[] = {
0.0, 1.0,
1.0, 100.0,
0.0, 5000.0,
0.0, 6000.0
};
double approx[] = { 100.0, 1000.0, 5000000.0, 6000000.0 };
for(j=0; j < (sizeof(rf) / sizeof(rfunc)); j++)
{
for(i=0; i < 5 ; i++)
{
ic = (*f[i])(ivals[2*j], ivals[2*j+1], approx[j], rf[j]);
printf("%10s [ 0,1] num: %+lf, an: %lf\n",
names[i], ic, INTG((*If[j]), ivals[2*j], ivals[2*j+1]));
}
printf("\n");
}
}

View file

@ -0,0 +1,33 @@
rules =
left_rect: (f, x, h) -> f(x)
mid_rect: (f, x, h) -> f(x+h/2)
right_rect: (f, x, h) -> f(x+h)
trapezium: (f, x, h) -> (f(x) + f(x+h)) / 2
simpson: (f, x, h) -> (f(x) + 4 * f(x + h/2) + f(x+h)) / 6
functions =
cube: (x) -> x*x*x
reciprocal: (x) -> 1/x
identity: (x) -> x
sum = (list) -> list.reduce ((a, b) -> a+b), 0
integrate = (f, a, b, steps, meth) ->
h = (b-a) / steps
h * sum(meth(f, a+i*h, h) for i in [0...steps])
# Tests
tests = [
[0, 1, 100, 'cube']
[1, 100, 1000, 'reciprocal']
[0, 5000, 5000000, 'identity']
[0, 6000, 6000000, 'identity']
]
for test in tests
[a, b, steps, func_name] = test
func = functions[func_name]
console.log "-- tests for #{func_name} with #{steps} steps from #{a} to #{b}"
for rule_name, rule of rules
result = integrate func, a, b, steps, rule
console.log rule_name, result

View file

@ -0,0 +1,25 @@
> coffee numerical_integration.coffee
-- tests for cube with 100 steps from 0 to 1
left_rect 0.24502500000000005
mid_rect 0.24998750000000006
right_rect 0.25502500000000006
trapezium 0.250025
simpson 0.25
-- tests for reciprocal with 1000 steps from 1 to 100
left_rect 4.65499105751468
mid_rect 4.604762548678376
right_rect 4.55698105751468
trapezium 4.605986057514676
simpson 4.605170384957133
-- tests for identity with 5000000 steps from 0 to 5000
left_rect 12499997.5
mid_rect 12500000
right_rect 12500002.5
trapezium 12500000
simpson 12500000
-- tests for identity with 6000000 steps from 0 to 6000
left_rect 17999997.000000004
mid_rect 17999999.999999993
right_rect 18000003.000000004
trapezium 17999999.999999993
simpson 17999999.999999993

View file

@ -0,0 +1,27 @@
(defun left-rectangle (f a b n &aux (d (/ (- b a) n)))
(* d (loop for x from a below b by d summing (funcall f x))))
(defun right-rectangle (f a b n &aux (d (/ (- b a) n)))
(* d (loop for x from b above a by d summing (funcall f x))))
(defun midpoint-rectangle (f a b n &aux (d (/ (- b a) n)))
(* d (loop for x from (+ a (/ d 2)) below b by d summing (funcall f x))))
(defun trapezium (f a b n &aux (d (/ (- b a) n)))
(* (/ d 2)
(+ (funcall f a)
(* 2 (loop for x from (+ a d) below b by d summing (funcall f x)))
(funcall f b))))
(defun simpson (f a b n)
(loop with h = (/ (- b a) n)
with sum1 = (funcall f (+ a (/ h 2)))
with sum2 = 0
for i from 1 below n
do (incf sum1 (funcall f (+ a (* h i) (/ h 2))))
do (incf sum2 (funcall f (+ a (* h i))))
finally (return (* (/ h 6)
(+ (funcall f a)
(funcall f b)
(* 4 sum1)
(* 2 sum2))))))

View file

@ -0,0 +1,63 @@
import std.stdio, std.typecons, std.typetuple;
template integrate(alias method) {
double integrate(F, Float)(in F f, in Float a,
in Float b, in int steps) {
double s = 0.0;
immutable double h = (b - a) / steps;
foreach (i; 0 .. steps)
s += method(f, a + h * i, h);
return h * s;
}
}
double rectangularLeft(F, Float)(in F f, in Float x, in Float h)
pure nothrow {
return f(x);
}
double rectangularMiddle(F, Float)(in F f, in Float x, in Float h)
pure nothrow {
return f(x + h / 2);
}
double rectangularRight(F, Float)(in F f, in Float x, in Float h)
pure nothrow {
return f(x + h);
}
double trapezium(F, Float)(in F f, in Float x, in Float h)
pure nothrow {
return (f(x) + f(x + h)) / 2;
}
double simpson(F, Float)(in F f, in Float x, in Float h)
pure nothrow {
return (f(x) + 4 * f(x + h / 2) + f(x + h)) / 6;
}
void main() {
immutable args = [
tuple((double x) => x ^^ 3, 0.0, 1.0, 10),
tuple((double x) => 1 / x, 1.0, 100.0, 1000),
tuple((double x) => x, 0.0, 5_000.0, 5_000_000),
tuple((double x) => x, 0.0, 6_000.0, 6_000_000)];
alias TypeTuple!(integrate!rectangularLeft,
integrate!rectangularMiddle,
integrate!rectangularRight,
integrate!trapezium,
integrate!simpson) ints;
alias TypeTuple!("rectangular left: ",
"rectangular middle: ",
"rectangular right: ",
"trapezium: ",
"simpson: ") names;
foreach (a; args) {
foreach (i, n; names)
writefln("%s %f", n, ints[i](a.tupleof));
writeln();
}
}

View file

@ -0,0 +1,71 @@
import std.stdio, std.typecons, std.typetuple;
template integrate(alias method) {
template integrate(alias f) {
double integrate(Float)(in Float a, in Float b,
in int steps) pure nothrow {
Float s = 0.0;
immutable Float h = (b - a) / steps;
foreach (i; 0 .. steps)
s += method!(f, Float)(a + h * i, h);
return h * s;
}
}
}
double rectangularLeft(alias f, Float)(in Float x, in Float h)
pure nothrow {
return f(x);
}
double rectangularMiddle(alias f, Float)(in Float x, in Float h)
pure nothrow {
return f(x + h / 2);
}
double rectangularRight(alias f, Float)(in Float x, in Float h)
pure nothrow {
return f(x + h);
}
double trapezium(alias f, Float)(in Float x, in Float h)
pure nothrow {
return (f(x) + f(x + h)) / 2;
}
double simpson(alias f, Float)(in Float x, in Float h)
pure nothrow {
return (f(x) + 4 * f(x + h / 2) + f(x + h)) / 6;
}
void main() {
static double f1(in double x) pure nothrow { return x ^^ 3; }
static double f2(in double x) pure nothrow { return 1 / x; }
static double f3(in double x) pure nothrow { return x; }
alias TypeTuple!(f1, f2, f3, f3) funcs;
alias TypeTuple!("rectangular left: ",
"rectangular middle: ",
"rectangular right: ",
"trapezium: ",
"simpson: ") names;
alias TypeTuple!(integrate!rectangularLeft,
integrate!rectangularMiddle,
integrate!rectangularRight,
integrate!trapezium,
integrate!simpson) ints;
immutable args = [tuple(0.0, 1.0, 10),
tuple(1.0, 100.0, 1_000),
tuple(0.0, 5_000.0, 5_000_000),
tuple(0.0, 6_000.0, 6_000_000)];
foreach (i, f; funcs) {
foreach (j, n; names) {
alias ints[j] integ;
writefln("%s %f", n, integ!f(args[i].tupleof));
}
writeln();
}
}

View file

@ -0,0 +1,26 @@
pragma.enable("accumulator")
def leftRect(f, x, h) {
return f(x)
}
def midRect(f, x, h) {
return f(x + h/2)
}
def rightRect(f, x, h) {
return f(x + h)
}
def trapezium(f, x, h) {
return (f(x) + f(x+h)) / 2
}
def simpson(f, x, h) {
return (f(x) + 4 * f(x + h / 2) + f(x+h)) / 6
}
def integrate(f, a, b, steps, meth) {
def h := (b-a) / steps
return h * accum 0 for i in 0..!steps { _ + meth(f, a+i*h, h) }
}

View file

@ -0,0 +1,5 @@
? integrate(fn x { x ** 2 }, 3.0, 7.0, 30, simpson)
# value: 105.33333333333334
? integrate(fn x { x ** 9 }, 0, 1, 300, simpson)
# value: 0.10000000002160479

View file

@ -0,0 +1,79 @@
function int_leftrect(sequence bounds, integer n, integer func_id)
atom h, sum
h = (bounds[2]-bounds[1])/n
sum = 0
for x = bounds[1] to bounds[2]-h by h do
sum += call_func(func_id, {x})
end for
return h*sum
end function
function int_rightrect(sequence bounds, integer n, integer func_id)
atom h, sum
h = (bounds[2]-bounds[1])/n
sum = 0
for x = bounds[1] to bounds[2]-h by h do
sum += call_func(func_id, {x+h})
end for
return h*sum
end function
function int_midrect(sequence bounds, integer n, integer func_id)
atom h, sum
h = (bounds[2]-bounds[1])/n
sum = 0
for x = bounds[1] to bounds[2]-h by h do
sum += call_func(func_id, {x+h/2})
end for
return h*sum
end function
function int_trapezium(sequence bounds, integer n, integer func_id)
atom h, sum
h = (bounds[2]-bounds[1])/n
sum = call_func(func_id, {bounds[1]}) + call_func(func_id, {bounds[2]})
for x = bounds[1] to bounds[2]-h by h do
sum += 2*call_func(func_id, {x})
end for
return h * sum / 2
end function
function int_simpson(sequence bounds, integer n, integer func_id)
atom h, sum1, sum2
h = (bounds[2]-bounds[1])/n
sum1 = call_func(func_id, {bounds[1] + h/2})
sum2 = 0
for i = 1 to n-1 do
sum1 += call_func(func_id, {bounds[1] + h * i + h / 2})
sum2 += call_func(func_id, {bounds[1] + h * i})
end for
return h/6 * (call_func(func_id, {bounds[1]}) +
call_func(func_id, {bounds[2]}) + 4*sum1 + 2*sum2)
end function
function xp2d2(atom x)
return x*x/2
end function
function logx(atom x)
return log(x)
end function
function x(atom x)
return x
end function
? int_leftrect({-1,1},1000,routine_id("xp2d2"))
? int_rightrect({-1,1},1000,routine_id("xp2d2"))
? int_midrect({-1,1},1000,routine_id("xp2d2"))
? int_simpson({-1,1},1000,routine_id("xp2d2"))
puts(1,'\n')
? int_leftrect({1,2},1000,routine_id("logx"))
? int_rightrect({1,2},1000,routine_id("logx"))
? int_midrect({1,2},1000,routine_id("logx"))
? int_simpson({1,2},1000,routine_id("logx"))
puts(1,'\n')
? int_leftrect({0,10},1000,routine_id("x"))
? int_rightrect({0,10},1000,routine_id("x"))
? int_midrect({0,10},1000,routine_id("x"))
? int_simpson({0,10},1000,routine_id("x"))

View file

@ -0,0 +1,40 @@
fvariable step
defer method ( fn F: x -- fn[x] )
: left execute ;
: right step f@ f+ execute ;
: mid step f@ 2e f/ f+ execute ;
: trap
dup fdup left
fswap right f+ 2e f/ ;
: simpson
dup fdup left
dup fover mid 4e f* f+
fswap right f+ 6e f/ ;
: set-step ( n F: a b -- n F: a )
fover f- dup 0 d>f f/ step f! ;
: integrate ( xt n F: a b -- F: sigma )
set-step
0e
0 do
dup fover method f+
fswap step f@ f+ fswap
loop
drop fnip
step f@ f* ;
\ testing similar to the D example
: test
' is method ' 4 -1e 2e integrate f. ;
: fn1 fsincos f+ ;
: fn2 fdup f* 4e f* 1e f+ 2e fswap f/ ;
7 set-precision
test left fn2 \ 2.456897
test right fn2 \ 2.245132
test mid fn2 \ 2.496091
test trap fn2 \ 2.351014
test simpson fn2 \ 2.447732

View file

@ -0,0 +1,4 @@
elemental function elemf(x)
real :: elemf, x
elemf = f(x)
end function elemf

View file

@ -0,0 +1,75 @@
module Integration
implicit none
contains
! function, lower limit, upper limit, steps, method
function integrate(f, a, b, in, method)
real :: integrate
real, intent(in) :: a, b
integer, optional, intent(in) :: in
character(len=*), intent(in), optional :: method
interface
elemental function f(ra)
real :: f
real, intent(in) :: ra
end function f
end interface
integer :: n, i, m
real :: h
real, dimension(:), allocatable :: xpoints
real, dimension(:), target, allocatable :: fpoints
real, dimension(:), pointer :: fleft, fmid, fright
if ( present(in) ) then
n = in
else
n = 20
end if
if ( present(method) ) then
select case (method)
case ('leftrect')
m = 1
case ('midrect')
m = 2
case ('rightrect')
m = 3
case ( 'trapezoid' )
m = 4
case default
m = 0
end select
else
m = 0
end if
h = (b - a) / n
allocate(xpoints(0:2*n), fpoints(0:2*n))
xpoints = (/ (a + h*i/2, i = 0,2*n) /)
fpoints = f(xpoints)
fleft => fpoints(0 : 2*n-2 : 2)
fmid => fpoints(1 : 2*n-1 : 2)
fright => fpoints(2 : 2*n : 2)
select case (m)
case (0) ! simpson
integrate = h / 6.0 * sum(fleft + fright + 4.0*fmid)
case (1) ! leftrect
integrate = h * sum(fleft)
case (2) ! midrect
integrate = h * sum(fmid)
case (3) ! rightrect
integrate = h * sum(fright)
case (4) ! trapezoid
integrate = h * sum(fleft + fright) / 2
end select
deallocate(xpoints, fpoints)
end function integrate
end module Integration

View file

@ -0,0 +1,12 @@
program IntegrationTest
use Integration
use FunctionHolder
implicit none
print *, integrate(afun, 0., 3**(1/3.), method='simpson')
print *, integrate(afun, 0., 3**(1/3.), method='leftrect')
print *, integrate(afun, 0., 3**(1/3.), method='midrect')
print *, integrate(afun, 0., 3**(1/3.), method='rightrect')
print *, integrate(afun, 0., 3**(1/3.), method='trapezoid')
end program IntegrationTest

View file

@ -0,0 +1,13 @@
module FunctionHolder
implicit none
contains
pure function afun(x)
real :: afun
real, intent(in) :: x
afun = x**2
end function afun
end module FunctionHolder

View file

@ -0,0 +1,172 @@
package main
import (
"fmt"
"math"
)
// specification for an integration
type spec struct {
lower, upper float64 // bounds for integration
n int // number of parts
exact float64 // expected answer
fs string // mathematical description of function
f func(float64) float64 // function to integrate
}
// test cases per task description
var data = []spec{
spec{0, 1, 100, .25, "x^3", func(x float64) float64 { return x * x * x }},
spec{1, 100, 1000, float64(math.Log(100)), "1/x",
func(x float64) float64 { return 1 / x }},
spec{0, 5000, 5e5, 12.5e6, "x", func(x float64) float64 { return x }},
spec{0, 6000, 6e6, 18e6, "x", func(x float64) float64 { return x }},
}
// object for associating a printable function name with an integration method
type method struct {
name string
integrate func(spec) float64
}
// integration methods implemented per task description
var methods = []method{
method{"Rectangular (left) ", rectLeft},
method{"Rectangular (right) ", rectRight},
method{"Rectangular (midpoint)", rectMid},
method{"Trapezium ", trap},
method{"Simpson's ", simpson},
}
func rectLeft(t spec) float64 {
parts := make([]float64, t.n)
r := t.upper - t.lower
nf := float64(t.n)
x0 := t.lower
for i := range parts {
x1 := t.lower + float64(i+1)*r/nf
// x1-x0 better than r/nf.
// (with r/nf, the represenation error accumulates)
parts[i] = t.f(x0) * (x1 - x0)
x0 = x1
}
return sum(parts)
}
func rectRight(t spec) float64 {
parts := make([]float64, t.n)
r := t.upper - t.lower
nf := float64(t.n)
x0 := t.lower
for i := range parts {
x1 := t.lower + float64(i+1)*r/nf
parts[i] = t.f(x1) * (x1 - x0)
x0 = x1
}
return sum(parts)
}
func rectMid(t spec) float64 {
parts := make([]float64, t.n)
r := t.upper - t.lower
nf := float64(t.n)
// there's a tiny gloss in the x1-x0 trick here. the correct way
// would be to compute x's at division boundaries, but we don't need
// those x's for anything else. (the function is evaluated on x's
// at division midpoints rather than division boundaries.) so, we
// reuse the midpoint x's, knowing that they will average out just
// as well. we just need one extra point, so we use lower-.5.
x0 := t.lower - .5*r/nf
for i := range parts {
x1 := t.lower + (float64(i)+.5)*r/nf
parts[i] = t.f(x1) * (x1 - x0)
x0 = x1
}
return sum(parts)
}
func trap(t spec) float64 {
parts := make([]float64, t.n)
r := t.upper - t.lower
nf := float64(t.n)
x0 := t.lower
f0 := t.f(x0)
for i := range parts {
x1 := t.lower + float64(i+1)*r/nf
f1 := t.f(x1)
parts[i] = (f0 + f1) * .5 * (x1 - x0)
x0, f0 = x1, f1
}
return sum(parts)
}
func simpson(t spec) float64 {
parts := make([]float64, 2*t.n+1)
r := t.upper - t.lower
nf := float64(t.n)
// similar to the rectangle midpoint logic explained above,
// we play a little loose with the values used for dx and dx0.
dx0 := r / nf
parts[0] = t.f(t.lower) * dx0
parts[1] = t.f(t.lower+dx0*.5) * dx0 * 4
x0 := t.lower + dx0
for i := 1; i < t.n; i++ {
x1 := t.lower + float64(i+1)*r/nf
xmid := (x0 + x1) * .5
dx := x1 - x0
parts[2*i] = t.f(x0) * dx * 2
parts[2*i+1] = t.f(xmid) * dx * 4
x0 = x1
}
parts[2*t.n] = t.f(t.upper) * dx0
return sum(parts) / 6
}
// sum a list of numbers avoiding loss of precision
func sum(v []float64) float64 {
if len(v) == 0 {
return 0
}
var parts []float64
for _, x := range v {
var i int
for _, p := range parts {
sum := p + x
var err float64
if math.Abs(x) < math.Abs(p) {
err = x - (sum - p)
} else {
err = p - (sum - x)
}
if err != 0 {
parts[i] = err
i++
}
x = sum
}
parts = append(parts[:i], x)
}
var sum float64
for _, x := range parts {
sum += x
}
return sum
}
func main() {
for _, t := range data {
fmt.Println("Test case: f(x) =", t.fs)
fmt.Println("Integration from", t.lower, "to", t.upper,
"in", t.n, "parts")
fmt.Printf("Exact result %.7e Error\n", t.exact)
for _, m := range methods {
a := m.integrate(t)
e := a - t.exact
if e < 0 {
e = -e
}
fmt.Printf("%s %.7e %.7e\n", m.name, a, e)
}
fmt.Println("")
}
}

View file

@ -0,0 +1,44 @@
def assertBounds = { List bounds, int nRect ->
assert (bounds.size() == 2) && (bounds[0] instanceof Double) && (bounds[1] instanceof Double) && (nRect > 0)
}
def integral = { List bounds, int nRectangles, Closure f, List pointGuide, Closure integralCalculator->
double a = bounds[0], b = bounds[1], h = (b - a)/nRectangles
def xPoints = pointGuide.collect { double it -> a + it*h }
def fPoints = xPoints.collect { x -> f(x) }
integralCalculator(h, fPoints)
}
def leftRectIntegral = { List bounds, int nRect, Closure f ->
assertBounds(bounds, nRect)
integral(bounds, nRect, f, (0..<nRect)) { h, fPoints -> h*fPoints.sum() }
}
def rightRectIntegral = { List bounds, int nRect, Closure f ->
assertBounds(bounds, nRect)
integral(bounds, nRect, f, (1..nRect)) { h, fPoints -> h*fPoints.sum() }
}
def midRectIntegral = { List bounds, int nRect, Closure f ->
assertBounds(bounds, nRect)
integral(bounds, nRect, f, ((0.5d)..nRect)) { h, fPoints -> h*fPoints.sum() }
}
def trapezoidIntegral = { List bounds, int nRect, Closure f ->
assertBounds(bounds, nRect)
integral(bounds, nRect, f, (0..nRect)) { h, fPoints ->
def fLeft = fPoints[0..<nRect]
def fRight = fPoints[1..nRect]
h/2*(fLeft + fRight).sum()
}
}
def simpsonsIntegral = { List bounds, int nSimpRect, Closure f ->
assertBounds(bounds, nSimpRect)
integral(bounds, nSimpRect*2, f, (0..(nSimpRect*2))) { h, fPoints ->
def fLeft = fPoints[(0..<nSimpRect*2).step(2)]
def fMid = fPoints[(1..<nSimpRect*2).step(2)]
def fRight = fPoints[(2..nSimpRect*2).step(2)]
h/3*((fLeft + fRight).sum() + 4*(fMid.sum()))
}
}

View file

@ -0,0 +1,40 @@
double tolerance = 0.0001 // allowable "wrongness", ensures accuracy to 1 in 10,000
double sinIntegralCalculated = -(Math.cos(Math.PI) - Math.cos(0d))
assert (leftRectIntegral([0d, Math.PI], 129, Math.&sin) - sinIntegralCalculated).abs() < tolerance
assert (rightRectIntegral([0d, Math.PI], 129, Math.&sin) - sinIntegralCalculated).abs() < tolerance
assert (midRectIntegral([0d, Math.PI], 91, Math.&sin) - sinIntegralCalculated).abs() < tolerance
assert (trapezoidIntegral([0d, Math.PI], 129, Math.&sin) - sinIntegralCalculated).abs() < tolerance
assert (simpsonsIntegral([0d, Math.PI], 6, Math.&sin) - sinIntegralCalculated).abs() < tolerance
double cubeIntegralCalculated = 1d/4d *(10d**4 - 0d**4)
assert ((leftRectIntegral([0d, 10d], 20000) { it**3 } - cubeIntegralCalculated)/cubeIntegralCalculated).abs() < tolerance
assert ((rightRectIntegral([0d, 10d], 20001) { it**3 } - cubeIntegralCalculated)/cubeIntegralCalculated).abs() < tolerance
assert ((midRectIntegral([0d, 10d], 71) { it**3 } - cubeIntegralCalculated)/cubeIntegralCalculated).abs() < tolerance
assert ((trapezoidIntegral([0d, 10d], 101) { it**3 } - cubeIntegralCalculated)/cubeIntegralCalculated).abs() < tolerance
// I can name that tune in one note!
assert (simpsonsIntegral([0d, 10d], 1) { it**3 } == cubeIntegralCalculated)
assert (simpsonsIntegral([0d, Math.PI], 1) { it**3 } == (1d/4d *(Math.PI**4 - 0d**4)))
assert (simpsonsIntegral([-7.23d, Math.PI], 1) { it**3 } == (1d/4d *(Math.PI**4 - (-7.23d)**4)))
double quarticIntegralCalculated = 1d/5d *(10d**5 - 0d**5)
assert ((leftRectIntegral([0d, 10d], 25000) { it**4 } - quarticIntegralCalculated)/quarticIntegralCalculated).abs() < tolerance
assert ((rightRectIntegral([0d, 10d], 25001) { it**4 } - quarticIntegralCalculated)/quarticIntegralCalculated).abs() < tolerance
assert ((midRectIntegral([0d, 10d], 92) { it**4 } - quarticIntegralCalculated)/quarticIntegralCalculated).abs() < tolerance
assert ((trapezoidIntegral([0d, 10d], 130) { it**4 } - quarticIntegralCalculated)/quarticIntegralCalculated).abs() < tolerance
assert ((simpsonsIntegral([0d, 10d], 5) { it**4 } - quarticIntegralCalculated)/quarticIntegralCalculated).abs() < tolerance
def cubicPoly = { it**3 + 2*it**2 + 7*it + 12d }
def cubicPolyAntiDeriv = { 1/4*it**4 + 2/3*it**3 + 7/2*it**2 + 12*it }
double cubicPolyIntegralCalculated = (cubicPolyAntiDeriv(10d) - cubicPolyAntiDeriv(0d))
assert ((leftRectIntegral([0d, 10d], 20000, cubicPoly) - cubicPolyIntegralCalculated)/cubicPolyIntegralCalculated).abs() < tolerance
assert ((rightRectIntegral([0d, 10d], 20001, cubicPoly) - cubicPolyIntegralCalculated)/cubicPolyIntegralCalculated).abs() < tolerance
assert ((midRectIntegral([0d, 10d], 71, cubicPoly) - cubicPolyIntegralCalculated)/cubicPolyIntegralCalculated).abs() < tolerance
assert ((trapezoidIntegral([0d, 10d], 101, cubicPoly) - cubicPolyIntegralCalculated)/cubicPolyIntegralCalculated).abs() < tolerance
// I can name that tune in one note!
assert ((simpsonsIntegral([0d, 10d], 1, cubicPoly) - cubicPolyIntegralCalculated)/cubicPolyIntegralCalculated).abs() < tolerance**2.75 // 1 in 100 billion
double cpIntegralCalc0ToPI = (cubicPolyAntiDeriv(Math.PI) - cubicPolyAntiDeriv(0d))
assert ((simpsonsIntegral([0d, Math.PI], 1, cubicPoly) - cpIntegralCalc0ToPI)/ cpIntegralCalc0ToPI).abs() < tolerance**2.75 // 1 in 100 billion
double cpIntegralCalcMinusEToPI = (cubicPolyAntiDeriv(Math.PI) - cubicPolyAntiDeriv(-Math.E))
assert ((simpsonsIntegral([-Math.E, Math.PI], 1, cubicPoly) - cpIntegralCalcMinusEToPI)/ cpIntegralCalcMinusEToPI).abs() < tolerance**2.5 // 1 in 10 billion

View file

@ -0,0 +1,31 @@
println "f(x) = x**3, where x is [0,1], with 100 approximations. The exact result is 1/4, or 0.25."
println ([" LeftRect": leftRectIntegral([0d, 1d], 100) { it**3 }])
println (["RightRect": rightRectIntegral([0d, 1d], 100) { it**3 }])
println ([" MidRect": midRectIntegral([0d, 1d], 100) { it**3 }])
println (["Trapezoid": trapezoidIntegral([0d, 1d], 100) { it**3 }])
println ([" Simpsons": simpsonsIntegral([0d, 1d], 100) { it**3 }])
println ()
println "f(x) = 1/x, where x is [1, 100], with 1,000 approximations. The exact result is the natural log of 100, or about 4.605170."
println ([" LeftRect": leftRectIntegral([1d, 100d], 1000) { 1/it }])
println (["RightRect": rightRectIntegral([1d, 100d], 1000) { 1/it }])
println ([" MidRect": midRectIntegral([1d, 100d], 1000) { 1/it }])
println (["Trapezoid": trapezoidIntegral([1d, 100d], 1000) { 1/it }])
println ([" Simpsons": simpsonsIntegral([1d, 100d], 1000) { 1/it }])
println ()
println "f(x) = x, where x is [0,5000], with 5,000,000 approximations. The exact result is 12,500,000."
println ([" LeftRect": leftRectIntegral([0d, 5000d], 5000000) { it }])
println (["RightRect": rightRectIntegral([0d, 5000d], 5000000) { it }])
println ([" MidRect": midRectIntegral([0d, 5000d], 5000000) { it }])
println (["Trapezoid": trapezoidIntegral([0d, 5000d], 5000000) { it }])
println ([" Simpsons": simpsonsIntegral([0d, 5000d], 5000000) { it }])
println ()
println "f(x) = x, where x is [0,6000], with 6,000,000 approximations. The exact result is 18,000,000."
println ([" LeftRect": leftRectIntegral([0d, 6000d], 6000000) { it }])
println (["RightRect": rightRectIntegral([0d, 6000d], 6000000) { it }])
println ([" MidRect": midRectIntegral([0d, 6000d], 6000000) { it }])
println (["Trapezoid": trapezoidIntegral([0d, 6000d], 6000000) { it }])
println ([" Simpsons": simpsonsIntegral([0d, 6000d], 6000000) { it }])
println ()

View file

@ -0,0 +1 @@
approx f xs ws = sum [w * f x | (x,w) <- zip xs ws]

View file

@ -0,0 +1,7 @@
integrateOpen :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateOpen v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs) * n
h = (b-a) / fromIntegral m
ws = concat $ replicate n vs
c = a + h/2
xs = [c + h * fromIntegral i | i <- [0..m-1]]

View file

@ -0,0 +1,14 @@
integrateClosed :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateClosed v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs - 1) * n
h = (b-a) / fromIntegral m
ws = overlap n vs
xs = [a + h * fromIntegral i | i <- [0..m]]
overlap :: Num a => Int -> [a] -> [a]
overlap n [] = []
overlap n (x:xs) = x : inter n xs where
inter 1 ys = ys
inter n [] = x : inter (n-1) xs
inter n [y] = (x+y) : inter (n-1) xs
inter n (y:ys) = y : inter n ys

View file

@ -0,0 +1,5 @@
intLeftRect = integrateClosed 1 [1,0]
intRightRect = integrateClosed 1 [0,1]
intMidRect = integrateOpen 1 [1]
intTrapezium = integrateClosed 2 [1,1]
intSimpson = integrateClosed 3 [1,4,1]

View file

@ -0,0 +1,3 @@
intMilne = integrateClosed 45 [14,64,24,64,14]
intOpen1 = integrateOpen 2 [3,3]
intOpen2 = integrateOpen 3 [8,-4,8]

View file

@ -0,0 +1,70 @@
approx f xs ws = sum [w * f x | (x,w) <- zip xs ws]
integrateOpen :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateOpen v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs) * n
h = (b-a) / fromIntegral m
ws = concat $ replicate n vs
c = a + h/2
xs = [c + h * fromIntegral i | i <- [0..m-1]]
integrateClosed :: Fractional a => a -> [a] -> (a -> a) -> a -> a -> Int -> a
integrateClosed v vs f a b n = approx f xs ws * h / v where
m = fromIntegral (length vs - 1) * n
h = (b-a) / fromIntegral m
ws = overlap n vs
xs = [a + h * fromIntegral i | i <- [0..m]]
overlap :: Num a => Int -> [a] -> [a]
overlap n [] = []
overlap n (x:xs) = x : inter n xs where
inter 1 ys = ys
inter n [] = x : inter (n-1) xs
inter n [y] = (x+y) : inter (n-1) xs
inter n (y:ys) = y : inter n ys
intLeftRect = integrateClosed 1 [1,0]
intMidRect = integrateOpen 1 [1]
intRightRect = integrateClosed 1 [0,1]
intTrapezium = integrateClosed 2 [1,1]
intSimpson = integrateClosed 3 [1,4,1]
uncurry4 f ~(a, b, c, d) = f a b c d
main = do
let m1 = "rectangular left: "
let m2 = "rectangular middle: "
let m3 = "rectangular right: "
let m4 = "trapezium: "
let m5 = "simpson: "
let arg1 = ((\x -> x ^ 3), 0, 1, 100)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg1)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg1)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg1)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg1)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg1)
putStrLn ""
let arg2 = ((\x -> 1 / x), 1, 100, 1000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg2)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg2)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg2)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg2)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg2)
putStrLn ""
let arg3 = ((\x -> x), 0, 5000, 5000000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg3)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg3)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg3)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg3)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg3)
putStrLn ""
let arg4 = ((\x -> x), 0, 6000, 6000000)
putStrLn $ m1 ++ (show $ uncurry4 intLeftRect arg4)
putStrLn $ m2 ++ (show $ uncurry4 intMidRect arg4)
putStrLn $ m3 ++ (show $ uncurry4 intRightRect arg4)
putStrLn $ m4 ++ (show $ uncurry4 intTrapezium arg4)
putStrLn $ m5 ++ (show $ uncurry4 intSimpson arg4)

View file

@ -0,0 +1,11 @@
integrate=: adverb define
'a b steps'=. 3{.y,128
size=. (b - a)%steps
size * +/ u |: 2 ]\ a + size * i.>:steps
)
rectangle=: adverb def 'u -: +/ y'
trapezium=: adverb def '-: +/ u y'
simpson =: adverb def '6 %~ +/ 1 1 4 * u y, -:+/y'

View file

@ -0,0 +1,28 @@
Ir=: rectangle integrate
It=: trapezium integrate
Is=: simpson integrate
^&3 Ir 0 1 100
0.249987
^&3 It 0 1 100
0.250025
^&3 Is 0 1 100
0.25
% Ir 1 100 1000
4.60476
% It 1 100 1000
4.60599
% Is 1 100 1000
4.60517
] Ir 0 5000 5e6
1.25e7
] It 0 5000 5e6
1.25e7
] Is 0 5000 5e6
1.25e7
] Ir 0 6000 6e6
1.8e7
] It 0 6000 6e6
1.8e7
] Is 0 6000 6e6
1.8e7

View file

@ -0,0 +1,6 @@
*: rectangle integrate 0 1p1 10
10.3095869962
*: trapezium integrate 0 1p1 10
10.3871026879
*: simpson integrate 0 1p1 10
10.3354255601

View file

@ -0,0 +1,7 @@
sin=: 1&o.
sin rectangle integrate 0 1p1 10
2.00824840791
sin trapezium integrate 0 1p1 10
1.98352353751
sin simpson integrate 0 1p1 10
2.00000678444

View file

@ -0,0 +1,4 @@
0 p.. 0 0 1
0 0 0 0.333333333333
0 p.. 0 0 1x NB. or using rationals
0 0 0 1r3

View file

@ -0,0 +1,2 @@
0 0 1 (0&p..@[ -~/@:p. ]) 0 1p1
10.3354255601

View file

@ -0,0 +1,2 @@
*:d._1]1p1
10.3354

View file

@ -0,0 +1,123 @@
class NumericalIntegration
{
interface FPFunction
{
double eval(double n);
}
public static double rectangularLeft(double a, double b, int n, FPFunction f)
{
return rectangular(a, b, n, f, 0);
}
public static double rectangularMidpoint(double a, double b, int n, FPFunction f)
{
return rectangular(a, b, n, f, 1);
}
public static double rectangularRight(double a, double b, int n, FPFunction f)
{
return rectangular(a, b, n, f, 2);
}
public static double trapezium(double a, double b, int n, FPFunction f)
{
double range = checkParamsGetRange(a, b, n);
double nFloat = (double)n;
double sum = 0.0;
for (int i = 1; i < n; i++)
{
double x = a + range * (double)i / nFloat;
sum += f.eval(x);
}
sum += (f.eval(a) + f.eval(b)) / 2.0;
return sum * range / nFloat;
}
public static double simpsons(double a, double b, int n, FPFunction f)
{
double range = checkParamsGetRange(a, b, n);
double nFloat = (double)n;
double sum1 = f.eval(a + range / (nFloat * 2.0));
double sum2 = 0.0;
for (int i = 1; i < n; i++)
{
double x1 = a + range * ((double)i + 0.5) / nFloat;
sum1 += f.eval(x1);
double x2 = a + range * (double)i / nFloat;
sum2 += f.eval(x2);
}
return (f.eval(a) + f.eval(b) + sum1 * 4.0 + sum2 * 2.0) * range / (nFloat * 6.0);
}
private static double rectangular(double a, double b, int n, FPFunction f, int mode)
{
double range = checkParamsGetRange(a, b, n);
double modeOffset = (double)mode / 2.0;
double nFloat = (double)n;
double sum = 0.0;
for (int i = 0; i < n; i++)
{
double x = a + range * ((double)i + modeOffset) / nFloat;
sum += f.eval(x);
}
return sum * range / nFloat;
}
private static double checkParamsGetRange(double a, double b, int n)
{
if (n <= 0)
throw new IllegalArgumentException("Invalid value of n");
double range = b - a;
if (range <= 0)
throw new IllegalArgumentException("Invalid range");
return range;
}
private static void testFunction(String fname, double a, double b, int n, FPFunction f)
{
System.out.println("Testing function \"" + fname + "\", a=" + a + ", b=" + b + ", n=" + n);
System.out.println("rectangularLeft: " + rectangularLeft(a, b, n, f));
System.out.println("rectangularMidpoint: " + rectangularMidpoint(a, b, n, f));
System.out.println("rectangularRight: " + rectangularRight(a, b, n, f));
System.out.println("trapezium: " + trapezium(a, b, n, f));
System.out.println("simpsons: " + simpsons(a, b, n, f));
System.out.println();
return;
}
public static void main(String[] args)
{
testFunction("x^3", 0.0, 1.0, 100, new FPFunction() {
public double eval(double n) {
return n * n * n;
}
}
);
testFunction("1/x", 1.0, 100.0, 1000, new FPFunction() {
public double eval(double n) {
return 1.0 / n;
}
}
);
testFunction("x", 0.0, 5000.0, 5000000, new FPFunction() {
public double eval(double n) {
return n;
}
}
);
testFunction("x", 0.0, 6000.0, 6000000, new FPFunction() {
public double eval(double n) {
return n;
}
}
);
return;
}
}

View file

@ -0,0 +1,117 @@
while 1
read x$
if x$ ="end" then print "**Over**": end
read a, b, N, knownValue
print " Function y ="; x$; " from "; a; " to "; b; " in "; N; " steps"
print " Known exact value ="; knownValue
areaLR = IntegralByLeftRectangle( x$, a, b, N)
areaRR = IntegralByRightRectangle( x$, a, b, N)
areaMR = IntegralByMiddleRectangle( x$, a, b, N)
areaTr = IntegralByTrapezium( x$, a, b, N)
areaSi = IntegralBySimpsonRule( x$, a, b, N)
print "Left rectangle method "; using( "##########.##########", areaLR); " diff "; knownValue-areaLR; tab(70); (knownValue-areaLR)/knownValue*100;" %"
print "Right rectangle method "; using( "##########.##########", areaRR); " diff "; knownValue-areaRR; tab(70); (knownValue-areaRR)/knownValue*100;" %"
print "Middle rectangle method "; using( "##########.##########", areaMR); " diff "; knownValue-areaMR; tab(70); (knownValue-areaMR)/knownValue*100;" %"
print "Trapezium method "; using( "##########.##########", areaTr); " diff "; knownValue-areaTr; tab(70); (knownValue-areaTr)/knownValue*100;" %"
print "Simpson's Rule "; using( "##########.##########", areaSi); " diff "; knownValue-areaSi; tab(70); (knownValue-areaSi)/knownValue*100;" %"
print
wend
end
'------------------------------------------------------
'we have N sizes, that gives us N+1 points
'point 0 is a
'point N is b
'point i is xi =a +i *h
'Often, precision is (sharper?) then single step area
'So there should be EXACT number of steps, hence loop by integer i.
function IntegralByLeftRectangle( x$, a, b, N)
h = ( b -a) /N
s = 0
for i = 0 to N -1
x = a +i *h
s = s + h *eval( x$)
next
IntegralByLeftRectangle = s
end function
function IntegralByRightRectangle( x$, a, b, N)
h =( b -a) /N
s = 0
for i =1 to N
x = a +i *h
s = s + h *eval( x$)
next
IntegralByRightRectangle = s
end function
function IntegralByMiddleRectangle( x$, a, b, N)
h =( b -a) /N
s = 0
for i =0 to N -1
x = a +i *h +h /2
s = s + h *eval( x$)
next
IntegralByMiddleRectangle = s
end function
function IntegralByTrapezium( x$, a, b, N)
'Formula is h*((f(a)+f(b))/2 + sum_{i=1}^{N-1} (f(x_i)))
h =( b -a) /N
x = a
fa =eval( x$)
x =b
fb =eval( x$)
s = h *( fa +fb) /2
for i =1 to N -1
x = a +i *h
s = s + h *eval( x$)
next
IntegralByTrapezium = s
end function
function IntegralBySimpsonRule( x$, a, b, N)
'Simpson
'N should be even.
if N mod 2 then N =N +1
'It really doesn't look right to double number of points from N to 2N -
' - this method is most accurate of all presented!
'So we use NN as N/2, and N will be 2NN
'Formula is h/6*( f(a)+f(b) + 4*(f(x_1)+f(x_3)+...+f(x_{2NN-1})+ 2*(f(x_2)+f(x_4)+...+f(x_{2NN-2})) )
'Somehow I messed up h/6, h/3 and what is h, regarding "n=number of double intervals of size 2h"
NN =N /2
h =( b -a) /N
x =a
fa =eval (x$)
x =b
fb =eval( x$)
s = h /3 *( fa +fb)
for i =1 to 2 *NN -1 step 2
x = a +i *h
s = s + h /3 *4 *eval( x$) 'odd points
next
for i =2 to 2 *NN -2 step 2
x = a +i *h
s = s + h /3 *2 *eval( x$) 'even points
next
IntegralBySimpsonRule = s
end function
'=======================================================
data "x^3", 0, 1, 100, 0.25
data "x^-1", 1, 100, 1000, 4.605170
data "x", 0, 5000, 1000, 12500000.0 ' should use 5 000 000 steps
data "x", 0, 6000, 1000, 18000000.0 ' should use 6 000 000 steps
data "end"
end

View file

@ -0,0 +1,36 @@
to i.left :fn :x :step
output invoke :fn :x
end
to i.right :fn :x :step
output invoke :fn :x + :step
end
to i.mid :fn :x :step
output invoke :fn :x + :step/2
end
to i.trapezium :fn :x :step
output ((i.left :fn :x :step) + (i.right :fn :x :step)) / 2
end
to i.simpsons :fn :x :step
output ( (i.left :fn :x :step)
+ (i.mid :fn :x :step) * 4
+ (i.right :fn :x :step) ) / 6
end
to integrate :method :fn :steps :a :b
localmake "step (:b - :a) / :steps
localmake "sigma 0
; for [x :a :b-:step :step] [make "sigma :sigma + apply :method (list :fn :x :step)]
repeat :steps [
make "sigma :sigma + (invoke :method :fn :a :step)
make "a :a + :step ]
output :sigma * :step
end
to fn2 :x
output 2 / (1 + 4 * :x * :x)
end
print integrate "i.left "fn2 4 -1 2 ; 2.456897
print integrate "i.right "fn2 4 -1 2 ; 2.245132
print integrate "i.mid "fn2 4 -1 2 ; 2.496091
print integrate "i.trapezium "fn2 4 -1 2 ; 2.351014
print integrate "i.simpsons "fn2 4 -1 2 ; 2.447732

View file

@ -0,0 +1,73 @@
function leftRect( f, a, b, n )
local h = (b - a) / n
local x = a
local sum = 0
for i = 1, 100 do
sum = sum + a + f(x)
x = x + h
end
return sum * h
end
function rightRect( f, a, b, n )
local h = (b - a) / n
local x = b
local sum = 0
for i = 1, 100 do
sum = sum + a + f(x)
x = x - h
end
return sum * h
end
function midRect( f, a, b, n )
local h = (b - a) / n
local x = a + h/2
local sum = 0
for i = 1, 100 do
sum = sum + a + f(x)
x = x + h
end
return sum * h
end
function trapezium( f, a, b, n )
local h = (b - a) / n
local x = a
local sum = 0
for i = 1, 100 do
sum = sum + f(x)*2
x = x + h
end
return (b - a) * sum / (2 * n)
end
function simpson( f, a, b, n )
local h = (b - a) / n
local sum1 = f(a + h/2)
local sum2 = 0
for i = 1, n-1 do
sum1 = sum1 + f(a + h * i + h/2)
sum2 = sum2 + f(a + h * i)
end
return (h/6) * (f(a) + f(b) + 4*sum1 + 2*sum2)
end
int_methods = { leftRect, rightRect, midRect, trapezium, simpson }
for i = 1, 5 do
print( int_methods[i]( function(x) return x^3 end, 0, 1, 100 ) )
print( int_methods[i]( function(x) return 1/x end, 1, 100, 1000 ) )
print( int_methods[i]( function(x) return x end, 0, 5000, 5000000 ) )
print( int_methods[i]( function(x) return x end, 0, 6000, 6000000 ) )
end

View file

@ -0,0 +1,8 @@
function integral = leftRectIntegration(f,a,b,n)
format long;
width = (b-a)/n; %calculate the width of each devision
x = linspace(a,b,n); %define x-axis
integral = width * sum( f(x(1:n-1)) );
end

View file

@ -0,0 +1,8 @@
function integral = rightRectIntegration(f,a,b,n)
format long;
width = (b-a)/n; %calculate the width of each devision
x = linspace(a,b,n); %define x-axis
integral = width * sum( f(x(2:n)) );
end

View file

@ -0,0 +1,8 @@
function integral = midPointRectIntegration(f,a,b,n)
format long;
width = (b-a)/n; %calculate the width of each devision
x = linspace(a,b,n); %define x-axis
integral = width * sum( f( (x(1:n-1)+x(2:n))/2 ) );
end

View file

@ -0,0 +1,7 @@
function integral = trapezoidalIntegration(f,a,b,n)
format long;
x = linspace(a,b,n); %define x-axis
integral = trapz( x,f(x) );
end

View file

@ -0,0 +1 @@
integral = quad(f,a,b,tol)

View file

@ -0,0 +1,5 @@
trapezoidalIntegration(@(x)( exp(-(x.^2)) ),0,10,100000)
ans =
0.886226925452753

View file

@ -0,0 +1,5 @@
quad(@sin,0,pi,1/1000000000000)
ans =
2.000000000000000

View file

@ -0,0 +1,4 @@
function answer = fermiDirac(x)
k = 8.617343e-5; %Boltazmann's Constant in eV/K
answer = 1./( 1+exp( (x)/(k*2000) ) ); %Fermi-Dirac distribution with mu = 0 and T = 2000K
end

View file

@ -0,0 +1,5 @@
rightRectIntegration(@fermiDirac,-1,1,1000000)
ans =
0.999998006023282

View file

@ -0,0 +1,26 @@
leftRect[f_, a_Real, b_Real, N_Integer] :=
Module[{sum = 0, dx = (b - a)/N, x = a, n = N} ,
For[n = N, n > 0, n--, x += dx; sum += f[x];];
Return [ sum*dx ]]
rightRect[f_, a_Real, b_Real, N_Integer] :=
Module[{sum = 0, dx = (b - a)/N, x = a + (b - a)/N, n = N} ,
For[n = N, n > 0, n--, x += dx; sum += f[x];];
Return [ sum*dx ]]
midRect[f_, a_Real, b_Real, N_Integer] :=
Module[{sum = 0, dx = (b - a)/N, x = a + (b - a)/(2 N), n = N} ,
For[n = N, n > 0, n--, x += dx; sum += f[x];];
Return [ sum*dx ]]
trapezium[f_, a_Real, b_Real, N_Integer] :=
Module[{sum = f[a], dx = (b - a)/N, x = a, n = N} ,
For[n = 1, n < N, n++, x += dx; sum += 2 f[x];];
sum += f[b];
Return [ 0.5*sum*dx ]]
simpson[f_, a_Real, b_Real, N_Integer] :=
Module[{sum1 = f[a + (b - a)/(2 N)], sum2 = 0, dx = (b - a)/N, x = a, n = N} ,
For[n = 1, n < N, n++, sum1 += f[a + dx*n + dx/2];
sum2 += f[a + dx*n];];
Return [(dx/6)*(f[a] + f[b] + 4*sum1 + 2*sum2)]]

View file

@ -0,0 +1,27 @@
right_rect(e, x, a, b, n) := block([h: (b - a) / n, s: 0],
for i from 1 thru n do s: s + subst(x = a + i * h, e),
s * h)$
left_rect(e, x, a, b, n) := block([h: (b - a) / n, s: 0],
for i from 1 thru n do s: s + subst(x = a + (i - 1) * h, e),
s * h)$
mid_rect(e, x, a, b, n) := block([h: (b - a) / n, s: 0],
for i from 1 thru n do s: s + subst(x = a + (i - 1/2) * h, e),
s * h)$
trapezium(e, x, a, b, n) := block([h: (b - a) / n, s: 0],
for i from 1 thru n - 1 do s: s + subst(x = a + i * h, e),
((subst(x = a, e) + subst(x = b, e)) / 2 + s) * h)$
simpson(e, x, a, b, n) := block([h: (b - a) / n, s: 0],
for i from 1 thru n do
s: s + subst(x = a + i * h, e) + 2 * subst(x = a + (i - 1/2) * h, e),
(subst(x = a, e) - subst(x = b, e) + 2 * s) * h / 6)$
/* some tests */
simpson(log(x), x, 1, 2, 20), bfloat;
2 * log(2) - 1 - %, bfloat;
trapezium(1/x, x, 1, 100, 10000) - log(100), bfloat;

View file

@ -0,0 +1,7 @@
let integrate f a b steps meth =
let h = (b -. a) /. float_of_int steps in
let rec helper i s =
if i >= steps then s
else helper (succ i) (s +. meth f (a +. h *. float_of_int i) h)
in
h *. helper 0 0.

View file

@ -0,0 +1,7 @@
let methods = [
( "rect_l", fun f x _ -> f x);
( "rect_m", fun f x h -> f (x +. h /. 2.) );
( "rect_r", fun f x h -> f (x +. h) );
( "trap", fun f x h -> (f x +. f (x +. h)) /. 2. );
( "simp", fun f x h -> (f x +. 4. *. f (x +. h /. 2.) +. f (x +. h)) /. 6. )
]

View file

@ -0,0 +1,6 @@
let functions = [
( "cubic", (fun x -> x*.x*.x), 0.0, 1.0, 100);
( "recip", (fun x -> 1.0/.x), 1.0, 100.0, 1000);
( "x to 5e3", (fun x -> x), 0.0, 5000.0, 5_000_000);
( "x to 6e3", (fun x -> x), 0.0, 6000.0, 6_000_000)
]

View file

@ -0,0 +1,7 @@
let () =
List.iter (fun (s,f,lo,hi,n) ->
Printf.printf "Testing function %s:\n" s;
List.iter (fun (name,meth) ->
Printf.printf " method %s gives %.15g\n" name (integrate f lo hi n meth)
) methods
) functions

View file

@ -0,0 +1,29 @@
rectLeft(f, a, b, n)={
sum(i=0,n-1,f(a+(b-a)*i/n), 0.)*(b-a)/n
};
rectMid(f, a, b, n)={
sum(i=1,n,f(a+(b-a)*(i-.5)/n), 0.)*(b-a)/n
};
rectRight(f, a, b, n)={
sum(i=1,n,f(a+(b-a)*i/n), 0.)*(b-a)/n
};
trapezoidal(f, a, b, n)={
sum(i=1,n-1,f(a+(b-a)*i/n), f(a)/2+f(b)/2.)*(b-a)/n
};
Simpson(f, a, b, n)={
my(h=(b - a)/n, s);
s = 2*sum(i=1,n-1,
2*f(a + h * (i+1/2)) + f(a + h * i)
, 0.) + 4*f(a + h/2) + f(a) + f(b);
s * h / 6
};
test(f, a, b, n)={
my(v=[rectLeft, rectMid, rectRight, trapezoidal, Simpson]);
print("Testing function "f" on ",[a,b]," with "n" intervals:");
for(i=1,#v, print("\t"v[i](f, a, b, n)))
};
# \\ Turn on timer
test(x->x^3, 0, 1, 100)
test(x->1/x, 1, 100, 1000)
test(x->x, 0, 5000, 5000000)
test(x->x, 0, 6000, 6000000)

View file

@ -0,0 +1,43 @@
integrals: procedure options (main);
/* The function to be integrated */
f: procedure (x) returns (float);
declare x float;
return (3*x**2 + 2*x);
end f;
declare (a, b) float;
declare (rect_area, trap_area, Simpson) float;
declare (d, dx) fixed decimal (10,2);
declare (l, r) float;
declare (S1, S2) float;
l = 0; r = 5;
a = 0; b = 5; /* bounds of integration */
dx = 0.05;
/* Rectangle method */
rect_area = 0;
do d = a to b by dx;
rect_area = rect_area + dx*f(d);
end;
put skip data (rect_area);
/* trapezoid method */
trap_area = 0;
do d = a to b by dx;
trap_area = trap_area + dx*(f(d) + f(d+dx))/2;
end;
put skip data (trap_area);
/* Simpson's */
S1 = f(a+dx/2);
S2 = 0;
do d = a to b by dx;
S1 = S1 + f(d+dx+dx/2);
S2 = S2 + f(d+dx);
end;
Simpson = dx * (f(a) + f(b) + 4*S1 + 2*S2) / 6;
put skip data (Simpson);
end integrals;

View file

@ -0,0 +1,41 @@
function RectLeft(function f(x: real): real; xl, xr: real): real;
begin
RectLeft := f(xl)
end;
function RectMid(function f(x: real): real; xl, xr: real) : real;
begin
RectMid := f((xl+xr)/2)
end;
function RectRight(function f(x: real): real; xl, xr: real): real;
begin
RectRight := f(xr)
end;
function Trapezium(function f(x: real): real; xl, xr: real): real;
begin
Trapezium := (f(xl) + f(xr))/2
end;
function Simpson(function f(x: real): real; xl, xr: real): real;
begin
Simpson := (f(xl) + 4*f((xl+xr)/2) + f(xr))/6
end;
function integrate(function method(function f(x: real): real; xl, xr: real): real;
function f(x: real): real;
a, b: real;
n: integer);
var
integral, h: real;
k: integer;
begin
integral := 0;
h := (b-a)/n;
for k := 0 to n-1 do
begin
integral := integral + method(f, a + k*h, a + (k+1)*h)
end;
integrate := integral
end;

View file

@ -0,0 +1,51 @@
sub leftrect(&f, $a, $b, $n) {
my $h = ($b - $a) / $n;
$h * [+] do f($_) for $a, *+$h ... $b-$h;
}
sub rightrect(&f, $a, $b, $n) {
my $h = ($b - $a) / $n;
$h * [+] do f($_) for $a+$h, *+$h ... $b;
}
sub midrect(&f, $a, $b, $n) {
my $h = ($b - $a) / $n;
$h * [+] do f($_) for $a+$h/2, *+$h ... $b-$h/2;
}
sub trapez(&f, $a, $b, $n) {
my $h = ($b - $a) / $n;
$h / 2 * [+] f($a), f($b), do f($_) * 2 for $a+$h, *+$h ... $b-$h;
}
sub simpsons(&f, $a, $b, $n) {
my $h = ($b - $a) / $n;
my $h2 = $h/2;
my $sum1 = f($a + $h2);
my $sum2 = 0;
for $a+$h, *+$h ... $b-$h {
$sum1 += f($_ + $h2);
$sum2 += f($_);
}
($h / 6) * (f($a) + f($b) + 4*$sum1 + 2*$sum2);
}
sub tryem($f, $a, $b, $n, $exact) {
say "\n$f\n in [$a..$b] / $n";
eval "my &f = $f;
say ' exact result: ', $exact;
say ' rectangle method left: ', leftrect &f, $a, $b, $n;
say ' rectangle method right: ', rightrect &f, $a, $b, $n;
say ' rectangle method mid: ', midrect &f, $a, $b, $n;
say 'composite trapezoidal rule: ', trapez &f, $a, $b, $n;
say ' quadratic simpsons rule: ', simpsons &f, $a, $b, $n;"
}
tryem '{ $_ ** 3 }', 0, 1, 100, 0.25;
tryem '1 / *', 1, 100, 1000, log(100);
tryem '{$_}', 0, 5_000, 10_000, 12_500_000;
tryem '{$_}', 0, 6_000, 12_000, 18_000_000;

View file

@ -0,0 +1,35 @@
{ $_ ** 3 }
in [0..1] / 100
exact result: 0.25
rectangle method left: 0.245025
rectangle method right: 0.255025
rectangle method mid: 0.2499875
composite trapezoidal rule: 0.250025
quadratic simpsons rule: 0.25
1 / *
in [1..100] / 1000
exact result: 4.60517018598809
rectangle method left: 4.65499105751468
rectangle method right: 4.55698105751468
rectangle method mid: 4.60476254867838
composite trapezoidal rule: 4.60598605751468
quadratic simpsons rule: 4.60517038495714
{$_}
in [0..5000] / 10000
exact result: 12500000
rectangle method left: 12498750
rectangle method right: 12501250
rectangle method mid: 12500000
composite trapezoidal rule: 12500000
quadratic simpsons rule: 12500000
{$_}
in [0..6000] / 12000
exact result: 18000000
rectangle method left: 17998500
rectangle method right: 18001500
rectangle method mid: 18000000
composite trapezoidal rule: 18000000
quadratic simpsons rule: 18000000

View file

@ -0,0 +1,32 @@
(scl 6)
(de leftRect (Fun X)
(Fun X) )
(de rightRect (Fun X H)
(Fun (+ X H)) )
(de midRect (Fun X H)
(Fun (+ X (/ H 2))) )
(de trapezium (Fun X H)
(/ (+ (Fun X) (Fun (+ X H))) 2) )
(de simpson (Fun X H)
(*/
(+
(Fun X)
(* 4 (Fun (+ X (/ H 2))))
(Fun (+ X H)) )
6 ) )
(de square (X)
(*/ X X 1.0) )
(de integrate (Fun From To Steps Meth)
(let (H (/ (- To From) Steps) Sum 0)
(for (X From (>= (- To H) X) (+ X H))
(inc 'Sum (Meth Fun X H)) )
(*/ H Sum 1.0) ) )
(prinl (round (integrate square 3.0 7.0 30 simpson)))

View file

@ -0,0 +1,102 @@
Prototype.d TestFunction(Arg.d)
Procedure.d LeftIntegral(Start, Stop, Steps, *func.TestFunction)
Protected.d n=(Stop-Start)/Steps, sum, x=Start
While x <= Stop-n
sum + n * *func(x)
x + n
Wend
ProcedureReturn sum
EndProcedure
Procedure.d MidIntegral(Start, Stop, Steps, *func.TestFunction)
Protected.d n=(Stop-Start)/Steps, sum, x=Start
While x <= Stop-n
sum + n * *func(x+n/2)
x + n
Wend
ProcedureReturn sum
EndProcedure
Procedure.d RightIntegral(Start, Stop, Steps, *func.TestFunction)
Protected.d n=(Stop-Start)/Steps, sum, x=Start
While x < Stop
x + n
sum + n * *func(x)
Wend
ProcedureReturn sum
EndProcedure
Procedure.d Trapezium(Start, Stop, Steps, *func.TestFunction)
Protected.d n=(Stop-Start)/Steps, sum, x=Start
While x<=Stop
sum + n * (*func(x) + *func(x+n))/2
x+n
Wend
ProcedureReturn sum
EndProcedure
Procedure.d Simpson(Start, Stop, Steps, *func.TestFunction)
Protected.d n=(Stop-Start)/Steps, sum1, sum2, x=Start
Protected i
For i=0 To steps-1
sum1+ *func(Start+n*i+n/2)
Next
For i=1 To Steps-1
sum2+ *func(Start+n*i)
Next
ProcedureReturn n * (*func(Start)+ *func(Stop)+4*sum1+2*sum2) / 6
EndProcedure
;- Set up functions to integrate
Procedure.d Test1(n.d)
ProcedureReturn n*n*n
EndProcedure
Procedure.d Test2(n.d)
ProcedureReturn 1/n
EndProcedure
; This function should be integrated as a integer function, but for
; comparably this will stay as a float.
Procedure.d Test3(n.d)
ProcedureReturn n
EndProcedure
;- Test the code & present the results
CompilerIf #PB_Compiler_Debugger
MessageRequester("Notice!","Running this program in Debug-mode will be slow")
CompilerEndIf
; = 0.25
Define Answer$
Answer$="Left ="+StrD(LeftIntegral (0,1,100,@Test1()))+#CRLF$
Answer$+"Mid ="+StrD(MidIntegral (0,1,100,@Test1()))+#CRLF$
Answer$+"Right ="+StrD(RightIntegral(0,1,100,@Test1()))+#CRLF$
Answer$+"Trapezium="+StrD(Trapezium (0,1,100,@Test1()))+#CRLF$
Answer$+"Simpson ="+StrD(Simpson (0,1,100,@Test1()))
MessageRequester("Answer should be 1/4",Answer$)
; = Ln(100) e.g. ~4.60517019...
Answer$="Left ="+StrD(LeftIntegral (1,100,1000,@Test2()))+#CRLF$
Answer$+"Mid ="+StrD(MidIntegral (1,100,1000,@Test2()))+#CRLF$
Answer$+"Right ="+StrD(RightIntegral (1,100,1000,@Test2()))+#CRLF$
Answer$+"Trapezium="+StrD(Trapezium (1,100,1000,@Test2()))+#CRLF$
Answer$+"Simpson ="+StrD(Simpson (1,100,1000,@Test2()))
MessageRequester("Answer should be Ln(100), e.g. ~4.60517019",Answer$)
; 12,500,000
Answer$="Left ="+StrD(LeftIntegral (0,5000,5000000,@Test3()))+#CRLF$
Answer$+"Mid ="+StrD(MidIntegral (0,5000,5000000,@Test3()))+#CRLF$
Answer$+"Right ="+StrD(RightIntegral (0,5000,5000000,@Test3()))+#CRLF$
Answer$+"Trapezium="+StrD(Trapezium (0,5000,5000000,@Test3()))+#CRLF$
Answer$+"Simpson ="+StrD(Simpson (0,5000,5000000,@Test3()))
MessageRequester("Answer should be 12,500,000",Answer$)
; 18,000,000
Answer$="Left ="+StrD(LeftIntegral (0,6000,6000000,@Test3()))+#CRLF$
Answer$+"Mid ="+StrD(MidIntegral (0,6000,6000000,@Test3()))+#CRLF$
Answer$+"Right ="+StrD(RightIntegral (0,6000,6000000,@Test3()))+#CRLF$
Answer$+"Trapezium="+StrD(Trapezium (0,6000,6000000,@Test3()))+#CRLF$
Answer$+"Simpson ="+StrD(Simpson (0,6000,6000000,@Test3()))
MessageRequester("Answer should be 18,000,000",Answer$)

View file

@ -0,0 +1,55 @@
from fractions import Fraction
def left_rect(f,x,h):
return f(x)
def mid_rect(f,x,h):
return f(x + h/2)
def right_rect(f,x,h):
return f(x+h)
def trapezium(f,x,h):
return (f(x) + f(x+h))/2.0
def simpson(f,x,h):
return (f(x) + 4*f(x + h/2) + f(x+h))/6.0
def cube(x):
return x*x*x
def reciprocal(x):
return 1/x
def identity(x):
return x
def integrate( f, a, b, steps, meth):
h = (b-a)/steps
ival = h * sum(meth(f, a+i*h, h) for i in range(steps))
return ival
# Tests
for a, b, steps, func in ((0., 1., 100, cube), (1., 100., 1000, reciprocal)):
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps) = %r' %
(func.__name__, rule.__name__, a, b, steps,
integrate( func, a, b, steps, rule)))
a, b = Fraction.from_float(a), Fraction.from_float(b)
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps and fractions) = %r' %
(func.__name__, rule.__name__, a, b, steps,
float(integrate( func, a, b, steps, rule))))
# Extra tests (compute intensive)
for a, b, steps, func in ((0., 5000., 5000000, identity),
(0., 6000., 6000000, identity)):
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps) = %r' %
(func.__name__, rule.__name__, a, b, steps,
integrate( func, a, b, steps, rule)))
a, b = Fraction.from_float(a), Fraction.from_float(b)
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps and fractions) = %r' %
(func.__name__, rule.__name__, a, b, steps,
float(integrate( func, a, b, steps, rule))))

View file

@ -0,0 +1,23 @@
for a, b, steps, func in ((0., 1., 100, cube), (1., 100., 1000, reciprocal)):
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps) = %r' %
(func.__name__, rule.__name__, a, b, steps,
integrate( func, a, b, steps, rule)))
a, b = Fraction.from_float(a), Fraction.from_float(b)
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps and fractions) = %r' %
(func.__name__, rule.__name__, a, b, steps,
float(integrate( func, a, b, steps, rule))))
# Extra tests (compute intensive)
for a, b, steps, func in ((1., 5000., 5000000, identity),
(1., 6000., 6000000, identity)):
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps) = %r' %
(func.__name__, rule.__name__, a, b, steps,
integrate( func, a, b, steps, rule)))
a, b = Fraction.from_float(a), Fraction.from_float(b)
for rule in (left_rect, mid_rect, right_rect, trapezium, simpson):
print('%s integrated using %s\n from %r to %r (%i steps and fractions) = %r' %
(func.__name__, rule.__name__, a, b, steps,
float(integrate( func, a, b, steps, rule))))

View file

@ -0,0 +1,6 @@
def faster_simpson(f, a, b, steps):
h = (b-a)/steps
a1 = a+h/2
s1 = sum( f(a1+i*h) for i in range(0,steps))
s2 = sum( f(a+i*h) for i in range(1,steps))
return (h/6.0)*(f(a)+f(b)+4.0*s1+2.0*s2)

View file

@ -0,0 +1,36 @@
integrate.rect <- function(f, a, b, n, k=0) {
#k = 0 for left, 1 for right, 0.5 for midpoint
h <- (b-a)/n
x <- seq(a, b, len=n+1)
sum(f(x[-1]-h*(1-k)))*h
}
integrate.trapezoid <- function(f, a, b, n) {
h <- (b-a)/n
x <- seq(a, b, len=n+1)
fx <- f(x)
sum(fx[-1] + fx[-length(x)])*h/2
}
integrate.simpsons <- function(f, a, b, n) {
h <- (b-a)/n
x <- seq(a, b, len=n+1)
fx <- f(x)
sum(fx[-length(x)] + 4*f(x[-1]-h/2) + fx[-1]) * h/6
}
f1 <- (function(x) {x^3})
f2 <- (function(x) {1/x})
f3 <- (function(x) {x})
f4 <- (function(x) {x})
integrate.simpsons(f1,0,1,100) #0.25
integrate.simpsons(f2,1,100,1000) # 4.60517
integrate.simpsons(f3,0,5000,5000000) # 12500000
integrate.simpsons(f4,0,6000,6000000) # 1.8e+07
integrate.rect(f1,0,1,100,0) #TopLeft 0.245025
integrate.rect(f1,0,1,100,0.5) #Mid 0.2499875
integrate.rect(f1,0,1,100,1) #TopRight 0.255025
integrate.trapezoid(f1,0,1,100) # 0.250025

View file

@ -0,0 +1,60 @@
/*REXX program numerically integrates using five different methods. */
numeric digits 20 /*use twenty digits precision. */
do test=1 for 4 /*perform the test suite. */
if test==1 then do; L=0; H= 1; i= 100; end
if test==2 then do; L=1; H= 100; i= 1000; end
if test==3 then do; L=0; H=5000; i=5000000; end
if test==4 then do; L=0; H=6000; i=5000000; end
say
say center('test' test,79,'') /*display a header for the test. */
say ' left_rectangular('L","H','i") = " left_rect(L,H,i)
say ' midpoint_rectangular('L","H','i") = " midpoint_rect(L,H,i)
say ' right_rectangular('L","H','i") = " right_rect(L,H,i)
say ' simpson('L","H','i") = " simpson(L,H,i)
say ' trapezoid('L","H','i") = " trapezoid(L,H,i)
end /*test*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────LEFT_RECT subroutine────────────────*/
left_rect: procedure expose test; parse arg a,b,n; h=(b-a)/n
sum=0
do x=a by h for n
sum=sum+f(x)
end
return sum*h
/*──────────────────────────────────MIDPOINT_RECT subroutine────────────*/
midpoint_rect: procedure expose test; parse arg a,b,n; h=(b-a)/n
sum=0
do x=a+h/2 by h for n
sum=sum+f(x)
end
return sum*h
/*──────────────────────────────────RIGHT_RECT subroutine───────────────*/
right_rect: procedure expose test; parse arg a,b,n; h=(b-a)/n
sum=0
do x=a+h by h for n
sum=sum+f(x)
end
return sum*h
/*──────────────────────────────────SIMPSON subroutine──────────────────*/
simpson: procedure expose test; parse arg a,b,n; h=(b-a)/n
sum1=f(a+h/2)
sum2=0
do x=1 to n-1
sum1=sum1+f(a+h*x+h*.5)
sum2=sum2+f(a+x*h)
end
return h*(f(a)+f(b)+4*sum1+2*sum2)/6
/*──────────────────────────────────TRAPEZOID subroutine────────────────*/
trapezoid: procedure expose test; parse arg a,b,n; h=(b-a)/n
sum=0
do x=a to b by h
sum=sum+h*(f(x)+f(x+h))*.5
end
return sum
/*──────────────────────────────────F subroutine────────────────────────*/
f: procedure expose test; parse arg z
if test==1 then return z**3
if test==2 then return 1/z
return z

View file

@ -0,0 +1,58 @@
def leftrect(f, left, right)
f.call(left)
end
def midrect(f, left, right)
f.call((left+right)/2.0)
end
def rightrect(f, left, right)
f.call(right)
end
def trapezium(f, left, right)
(f.call(left) + f.call(right)) / 2.0
end
def simpson(f, left, right)
(f.call(left) + 4*f.call((left+right)/2.0) + f.call(right)) / 6.0
end
def integrate(f, a, b, steps, method)
delta = 1.0 * (b - a) / steps
total = 0.0
steps.times do |i|
left = a + i*delta
right = left + delta
total += delta * send(method, f, left, right)
end
total
end
def square(x)
x**2
end
def def_int(f, a, b)
l = case f.to_s
when /sin>/
lambda {|x| -Math.cos(x)}
when /square>/
lambda {|x| (x**3)/3.0}
end
l.call(b) - l.call(a)
end
a = 0
b = Math::PI
steps = 10
for func in [method(:square), Math.method(:sin)]
puts "integral of #{func} from #{a} to #{b} in #{steps} steps"
actual = def_int(func, a, b)
for method in [:leftrect, :midrect, :rightrect, :trapezium, :simpson]
int = integrate(func, a, b, steps, method)
diff = (int - actual) * 100.0 / actual
printf " %-10s %s\t(%.1f%%)\n", method, int, diff
end
end

View file

@ -0,0 +1,35 @@
object NumericalIntegration {
def leftRect(f:Double=>Double, a:Double, b:Double)=f(a)
def midRect(f:Double=>Double, a:Double, b:Double)=f((a+b)/2)
def rightRect(f:Double=>Double, a:Double, b:Double)=f(b)
def trapezoid(f:Double=>Double, a:Double, b:Double)=(f(a)+f(b))/2
def simpson(f:Double=>Double, a:Double, b:Double)=(f(a)+4*f((a+b)/2)+f(b))/6;
def fn1(x:Double)=x*x*x
def fn2(x:Double)=1/x
def fn3(x:Double)=x
type Method = (Double=>Double, Double, Double) => Double
def integrate(f:Double=>Double, a:Double, b:Double, steps:Double, m:Method)={
val delta:Double=(b-a)/steps
delta*(a until b by delta).foldLeft(0.0)((s,x) => s+m(f, x, x+delta))
}
def print(f:Double=>Double, a:Double, b:Double, steps:Double)={
println("rectangular left : %f".format(integrate(f, a, b, steps, leftRect)))
println("rectangular middle : %f".format(integrate(f, a, b, steps, midRect)))
println("rectangular right : %f".format(integrate(f, a, b, steps, rightRect)))
println("trapezoid : %f".format(integrate(f, a, b, steps, trapezoid)))
println("simpson : %f".format(integrate(f, a, b, steps, simpson)))
}
def main(args: Array[String]): Unit = {
print(fn1, 0, 1, 100)
println("------")
print(fn2, 1, 100, 1000)
println("------")
print(fn3, 0, 5000, 5000000)
println("------")
print(fn3, 0, 6000, 6000000)
}
}

View file

@ -0,0 +1,21 @@
(define (integrate f a b steps meth)
(define h (/ (- b a) steps))
(* h
(let loop ((i 0) (s 0))
(if (>= i steps)
s
(loop (+ i 1) (+ s (meth f (+ a (* h i)) h)))))))
(define (left-rect f x h) (f x))
(define (mid-rect f x h) (f (+ x (/ h 2))))
(define (right-rect f x h) (f (+ x h)))
(define (trapezium f x h) (/ (+ (f x) (f (+ x h))) 2))
(define (simpson f x h) (/ (+ (f x) (* 4 (f (+ x (/ h 2)))) (f (+ x h))) 6))
(define (square x) (* x x))
(define rl (integrate square 0 1 10 left-rect))
(define rm (integrate square 0 1 10 mid-rect))
(define rr (integrate square 0 1 10 right-rect))
(define t (integrate square 0 1 10 trapezium))
(define s (integrate square 0 1 10 simpson))

View file

@ -0,0 +1,23 @@
fun integrate (f, a, b, steps, meth) = let
val h = (b - a) / real steps
fun helper (i, s) =
if i >= steps then s
else helper (i+1, s + meth (f, a + h * real i, h))
in
h * helper (0, 0.0)
end
fun leftRect (f, x, _) = f x
fun midRect (f, x, h) = f (x + h / 2.0)
fun rightRect (f, x, h) = f (x + h)
fun trapezium (f, x, h) = (f x + f (x + h)) / 2.0
fun simpson (f, x, h) = (f x + 4.0 * f (x + h / 2.0) + f (x + h)) / 6.0
fun square x = x * x
val rl = integrate (square, 0.0, 1.0, 10, left_rect )
val rm = integrate (square, 0.0, 1.0, 10, mid_rect )
val rr = integrate (square, 0.0, 1.0, 10, right_rect)
val t = integrate (square, 0.0, 1.0, 10, trapezium )
val s = integrate (square, 0.0, 1.0, 10, simpson )

View file

@ -0,0 +1,54 @@
package require Tcl 8.5
proc leftrect {f left right} {
$f $left
}
proc midrect {f left right} {
set mid [expr {($left + $right) / 2.0}]
$f $mid
}
proc rightrect {f left right} {
$f $right
}
proc trapezium {f left right} {
expr {([$f $left] + [$f $right]) / 2.0}
}
proc simpson {f left right} {
set mid [expr {($left + $right) / 2.0}]
expr {([$f $left] + 4*[$f $mid] + [$f $right]) / 6.0}
}
proc integrate {f a b steps method} {
set delta [expr {1.0 * ($b - $a) / $steps}]
set total 0.0
for {set i 0} {$i < $steps} {incr i} {
set left [expr {$a + $i * $delta}]
set right [expr {$left + $delta}]
set total [expr {$total + $delta * [$method $f $left $right]}]
}
return $total
}
interp alias {} sin {} ::tcl::mathfunc::sin
proc square x {expr {$x*$x}}
proc def_int {f a b} {
switch -- $f {
sin {set lambda {x {expr {-cos($x)}}}}
square {set lambda {x {expr {$x**3/3.0}}}}
}
return [expr {[apply $lambda $b] - [apply $lambda $a]}]
}
set a 0
set b [expr {4*atan(1)}]
set steps 10
foreach func {square sin} {
puts "integral of ${func}(x) from $a to $b in $steps steps"
set actual [def_int $func $a $b]
foreach method {leftrect midrect rightrect trapezium simpson} {
set int [integrate $func $a $b $steps $method]
set diff [expr {($int - $actual) * 100.0 / $actual}]
puts [format " %-10s %s\t(%.1f%%)" $method $int $diff]
}
}

View file

@ -0,0 +1,7 @@
#import std
#import nat
#import flo
(integral_by "m") ("f","a","b","n") =
iprod ^(* ! div\float"n" minus/"b" "a",~&) ("m" "f")*ytp (ari successor "n")/"a" "b"

View file

@ -0,0 +1,3 @@
(integral_by "m") ("f","a","b","n") =
iprod ^(* ! div\float"n" minus/"b" "a",~&) ^H(*+ "m"+ -:"f"+ * ^/~& "f",~&ytp) (ari successor "n")/"a" "b"

View file

@ -0,0 +1,5 @@
left = integral_by "f". ("l","r"). "f" "l"
right = integral_by "f". ("l","r"). "f" "r"
midpoint = integral_by "f". ("l","r"). "f" div\2. plus/"l" "r"
trapezium = integral_by "f". ("l","r"). div\2. plus "f"~~/"l" "r"
simpson = integral_by "f". ("l","r"). div\6. plus:-0. <"f" "l",times/4. "f" div\2. plus/"l" "r","f" "r">

View file

@ -0,0 +1,3 @@
#cast %eL
examples = <.left,midpoint,rignt,trapezium,simpson> (sqr,0.,pi,10)

View file

@ -0,0 +1,47 @@
include c:\cxpl\codes; \intrinsic 'code' declarations
func real Func(FN, X); \Return F(X) for function number FN
int FN; real X;
[case FN of
1: return X*X*X;
2: return 1.0/X;
3: return X
other return 0.0;
];
func Integrate(A, B, FN, N); \Display area under curve for function FN
real A, B; int FN, N; \limits A, B, and number of slices N
real DX, X, Area; \delta X
int I;
[DX:= (B-A)/float(N);
X:= A; Area:= 0.0; \rectangular left
for I:= 1 to N do
[Area:= Area + Func(FN,X)*DX; X:= X+DX];
RlOut(0, Area);
X:= A; Area:= 0.0; \rectangular right
for I:= 1 to N do
[X:= X+DX; Area:= Area + Func(FN,X)*DX];
RlOut(0, Area);
X:= A+DX/2.0; Area:= 0.0; \rectangular mid point
for I:= 1 to N do
[Area:= Area + Func(FN,X)*DX; X:= X+DX];
RlOut(0, Area);
X:= A; Area:= 0.0; \trapezium
for I:= 1 to N do
[Area:= Area + (Func(FN,X)+Func(FN,X+DX))/2.0*DX; X:= X+DX];
RlOut(0, Area);
X:= A; Area:= 0.0; \Simpson's rule
for I:= 1 to N do
[Area:= Area +
DX/6.0*(Func(FN,X) + 4.0*Func(FN,(X+X+DX)/2.0) + Func(FN,X+DX));
X:= X+DX];
RlOut(0, Area);
CrLf(0);
];
[Format(9,6);
Integrate(0.0, 1.0, 1, 100);
Integrate(1.0, 100.0, 2, 1000);
Integrate(0.0, 5000.0, 3, 5_000_000);
Integrate(0.0, 6000.0, 3, 6_000_000);
]