1 package Math::GSL::MatrixComplex::Test;
2 use Test::More tests => 38;
3 use base q{Test::Class};
6 use Math::GSL qw/:all/;
7 use Math::GSL::Test qw/:all/;
8 use Math::GSL::Errno qw/:all/;
9 use Math::GSL::MatrixComplex qw/:all/;
10 use Math::GSL::Complex qw/:all/;
15 BEGIN{ gsl_set_error_handler_off(); }
17 sub make_fixture : Test(setup) {
21 sub teardown : Test(teardown) {
22 unlink 'matrix' if -f 'matrix';
25 sub GSL_MATRIX_COMPLEX_NEW: Tests(3) {
26 my $u = Math::GSL::MatrixComplex->new(10,20);
27 isa_ok($u, 'Math::GSL::MatrixComplex');
28 ok( $u->rows == 10, 'rows');
29 ok( $u->cols == 20, 'cols');
32 sub GSL_MATRIX_COMPLEX_SET : Tests(2) {
33 my $u = Math::GSL::MatrixComplex->new(2,2);
34 gsl_matrix_complex_set($u->raw, 0, 0, Math::GSL::Complex::gsl_complex_rect(3,5) );
35 ok_similar( [ map { Re $_ } $u->row(0)->as_list ], [ 3, 0 ] );
36 ok_similar( [ map { Im $_ } $u->row(0)->as_list ], [ 5, 0 ] );
39 sub GSL_MATRIX_COMPLEX_COL : Tests(3) {
40 my $u = Math::GSL::MatrixComplex->new(2,2);
41 isa_ok( $u->col(0) , 'Math::GSL::MatrixComplex');
42 cmp_ok( $u->col(0)->cols, '==', 1 );
43 cmp_ok( $u->col(0)->rows, '==', 2 );
46 sub GSL_MATRIX_COMPLEX_ROW : Tests(3) {
47 my $u = Math::GSL::MatrixComplex->new(2,2);
48 isa_ok( $u->row(0) , 'Math::GSL::MatrixComplex');
49 cmp_ok( $u->row(0)->cols, '==', 2 );
50 cmp_ok( $u->row(0)->rows, '==', 1 );
52 sub GSL_MATRIX_COMPLEX_SET_OO : Tests(2) {
53 my $u = Math::GSL::MatrixComplex->new(2,2);
54 $u->set_row(0, [ 1+7*i, 2*i ] )
55 ->set_row(1, [ 3*i, -4 ] );
56 ok_similar( [ map { Re $_ } $u->as_list ], [ 1, 0, 0, -4 ] );
57 ok_similar( [ map { Im $_ } $u->as_list ], [ 7, 2, 3, 0 ] );
60 sub HERMITIAN : Tests(1) {
61 my $matrix = gsl_matrix_complex_alloc(2,2);
62 my $transpose = gsl_matrix_complex_alloc(2,2);
63 gsl_matrix_complex_set($matrix, 0, 0, gsl_complex_rect(3,0));
64 gsl_matrix_complex_set($matrix, 0, 1, gsl_complex_rect(2,1));
65 gsl_matrix_complex_set($matrix, 1, 0, gsl_complex_rect(2,-1));
66 gsl_matrix_complex_set($matrix, 1, 1, gsl_complex_rect(1,0));
67 gsl_matrix_complex_memcpy($transpose, $matrix);
68 gsl_matrix_complex_transpose($transpose);
71 map { gsl_matrix_complex_set($transpose, $row, $_, gsl_complex_conjugate(gsl_matrix_complex_get($transpose, $row, $_))) } (0..1);
74 my $upper_right = gsl_matrix_complex_get($matrix, 0, 1 );
75 my $lower_left = gsl_matrix_complex_get($matrix, 1, 0 );
77 ok( gsl_complex_eq( gsl_complex_conjugate($upper_right), $lower_left ), 'hermitian' );
79 sub MULTIPLICATION_OVERLOAD : Tests(2) {
80 my $u = Math::GSL::MatrixComplex->new(2,2);
81 $u->set_row(0, [ 1+2*i, 2*i ] )
82 ->set_row(1, [ 3*i, -4 ] );
83 my $t = Math::GSL::MatrixComplex->new(2,2);
84 $t->set_row(0, [ 1+4*i, 1 ] )
85 ->set_row(1, [ 3*i, -4 ] );
87 ok_similar( [ map { Re $_ } $result->as_list ], [ -13, 1, -12, 16 ] );
88 ok_similar( [ map { Im $_ } $result->as_list ], [ 6, -6, -9, 3 ] );
91 sub MATRIX_IS_SQUARE : Tests(2) {
92 my $A = Math::GSL::MatrixComplex->new(2,2);
93 ok( $A->is_square, 'is_square true for 2x2' );
94 my $B = Math::GSL::MatrixComplex->new(2,3);
95 ok( ! $B->is_square, 'is_square false for 2x3' );
98 sub MATRIX_DETERMINANT : Tests(3) {
99 my $A = Math::GSL::MatrixComplex->new(2,2)
101 ->set_row(1, [4, 2] );
102 isa_ok( $A->det, 'Math::Complex');
103 ok_similar( [ $A->det ], [ -10 ], '->det() 2x2');
104 ok_similar( [ $A->lndet ], [ log 10 ], '->lndet() 2x2');
108 sub MATRIX_ZERO : Tests(2) {
109 my $A = Math::GSL::MatrixComplex->new(2,2)
110 ->set_row(0, [1, 3] )
111 ->set_row(1, [4, 2] );
112 isa_ok($A->zero, 'Math::GSL::MatrixComplex');
113 ok_similar( [ $A->zero->as_list ], [ 0, 0, 0, 0 ] );
116 sub MATRIX_IDENTITY : Tests(7) {
117 my $A = Math::GSL::MatrixComplex->new(2,2)->identity;
118 isa_ok($A, 'Math::GSL::MatrixComplex');
119 ok_similar([ $A->as_list ], [ 1, 0, 0, 1 ] );
120 ok_similar([ $A->inverse->as_list ], [ 1, 0, 0, 1 ] );
121 ok_similar([ Re $A->det ] ,[ 1 ] );
122 ok_similar([ Im $A->det ] ,[ 0 ] );
123 #MatrixComplex doesn't yet have any function to find eigenvalues of complex matrices
124 ok_similar([ map { Re $_ } $A->eigenvalues ], [ 1, 1 ], 'identity eigs=1' );
125 ok_similar([ map { Im $_ } $A->eigenvalues ], [ 0, 0 ], 'identity eigs=1' );
127 sub MATRIX_IS_HERMITIAN : Tests {
128 my $A = Math::GSL::MatrixComplex->new(2,2)
129 ->set_row(0, [1, 3] )
130 ->set_row(1, [4, 2] );
131 ok( $A->is_hermitian == 0, 'non hermitian matrix ');
132 my $B = Math::GSL::MatrixComplex->new(2,3)
133 ->set_row(0, [1, 3, 4] )
134 ->set_row(1, [4, 2, 8] );
135 ok( $B->is_hermitian == 0, 'non square matrix ');
136 my $C = Math::GSL::MatrixComplex->new(2,2)
137 ->set_row(0, [3, 2+1*i] )
138 ->set_row(1, [2-1*i, 1] );
139 ok( $C->is_hermitian == 1, 'hermitian matrix ');
142 sub MATRIX_INVERSE : Tests(3) {
143 my $A = Math::GSL::MatrixComplex->new(2,2)
144 ->set_row(0, [1, 3] )
145 ->set_row(1, [4, 2] );
146 my $Ainv = $A->inverse;
147 isa_ok( $Ainv, 'Math::GSL::MatrixComplex' );
148 ok_similar([ $Ainv->as_list ] , [ map { -$_/10 } ( 2, -3, -4, 1 ) ] );
149 my $B = Math::GSL::MatrixComplex->new(2,3)
150 ->set_row(0, [1, 3, 5] )
151 ->set_row(1, [2, 4, 6] );
152 dies_ok( sub { $B->inverse } , 'inverse of non square matrix dies' );
155 sub OVERLOAD_EQUAL : Tests(2) {
156 my $A = Math::GSL::MatrixComplex->new(2,2)
157 ->set_row(0, [1+2*i, 3] )
158 ->set_row(1, [4, 2] );
160 ok ( $A == $B, 'should be equal');
161 $B->set_row(0, [1,2]);
162 ok ( $A != $B, 'should not be equal');
165 Test::Class->runtests;