Numerical integration: Difference between revisions

Content added Content deleted
No edit summary
m (→‎{{header|Perl 6}}: Added 'Promise' for concurrency)
Line 3,340: Line 3,340:


=={{header|Perl 6}}==
=={{header|Perl 6}}==
The addition of <tt>'''Promise'''</tt>/<tt>'''await'''</tt>, in two places, allows for concurrent computation, and brings a significant speed-up in running time. Which is not to say that it makes this code fast, but it does make it less slow.

{{works with|rakudo|2016-11}}
{{works with|rakudo|2018-09}}


<lang perl6>use MONKEY-SEE-NO-EVAL;
<lang perl6>use MONKEY-SEE-NO-EVAL;


Line 3,380: Line 3,378:
}
}
sub tryem($f, $a, $b, $n, $exact) {
sub integrate($f, $a, $b, $n, $exact) {
my @r0;
say "\n$f\n in [$a..$b] / $n";
EVAL "my &f = $f;
my $e = 0.000001;
@r0.push: "$f\n in [$a..$b] / $n\n";
say ' exact result: ', $exact;
say ' rectangle method left: ', leftrect &f, $a, $b, $n;
@r0.push: ' exact result: '~ $exact.round($e);

say ' rectangle method right: ', rightrect &f, $a, $b, $n;
my (@r1,@r2,@r3,@r4,@r5);
say ' rectangle method mid: ', midrect &f, $a, $b, $n;
my &f;
say 'composite trapezoidal rule: ', trapez &f, $a, $b, $n;
EVAL "&f = $f";
say ' quadratic simpsons rule: ', simpsons &f, $a, $b, $n;"
my $p1 = Promise.start( { @r1.push: ' rectangle method left: '~ leftrect(&f, $a, $b, $n).round($e) } );
my $p2 = Promise.start( { @r2.push: ' rectangle method right: '~ rightrect(&f, $a, $b, $n).round($e) } );
my $p3 = Promise.start( { @r3.push: ' rectangle method mid: '~ midrect(&f, $a, $b, $n).round($e) } );
my $p4 = Promise.start( { @r4.push: 'composite trapezoidal rule: '~ trapez(&f, $a, $b, $n).round($e) } );
my $p5 = Promise.start( { @r5.push: ' quadratic simpsons rule: '~ simpsons(&f, $a, $b, $n).round($e) } );

await $p1, $p2, $p3, $p4, $p5;
@r0, @r1, @r2, @r3, @r4, @r5;
}
}
tryem '{ $_ ** 3 }', 0, 1, 100, 0.25;
.say for integrate '{ $_ ** 3 }', 0, 1, 100, 0.25; say '';
.say for integrate '1 / *', 1, 100, 1000, log(100); say '';
.say for integrate '*.self', 0, 5_000, 5_000_000, 12_500_000; say '';
tryem '1 / *', 1, 100, 1000, log(100);
.say for integrate '*.self', 0, 6_000, 6_000_000, 18_000_000;</lang>
tryem '*.self', 0, 5_000, 5_000_000, 12_500_000;
tryem '*.self', 0, 6_000, 6_000_000, 18_000_000;</lang>
{{out}}
{{out}}
<lang>{ $_ ** 3 }
<lang>{ $_ ** 3 }
Line 3,410: Line 3,413:
1 / *
1 / *
in [1..100] / 1000
in [1..100] / 1000
exact result: 4.60517018598809
exact result: 4.60517
rectangle method left: 4.65499105751468
rectangle method left: 4.654991
rectangle method right: 4.55698105751468
rectangle method right: 4.556981
rectangle method mid: 4.60476254867838
rectangle method mid: 4.604763
composite trapezoidal rule: 4.60598605751468
composite trapezoidal rule: 4.605986
quadratic simpsons rule: 4.60517038495714
quadratic simpsons rule: 4.60517


*.self
*.self
Line 3,435: Line 3,438:
quadratic simpsons rule: 18000000</lang>
quadratic simpsons rule: 18000000</lang>


Note that these integrations are done with rationals rather than floats, so should be fairly precise (though of course with so few iterations they are not terribly accurate (except when they are)). Some of the sums do overflow into Num (floating point)--currently rakudo allows 64-bit denominators--but at least all of the interval arithmetic is exact.
Note that these integrations are done with rationals rather than floats, so should be fairly precise (though of course with so few iterations they are not terribly accurate (except when they are)). Some of the sums do overflow into <tt>Num</tt> (floating point)--currently Rakudo allows 64-bit denominators--but at least all of the interval arithmetic is exact.


=={{header|Phix}}==
=={{header|Phix}}==