######################### -*- Mode: Perl -*- #########################
##
## File          : $Basename: lsp.t $
##
## Author        : Norbert Goevert
## Created On    : Wed Nov 11 15:56:08 1998
## Last Modified : Time-stamp: <2000-11-19 18:59:14 goevert>
##
## Description   : regression tests for LSP
##
## $Id: lsp.t 1.5 Wed, 29 Nov 2000 09:57:57 +0100 goevert $
## $ProjectHeader: LSP 2.6 Wed, 29 Nov 2000 09:57:57 +0100 goevert $
##
######################################################################


# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'

use strict;

use Test;

######################### We start with some black magic to print on failure.

# Change `plan tests => 1' below to `plan tests => last_test_to_print'.
our $loaded;
BEGIN { $| = 1; plan tests => 18; }
END   { ok(0) unless $loaded; }
require LSP;
require LSP::Linear;
require LSP::Binary;
require LSP::Binary::Linear;
$loaded = 1;
ok(1);

######################### End of black magic.

# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):

require Math::Matrix;

##
## this is the example taken from NFs lecture notes
##


my $LSP = new LSP 2, 2, [0, 0], [1, 0], [0, 1];
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([1, 1], [0, 1]);
$LSP->add_vector([1, 0], [1, 0]);
$LSP->add_vector([1, 0], [0, 1]);
$LSP->add_vector([0, 1], [1, 0]);
$LSP->add_vector([0, 1], [0, 1]);
$LSP->add_vector([0, 1], [0, 1]);

my $cmp = Math::Matrix->new( [ 0.166667,  0.833333 ],
                             [ 0.333333, -0.333333 ],
                             [ 0.166667, -0.166667 ],
                           );
my $result = $LSP->solve;
ok($cmp->equal($result));
$result->print;

my $probs = Math::Matrix->new([2/3], [1/3], [1/2]);
my @probs;
foreach ([1, 1], [0, 1], [1, 0]) {
  print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

unlink 't/lsp.dat';
$LSP->save('t/lsp.dat');
$LSP = LSP->load('t/lsp.dat');
@probs = ();
foreach ([1, 1], [0, 1], [1, 0]) {
  print "@$_: ", $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));


##
## another example
##


## standard LSP: baseline for tests

$LSP = LSP->new(2, 2, [0, 0], [1, 0], [0, 1]);
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([0, 1], [1, 0]);
$LSP->add_vector([1, 2], [1, 0]);
$LSP->add_vector([0, 2], [1, 0]);
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([0, 1], [1, 0]);
$LSP->add_vector([0, 2], [1, 0]);
$LSP->add_vector([0, 2], [1, 0]);
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([1, 2], [1, 0]);
$LSP->add_vector([1, 2], [1, 0]);
$LSP->add_vector([0, 2], [1, 0]);
$LSP->add_vector([0, 1], [1, 0]);
$LSP->add_vector([1, 1], [1, 0]);
$LSP->add_vector([1, 2], [0, 1]);
$LSP->add_vector([0, 1], [0, 1]);
$LSP->add_vector([1, 1], [0, 1]);
$LSP->add_vector([1, 2], [0, 1]);
$LSP->add_vector([1, 1], [0, 1]);
$LSP->add_vector([1, 1], [0, 1]);
my $momental = $LSP->momental;
$momental->print("\n");
my $solution = $LSP->solve;
$solution->print("\n");
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
$probs = Math::Matrix->new(@probs);

# test load and save
unlink 't/lsp.dat';
$LSP->save('t/lsp.dat');
$LSP = LSP->load('t/lsp.dat');
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: ", $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));


## LSP::Linear should have same results

$LSP = LSP::Linear->new(2, 2, [0, 0], [1, 0], [0, 1]);
$LSP->add_vector([0, 1], [0, 1], 1);
$LSP->add_vector([0, 1], [1, 0], 3);
$LSP->add_vector([0, 2], [1, 0], 4);
$LSP->add_vector([1, 1], [0, 1], 3);
$LSP->add_vector([1, 1], [1, 0], 4);
$LSP->add_vector([1, 2], [0, 1], 2);
$LSP->add_vector([1, 2], [1, 0], 3);
#$LSP->momental->print("\n");
ok($momental->equal($LSP->momental));
#$LSP->solve->print("\n");
ok($solution->equal($LSP->solve));
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  #print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

# test load and save
unlink 't/lsp.dat';
$LSP->save('t/lsp.dat');
$LSP = LSP::Linear->load('t/lsp.dat');
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: ", $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));


## LSP::Binary should have same results

$LSP = LSP::Binary->new(2, [0, 0], [1, 0], [0, 1]);
$LSP->add_vector([0, 1], 3, 1);
$LSP->add_vector([0, 2], 4, 0);
$LSP->add_vector([1, 1], 4, 3);
$LSP->add_vector([1, 2], 3, 2);
$momental = $LSP->momental;
#$LSP->momental->print("\n");
$solution = $LSP->solve;
#$LSP->solve->print("\n");
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  #print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

# test load and save
unlink 't/lsp.dat';
$LSP->save('t/lsp.dat');
$LSP = LSP::Binary->load('t/lsp.dat');
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: ", $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));


## LSP::Binary::Linear should have same results

$LSP = LSP::Binary::Linear->new(2);
$LSP->add_vector([0, 1], 3, 1);
$LSP->add_vector([0, 2], 4, 0);
$LSP->add_vector([1, 1], 4, 3);
$LSP->add_vector([1, 2], 3, 2);
#$LSP->momental->print("\n");
ok($momental->equal($LSP->momental));
#$LSP->solve->print("\n");
ok($solution->equal($LSP->solve));
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  #print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

# LSP::Binary::Linear should have same results if called with coefficients
# of the solution only
@probs = ();
$LSP = LSP::Binary::Linear->function($solution->transpose->[0]);
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

# test load and save
unlink 't/lsp.dat';
$LSP->save('t/lsp.dat');
$LSP = LSP::Binary::Linear->load('t/lsp.dat');
@probs = ();
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: ", $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));


# LSP::Binary should have same results if called with coefficients
# of the solution only
@probs = ();
$LSP = LSP::Binary->function( [0, 0], [1, 0], [0, 1],
                              $solution->transpose->[0]
                            );
foreach ([1, 1], [0, 1], [1, 2], [0, 2]) {
  print "@$_: " , $LSP->probability($_), "\n";
  push @probs, [ $LSP->probability($_) ];
}
ok($probs->equal(new Math::Matrix @probs));

## delete data file
ok(unlink 't/lsp.dat');
