Numerical integration: Difference between revisions
→{{header|Go}}: fix float type per language change
m ('round' defaults to 3) |
(→{{header|Go}}: fix float type per language change) |
||
Line 1,007:
end module FunctionHolder</lang>
=={{header|Go}}==
<lang go>package main▼
<lang go>▼
▲package main
import (
Line 1,019 ⟶ 1,017:
// specification for an integration
type spec struct {
lower, upper
n int // number of parts
exact
fs string // mathematical description of function
f func(
}
// test cases per task description
var data = []spec{
spec{0, 1, 100, .25, "x^3", func(x
spec{1, 100, 1000,
spec{0, 5000, 5e5, 12.5e6, "x", func(x
spec{0, 6000, 6e6, 18e6, "x", func(x
}
Line 1,037 ⟶ 1,035:
type method struct {
name string
integrate func(spec)
}
Line 1,049 ⟶ 1,047:
}
func rectLeft(t spec)
parts := make([]
r := t.upper - t.lower
nf :=
x0 := t.lower
for i := range parts {
x1 := t.lower +
// x1-x0 better than r/nf.
// (with r/nf, the represenation error accumulates)
Line 1,064 ⟶ 1,062:
}
func rectRight(t spec)
parts := make([]
r := t.upper - t.lower
nf :=
x0 := t.lower
for i := range parts {
x1 := t.lower +
parts[i] = t.f(x1) * (x1 - x0)
x0 = x1
Line 1,077 ⟶ 1,075:
}
func rectMid(t spec)
parts := make([]
r := t.upper - t.lower
nf :=
// 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
Line 1,089 ⟶ 1,087:
x0 := t.lower - .5*r/nf
for i := range parts {
x1 := t.lower + (
parts[i] = t.f(x1) * (x1 - x0)
x0 = x1
Line 1,096 ⟶ 1,094:
}
func trap(t spec)
parts := make([]
r := t.upper - t.lower
nf :=
x0 := t.lower
f0 := t.f(x0)
for i := range parts {
x1 := t.lower +
f1 := t.f(x1)
parts[i] = (f0 + f1) * .5 * (x1 - x0)
Line 1,111 ⟶ 1,109:
}
func simpson(t spec)
parts := make([]
r := t.upper - t.lower
nf :=
// similar to the rectangle midpoint logic explained above,
// we play a little loose with the values used for dx and dx0.
Line 1,122 ⟶ 1,120:
x0 := t.lower + dx0
for i := 1; i < t.n; i++ {
x1 := t.lower +
xmid := (x0 + x1) * .5
dx := x1 - x0
Line 1,131 ⟶ 1,129:
parts[2*t.n] = t.f(t.upper) * dx0
return sum(parts) / 6
}
// sum a list of numbers avoiding loss of precision
// (there might be better ways...)
func sum(parts []
in := ip - 1
sum := parts[ip]
ip++
Line 1,187 ⟶ 1,186:
fmt.Println("")
}
Output:
<pre>Test case: f(x) = x^3▼
▲Test case: f(x) = x^3
Integration from 0 to 1 in 100 parts
Exact result 2.5000000e-01 Error
Rectangular (left) 2.
Rectangular (right) 2.5502500e-01 5.
Rectangular (midpoint) 2.
Trapezium 2.5002500e-01 2.
Simpson's 2.
Test case: f(x) = 1/x
Integration from 1 to 100 in 1000 parts
Exact result 4.6051702e+00 Error
Rectangular (right) 4.
Rectangular (midpoint) 4.
Trapezium 4.6059861e+00 8.
Simpson's 4.
Test case: f(x) = x
Integration from 0 to 5000 in 500000 parts
Exact result 1.2500000e+07 Error
Rectangular (left) 1.
Rectangular (right) 1.
Rectangular (midpoint) 1.
Trapezium 1.
Simpson's 1.
Test case: f(x) = x
Integration from 0 to 6000 in 6000000 parts
Exact result 1.8000000e+07 Error
Rectangular (left) 1.
Rectangular (right) 1.
Rectangular (midpoint) 1.
Trapezium 1.
Simpson's 1.
=={{header|Haskell}}==
|