File: 21more_derivatives.t

package info (click to toggle)
libmath-symbolic-perl 0.612-2.1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,260 kB
  • sloc: perl: 12,634; makefile: 2
file content (90 lines) | stat: -rw-r--r-- 2,073 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!perl
use strict;
use warnings;
use Carp qw/croak/;
use Test::More tests => 12;
BEGIN {
    use_ok('Math::Symbolic');
}
use Math::Symbolic qw/:all/;
use Math::Symbolic::Derivative qw/partial_derivative/;

if ($ENV{TEST_YAPP_PARSER}) {
	require Math::Symbolic::Parser::Yapp;
	$Math::Symbolic::Parser = Math::Symbolic::Parser::Yapp->new();
}


my @f = (
    [
        q{-a+b*x},
        q{b}
    ],
    [
        q{a+b*x+c*x^2},
        q{b+2*c*x}
    ],
    [
        q{a+x+}.join('+', map {"x^$_"} 2..10),
        '1+'.join('+', map {"$_*x^".($_-1)} 2..10)
    ],
    [
        q{sin(2*x)*cos(3*x)},
        q{2*cos(2*x)*cos(3*x)-3*sin(3*x)*sin(2*x)},
    ],
    [
        q{log(a, 2*x)},
        q{2/(log(2.71828182845905, a)*2*x)},
        { x => sub {$_[0] > 0}, a => sub {$_[0] > 0}, }
    ],
    [
        q{x/x^2},
        q{-1/x^2},
        { x => sub {$_[0] > 0} },
    ],
    [
        q{2/x},
        q{-2/x^2},
        { x => sub {$_[0] > 0} },
    ],
    [
        q{c/x},
        q{-c/x^2},
        { x => sub {$_[0] > 0} },
    ],
);

foreach my $ref (@f) {
    my ($f, $deriv) = map { parse_from_string($_) } @{$ref}[0,1];
    my $limits = $ref->[2];
    die "parse of '$ref->[0]' failed" if not defined $f;
    die "parse of '$ref->[1]' failed" if not defined $deriv;
    my $d = partial_derivative($f, 'x');
    ok($d->test_num_equiv($deriv, limits => $limits), "$d == $deriv");
}

# Test for regression RT #43783
{
  my $formula1    = parse_from_string('K-C*exp(-L*x)');
  my $formula2    = parse_from_string('K+-C*exp(-L*x)');

  my %parameters = ( C => 0.8, K => 1., L => 1. );

  my $deriv1 = partial_derivative($formula1, 'C')->apply_derivatives()->simplify();
  my $deriv2 = partial_derivative($formula2, 'C')->apply_derivatives()->simplify();

  foreach (1, 2, 3) {
    ok(
      float_eq( 
        $deriv1->value(%parameters, x => $_),
        $deriv2->value(%parameters, x => $_)
      ),
      "Derivatives of semantically equivalent formulas equivalent at x=$_"
    );
  }
}

sub float_eq {
  $_[0] + 1.e-6 > $_[1] and $_[0] - 1.e-6 < $_[1]
}