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

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

# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)

BEGIN { $| = 1; print "1..18\n"; }
END {print "not ok 1\n" unless $loaded;}

use PDL::Astro::Cosmology;

$loaded = 1;
print "ok 1\n";

use strict;
use PDL;

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

# arbitrary value
my $abstol = 1.05e-5;

my $testnum = 2;

sub check0 {
    my $result = shift ;
    my $answer;
    if ( ref($result) ) { # ie assuma a piddle
	$answer = abs(sum($result));
    } else {
	$answer = abs($result);
    }
    print "not " unless $answer <= $abstol;
    print "ok $testnum\n" ;
    $testnum++;
#    print "  [ $answer ]\n";
}

my $z = pdl( [ 0.5, 1.0, 2.0 ] );

my $eds = new PDL::Astro::Cosmology;
my $sn  = new PDL::Astro::Cosmology ( matter => 0.3, lambda => 0.7, h => 70 );
my $opn = new PDL::Astro::Cosmology ( matter => 0.3, lambda => 0, h => 70 );

# test the values stored in the objects
check0( $eds->h0() - 50.0 );
check0( $sn->omega_lambda - 0.7 );

# repeat, using different names
check0( $eds->hO() - 50.0 );
check0( $sn->lambda - 0.7 );

my $dl_eds = $eds->lum_dist( $z );
my $dl_sn  = $sn->lum_dist( $z );
my $dl_opn = $opn->lum_dist( $z );

check0( $dl_eds - $eds->luminosity_distance($z) );
check0( $dl_sn  - $sn->luminosity_distance($z)  );
check0( $dl_opn - $opn->luminosity_distance($z)  );

# not really a fair check, as calculated these using this module
my $dl_eds_ans = pdl( [3300.7765, 7024.5742, 15204.864] );
my $dl_sn_ans  = pdl( [2832.9381, 6607.6576, 15539.587] );
my $dl_opn_ans = pdl( [2565.1861, 5872.2944, 14242.634] );

# going for a percentage check here
check0( 100.0 * ($dl_eds - $dl_eds_ans) / $dl_eds_ans );
check0( 100.0 * ($dl_sn  - $dl_sn_ans) / $dl_sn_ans  );
check0( 100.0 * ($dl_opn - $dl_opn_ans) / $dl_opn_ans  );

my $zp1_sq = (1.0 + $z) * (1.0 + $z);
check0( 100.0 * ($dl_eds/$zp1_sq - $eds->angular_diameter_distance($z)) / $eds->adiam_dist($z) );
check0( 100.0 * ($dl_sn/$zp1_sq  - $sn->angular_diameter_distance($z))  / $sn->adiam_dist($z)  );
check0( 100.0 * ($dl_opn/$zp1_sq - $opn->angular_diameter_distance($z))  / $opn->adiam_dist($z)  );

my $dt_eds = $eds->lookback_time( $z );
my $dt_sn  = $sn->lookback_time( $z );
my $dt_opn = $opn->lookback_time( $z );

my $dt_eds_ans = pdl( [5.9407884e+09, 8.4280545e+09, 1.052844e+10] );
my $dt_sn_ans  = pdl( [5.0407463e+09, 7.7155029e+09, 1.0240577e+10] );
my $dt_opn_ans = pdl( [4.514814e+09, 6.6254651e+09, 8.5750495e+09] );

check0( 100.0 * ($dt_eds - $dt_eds_ans) / $dt_eds_ans );
check0( 100.0 * ($dt_sn  - $dt_sn_ans) / $dt_sn_ans );
check0( 100.0 * ($dt_opn - $dt_opn_ans) / $dt_opn_ans );

# can we change the sn model to equal the open model ?
$sn->lambda( 0 );
check0( $sn->lum_dist( $z ) - $opn->lum_dist( $z ) );

## End of the test
exit;

