Numerical integration: Difference between revisions

Content deleted Content added
Sonia (talk | contribs)
→‎{{header|Go}}: improved summation algorithm
Line 1,336:
"fmt"
"math"
"sort"
)
 
Line 1,351 ⟶ 1,350:
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 }},
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{
Line 1,370:
method{"Simpson's ", simpson},
}
 
func rectLeft(t spec) float64 {
parts := make([]float64, t.n)
Line 1,456:
 
// sum a list of numbers avoiding loss of precision
func sum(partsv []float64) float64 {
// (there might be better ways...)
if len(v) == 0 {
func sum(parts []float64) float64 {
return 0
sort.Float64s(parts)
}
ip := sort.SearchFloat64s(parts, 0)
invar :=parts ip - 1[]float64
sumfor _, x := parts[ip]range v {
ip++ var i int
for _, p := range parts {
if sum <:= p 0+ {x
ifvar iperr < len(parts) {float64
if math.Abs(x) < math.Abs(p) // add the next biggest positive part{
sumerr += parts[ip]x - (sum - p)
ip++
} else {
//err no= morep positive- parts.(sum - x)
// add remaining negatives and exit loop
for ; in >= 0; in-- {
sum += parts[in]
}
break
}
} else if err != 0 {
if in >= 0 {parts[i] = err
// add the next biggest negative parti++
sum += parts[in]
in--
} else {
// no more negative parts.
// add remaining positives and exit loop
for ; ip < len(parts); ip++ {
sum += parts[ip]
}
break
}
x = ip++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")
"in", t.n, sum += "parts[in]")
fmt.Printf("Exact result %.7e Error\n", t.exact)
for _, m := range methods {
Line 1,512 ⟶ 1,504:
}</lang>
Output:
<pre>
<pre>Test case: f(x) = x^3
Integration from 0 to 1 in 100 parts
Exact result 2.5000000e-01 Error
Line 1,519 ⟶ 1,512:
Rectangular (midpoint) 2.4998750e-01 1.2500000e-05
Trapezium 2.5002500e-01 2.5000000e-05
Simpson's 2.5000000e-01 50.5511151e-170000000e+00
 
Test case: f(x) = 1/x
Line 1,535 ⟶ 1,528:
Rectangular (left) 1.2499975e+07 2.5000000e+01
Rectangular (right) 1.2500025e+07 2.5000000e+01
Rectangular (midpoint) 1.2500000e+07 10.6763806e-080000000e+00
Trapezium 1.2500000e+07 30.7252903e-080000000e+00
Simpson's 1.2500000e+07 20.9802322e-080000000e+00
 
Test case: f(x) = x
Line 1,544 ⟶ 1,537:
Rectangular (left) 1.7999997e+07 3.0000000e+00
Rectangular (right) 1.8000003e+07 3.0000000e+00
Rectangular (midpoint) 1.8000000e+07 10.4901161e-080000000e+00
Trapezium 1.8000000e+07 10.8626451e-080000000e+00
Simpson's 1.8000000e+07 70.4505806e-09</pre>0000000e+00
</pre>
 
=={{header|Groovy}}==