В продолжение http://friendfeed.com/kkapp/b5d3658c.
Численные методы вычисления аналитически сложных функций всегда казались очень крутым хаком реальности, жалко, что в работе применить не удалось.
Простейшая численная интеграция линейными функциями. Потратил условный час работы в течение двух дней. Тесты вычислял руками и ВольфрамАльфой.
#! /usr/bin/perl use strict; use warnings; use List::Util qw/sum/; use Test::Most; use Test::Number::Delta within => 0.001; use Data::Dump; my $EPS = 0.000001; sub integrate { my ($f, $x1, $x2) = @_; my $d = 1; my ($cur, $prev) = 0; do { my $dx = ($x2 - $x1) / $d; $prev = $cur; $cur = sum map { $dx * ( $f->($x1 + $dx * $_) + ($f->($x1 + $dx * ($_ + 1)) - $f->($x1 + $dx * $_)) / 2) } 0 .. ($d - 1); $d *= 2; } while (abs($cur - $prev) > $EPS); return $cur; } delta_ok(integrate(sub { $_[0] * 10 }, 2, 5), 105); delta_ok(integrate(sub { 100 - $_[0] * 10 }, 2, 5), 195); delta_ok(integrate(sub { 3 }, 1, 10), 27); delta_ok(integrate(sub { -2 * $_[0] }, -3, 4), -7); delta_ok(integrate(sub { $_[0] ** 2 }, 0, 5), 125/3); delta_ok(integrate(sub { sin($_[0]) }, 0, 3.1415), 2); delta_ok(integrate(sub { sin($_[0]) }, 0, 3 * 3.1415), 2); delta_ok(integrate(sub { -($_[0] ** 4) }, -5, -2), -3093/5); done_testing;