Source

perl-PDL-Lib-Linear-Solve / t / lin_solve.t

#!/usr/bin/perl

use strict;
use warnings;

use constant NUM_LINEAR_SOLVE_TESTS => 4;
use constant NUM_INV_TESTS => 5;
use Test::More tests => (NUM_LINEAR_SOLVE_TESTS+NUM_INV_TESTS);

use PDL;

use PDL::Lib::Linear::Solve;

sub eye
{
    my $n = shift;
    my $pdl = zeroes($n,$n);
    $pdl->diagonal(0,1)++;
    return $pdl;
}

sub tapprox {
    my($a,$b) = @_;
    my $c = abs($a-$b);
    my $d = max($c);
    $d < 0.01;
}

my @linear_solve_tests =
(
    {
        'in_c' => [[1,1],[0,1]],
        'in_v' => [[5],[2]],
        'out_c' => eye(2),
        'out_v' => [[3],[2]],
    },
    {
        'in_c' => [[1,1,1],[0,1,1],[1,1,0]],
        'in_v' => eye(3),
        'out_c' => eye(3),
        'out_v' => [[1,-1,0],[-1,1,1],[1,0,-1]],
    },
    {
        # This is a singular matrix.
        'in_c' => [[1,1,1],[1,1,0],[2,2,0]],
        'in_v' => eye(3),
        'out_c' => [[1,1,1],[0,0,-1],[0,0,-2]],
        'out_v' => [[1,0,0],[-1,1,0],[-2,0,1]],
    },
    {
        # Test the identity.
        'in_c' => eye(2),
        'in_v' => eye(2),
        'out_c' => eye(2),
        'out_v' => eye(2),
    },
);

if (scalar(@linear_solve_tests) != NUM_LINEAR_SOLVE_TESTS)
{
    die "Incorrect number of linear solve tests!";
}

foreach my $t (@linear_solve_tests)
{
    my @out_array = linear_solve(map { pdl($_) } @$t{'in_c','in_v'});
    ok(tapprox($out_array[0], pdl($t->{'out_c'})) &&
       tapprox($out_array[1], pdl($t->{'out_v'})));
}

my @inv_tests =
(
    {
        'in_mat' => [[1,0],[0,1]],
    },
    {
        'in_mat' => [[0,1],[1,0]],
    },
    {
        'in_mat' => [[1,1],[1,0]],
    },
    {
        'in_mat' => [[1,1,1],[1,0,0],[0,2,0]],
    },
    {
        'in_mat' => [[1,2,3],[4,5,6],[-100,2,100]],
    },    
);

if (scalar(@inv_tests) != NUM_INV_TESTS)
{
    die "Incorrect number of inv tests!";
}

foreach my $t (@inv_tests)
{
    my $mat = pdl($t->{'in_mat'});
    my @dims = dims($mat);
    if ((scalar(@dims) != 2) || ($dims[0] != $dims[1]))
    {
        die "Incorrect input for inv:\n$mat\n";
    }
    my $result = myinv($mat);
    ok(tapprox($mat x $result, eye($dims[0])));
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.