Refactor Vector tests and get rid of redundant GSL_VECTOR_MAX test.
[Math-GSL.git] / lib / Math / GSL / Vector / Test.pm
blob69428556fa5121c6b6e195f5881841c199a02afb
1 package Math::GSL::Vector::Test;
2 use base q{Test::Class};
3 use Test::More;
4 use Math::GSL::Vector qw/:all/;
5 use Math::GSL qw/:all/;
6 use Data::Dumper;
7 use Math::GSL::Errno qw/:all/;
8 use Test::Exception;
9 use strict;
11 # This allows us to eval code
12 BEGIN{ gsl_set_error_handler_off(); }
14 sub make_fixture : Test(setup) {
15 my $self = shift;
16 $self->{vector} = gsl_vector_alloc(5);
17 $self->{object} = Math::GSL::Vector->new(5);
20 sub teardown : Test(teardown) {
21 unlink 'vector' if -f 'vector';
24 sub GSL_VECTOR_ALLOC : Tests {
25 my $vector = gsl_vector_alloc(5);
26 isa_ok($vector, 'Math::GSL::Vector');
28 sub GSL_VECTOR_LENGTH: Tests {
29 my $self = shift;
30 my $vector = $self->{object};
31 ok( $vector->length == 5, '$vector->length' );
33 sub GSL_VECTOR_SET_GET: Tests {
34 my $self = shift;
35 gsl_vector_set($self->{vector}, 0, 42 );
36 my $elem = gsl_vector_get($self->{vector}, 0);
37 ok( $elem == 42, 'gsl_vector_set/gsl_vector_get' );
40 sub GSL_VECTOR_ISNONNEG: Tests {
41 my $self = shift;
42 map { gsl_vector_set($self->{vector}, $_, -1 ) } (0..4);
43 ok( !gsl_vector_isnonneg($self->{vector}),'gsl_vector_isnonneg' );
44 map { gsl_vector_set($self->{vector}, $_, 1 ) } (0..4);
45 ok( gsl_vector_isnonneg($self->{vector}),'gsl_vector_isnonneg' );
48 sub GSL_VECTOR_ISNULL: Tests {
49 my $self = shift;
50 ok( !gsl_vector_isnull($self->{vector}), 'gsl_vector_isnull' );
51 map { gsl_vector_set($self->{vector}, $_, 0 ) } (0..4);
52 ok( gsl_vector_isnull($self->{vector}),'gsl_vector_isnull' );
53 gsl_vector_set($self->{vector}, 0, 5 );
54 ok( !gsl_vector_isnull($self->{vector}), 'gsl_vector_isnull' );
57 sub GSL_VECTOR_ISPOS: Tests {
58 my $self = shift;
59 map { gsl_vector_set($self->{vector}, $_, -1 ) } (0..4);
60 ok( !gsl_vector_ispos($self->{vector}),'gsl_vector_pos' );
61 map { gsl_vector_set($self->{vector}, $_, 1 ) } (0..4);
62 ok( gsl_vector_ispos($self->{vector}),'gsl_vector_pos' );
65 sub GSL_VECTOR_ISNEG: Tests {
66 my $self = shift;
68 map { gsl_vector_set($self->{vector}, $_, -$_ ) } (0..4);
69 ok( !gsl_vector_isneg($self->{vector}),'gsl_vector_neg' );
71 gsl_vector_set($self->{vector}, 0, -1 );
73 ok( gsl_vector_isneg($self->{vector}),'gsl_vector_neg' );
76 sub GSL_VECTOR_NEW: Tests {
77 my $vec = Math::GSL::Vector->new( [ map { $_ ** 2 } (1..10) ] );
78 isa_ok( $vec, 'Math::GSL::Vector', 'Math::GSL::Vector->new($values)' );
80 dies_ok( sub { Math::GSL::Vector->new(-1) }, 'new takes only positive indices');
82 dies_ok( sub { Math::GSL::Vector->new(3.14) }, 'new takes only integer indices');
84 dies_ok( sub { Math::GSL::Vector->new([]) },'new takes only nonempty array refs');
86 $vec = Math::GSL::Vector->new(42);
87 ok( $vec->length == 42 , 'new creates empty vectors of a given length');
89 sub GSL_VECTOR_AS_LIST: Tests {
90 my $vec = Math::GSL::Vector->new( [ map { $_ ** 2 } (reverse 1..10) ] );
91 my @x = $vec->as_list;
92 is_deeply( \@x, [map { $_ ** 2 } (reverse 1..10)] );
95 sub GSL_VECTOR_SET: Tests {
96 my $vec = Math::GSL::Vector->new( [ map { $_ ** 2 } (1..10) ] );
97 $vec->set( [ 0..4] , [ reverse 1..5 ] );
98 my ($x) = $vec->get([0]);
99 ok( $x == 5, "gsl_vector_set: $x ?= 5" );
101 sub GSL_VECTOR_MIN: Tests {
102 my $self = shift;
103 my $vec = Math::GSL::Vector->new( [ map { $_ ** 2 } (0..4) ] );
104 ok_similar( $vec->min ,0, '$vec->min' );
105 ok_similar( gsl_vector_min($self->{vector}) ,0, 'gsl_vector_min' );
108 sub GSL_VECTOR_MAX: Tests {
109 my $vec = Math::GSL::Vector->new( [ 3, 567, 4200 ]);
110 ok_similar( $vec->max ,4200, '$vec->min' );
111 ok_similar( gsl_vector_max($vec->raw) ,4200, 'gsl_vector_max' );
113 sub GSL_VECTOR_FREAD_FWRITE: Tests {
114 my $self = shift;
115 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
117 my $fh = fopen("vector", "w");
118 my $status = gsl_vector_fwrite($fh, $self->{vector} );
119 ok( ! $status, 'gsl_vector_fwrite' );
120 ok( -f "vector", 'gsl_vector_fwrite' );
121 fclose($fh);
123 map { gsl_vector_set($self->{vector}, $_, $_ ** 3 ) } (0..4);
125 $fh = fopen("vector", "r");
127 gsl_vector_fread($fh, $self->{vector} );
128 is_deeply( [ map { gsl_vector_get($self->{vector}, $_) } (0..4) ],
129 [ map { $_ ** 2 } (0..4) ],
131 fclose($fh);
134 sub GSL_VECTOR_SUBVECTOR : Tests {
135 my $self = shift;
136 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
137 my $vec_sub = gsl_vector_subvector($self->{vector}, 2, 3);
139 ok_similar( [ map { gsl_vector_get($vec_sub->{vector}, $_) } (0..2) ],
140 [ 4, 9, 16 ],
144 sub GSL_VECTOR_CALLOC : Tests {
145 my $vector = gsl_vector_calloc(5);
146 isa_ok($vector, 'Math::GSL::Vector');
149 sub GSL_VECTOR_SET_ALL : Tests {
150 my $vec = Math::GSL::Vector->new(5);
151 gsl_vector_set_all($vec->raw, 4);
152 ok_similar( [ $vec->as_list ], [ (4) x 5 ] );
155 sub GSL_VECTOR_SET_ZERO : Tests {
156 my $self = shift;
157 gsl_vector_set_zero($self->{vector});
158 map { is(gsl_vector_get($self->{vector} , $_ ), 0) } (0..4);
161 sub GSL_VECTOR_SET_BASIS : Tests {
162 my $self = shift;
163 my $x = gsl_vector_set_basis($self->{vector}, 0);
164 is (gsl_vector_get($self->{vector} , 0 ), 1);
165 is ($x, 0, "output");
166 map { is(gsl_vector_get($self->{vector} , $_ ), 0) } (1..4);
169 sub GSL_VECTOR_SUBVECTOR_WITH_STRIDE : Tests {
170 my $self = shift;
171 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
172 my $sub_stride = gsl_vector_subvector_with_stride($self->{vector}, 0, 2, 3);
173 is(gsl_vector_get($sub_stride->{vector} , 0 ), 0, "first element");
174 is(gsl_vector_get($sub_stride->{vector} , 1 ), 4, "second element");
175 is(gsl_vector_get($sub_stride->{vector} , 2 ), 16, "third element");
178 sub GSL_VECTOR_MAX_INDEX : Tests {
179 my $self = shift;
180 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
181 my $index = gsl_vector_max_index($self->{vector});
182 is($index, 4, "Position of the maximum");
185 sub GSL_VECTOR_MIN_INDEX : Tests {
186 my $self = shift;
187 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
188 my $index = gsl_vector_min_index($self->{vector});
189 is($index, 0, "Position of the minimum");
192 sub GSL_VECTOR_MINMAX_INDEX : Tests {
193 my $self = shift;
194 my ($min, $max);
195 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4);
196 ($min, $max) = gsl_vector_minmax_index($self->{vector});
197 ok_similar( [ 0, 4 ], [ $min, $max], 'gsl_vector_minmax_index' );
200 sub GSL_VECTOR_MINMAX : Tests {
201 my ($min, $max);
202 my $vector->{vector} = gsl_vector_alloc(5);
203 map { gsl_vector_set($vector->{vector}, $_, $_ ** 2 ) } (0..4);
205 ($min, $max) = Math::GSL::Vector::gsl_vector_minmax($vector->{vector});
207 ok_similar( [ 0, 16 ], [ $min, $max], 'gsl_vector_minmax' );
210 sub GSL_VECTOR_MEMCPY : Tests {
211 my $self = shift;
212 my $copy->{vector} = gsl_vector_alloc(5);
213 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
214 is( gsl_vector_memcpy($copy->{vector}, $self->{vector}), 0);
215 map { is(gsl_vector_get($copy->{vector}, $_), $_ ** 2 ) } (0..4); ;
218 sub GSL_VECTOR_VIEW_ARRAY : Tests {
219 my @array = [1,2,3,4,5,6];
220 my $vec_view = gsl_vector_view_array(@array, 2);
221 map { is(gsl_vector_get($vec_view->{vector}, $_), $_+1 ) } (0..1); ;
224 sub GSL_VECTOR_REVERSE : Tests {
225 my $self = shift;
226 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
227 is( gsl_vector_reverse($self->{vector}), 0);
228 ok_similar( [ 16, 9, 4, 1, 0], [ map { gsl_vector_get($self->{vector}, $_) } 0..4 ] );
231 sub GSL_VECTOR_SWAP_ELEMENTS : Tests {
232 my $self = shift;
233 map { gsl_vector_set($self->{vector}, $_, $_ ** 2 ) } (0..4); ;
234 is( gsl_vector_swap_elements($self->{vector}, 0, 4), 0);
235 is(gsl_vector_get($self->{vector}, 0), 16);
236 is(gsl_vector_get($self->{vector}, 4), 0);
237 map { is(gsl_vector_get($self->{vector}, $_), $_ ** 2 ) } (1..3); ;
240 sub GSL_VECTOR_ADD : Tests {
241 my $self = shift;
242 my $second_vec->{vector} = gsl_vector_alloc(5);
243 map { gsl_vector_set($self->{vector}, $_, $_ ) } (0..4); ;
244 map { gsl_vector_set($second_vec->{vector}, $_, $_ ) } (0..4); ;
245 is(gsl_vector_reverse($second_vec->{vector}),0);
246 is( gsl_vector_add($self->{vector}, $second_vec->{vector}), 0);
247 map { is(gsl_vector_get($self->{vector}, $_), 4 ) } (0..4); ;
250 sub GSL_VECTOR_SUB : Tests {
251 my $self = shift;
252 my $second_vec->{vector} = gsl_vector_alloc(5);
253 map { gsl_vector_set($self->{vector}, $_, $_ ) } (0..4); ;
254 map { gsl_vector_set($second_vec->{vector}, $_, 1) } (0..4); ;
255 is( gsl_vector_sub($self->{vector}, $second_vec->{vector}), 0);
256 map { is(gsl_vector_get($self->{vector}, $_), $_ - 1 ) } (0..4); ;
259 sub GSL_VECTOR_MUL : Tests {
260 my $self = shift;
261 my $second_vec->{vector} = gsl_vector_alloc(5);
262 map { gsl_vector_set($self->{vector}, $_, $_ ) } (0..4); ;
263 map { gsl_vector_set($second_vec->{vector}, $_, 2) } (0..4); ;
264 is( gsl_vector_mul($self->{vector}, $second_vec->{vector}), 0);
265 map { is(gsl_vector_get($self->{vector}, $_), $_ * 2 ) } (0..4); ;
268 sub GSL_VECTOR_DIV : Tests {
269 my $self = shift;
270 my $second_vec->{vector} = gsl_vector_alloc(5);
271 map { gsl_vector_set($self->{vector}, $_, $_*2 ) } (0..4); ;
272 map { gsl_vector_set($second_vec->{vector}, $_, 2) } (0..4); ;
273 is( gsl_vector_div($self->{vector}, $second_vec->{vector}), 0);
274 map { is(gsl_vector_get($self->{vector}, $_), $_ ) } (0..4); ;
277 sub GSL_VECTOR_SCALE : Tests {
278 my $v = Math::GSL::Vector->new([0..4]);
279 is( gsl_vector_scale($v->raw, 2), 0);
280 ok_similar( [ $v->as_list ], [ 0,2,4,6,8 ] );
283 sub GSL_VECTOR_SCALE_OVERLOAD : Tests {
284 my $v = Math::GSL::Vector->new([0..4]);
285 my $expected = [ map { $_*5} (0..4) ];
286 $v = 5 * $v;
287 ok_similar( [ $v->as_list ], $expected );
289 my $w = Math::GSL::Vector->new([0..4]);
290 $w = $w * 5;
291 ok_similar( [ $w->as_list ], $expected );
294 sub GSL_VECTOR_DOT_PRODUCT : Tests {
295 my $v = Math::GSL::Vector->new([0..4]);
296 my $w = Math::GSL::Vector->new([0..4]);
298 ok_similar( $v * $w , 4*4 + 3*3 + 2*2 + 1*1 );
300 my $z = Math::GSL::Vector->new([0..10]);
301 dies_ok( sub { $z * $v; }, 'dot_product checks vector length' );
303 my $q = Math::GSL::Vector->new(5);
304 ok_similar ( $q * $q, 0, 'newly created vectors are zero-filled');
307 sub GSL_VECTOR_SWAP : Tests {
309 my @idx = (0..(5+int rand(5)));
310 my $vec1 = gsl_vector_alloc($#idx+1);
311 my $vec2 = gsl_vector_alloc($#idx+1);
313 map { gsl_vector_set($vec1, $_, $_**2 ) } @idx;
314 map { gsl_vector_set($vec2, $_, $_) } @idx;
316 is( gsl_vector_swap($vec1, $vec2), 0);
318 ok_similar( [ map { gsl_vector_get($vec1, $_) } @idx ],
319 [ @idx ],
321 ok_similar( [ map { gsl_vector_get($vec2, $_) } @idx ],
322 [ map { $_**2 } @idx ],
326 sub GSL_VECTOR_FPRINTF_FSCANF : Tests {
327 my $vec1 = Math::GSL::Vector->new([ map { $_ ** 2 } (0..4) ]);
329 my $fh = fopen("vector", "w");
330 ok( defined $fh, 'fopen - write');
331 is( gsl_vector_fprintf($fh, $vec1->raw, "%f"), 0);
332 is( fclose($fh), 0 );
334 my $vec2 = Math::GSL::Vector->new([ map { $_ ** 3 } (0..4) ]);
336 $fh = fopen("vector", "r");
337 ok( defined $fh, 'fopen - readonly');
339 is(gsl_vector_fscanf($fh, $vec2->raw), 0);
341 ok_similar( [ $vec2->as_list ], [ map { $_ ** 2 } (0..4) ]);
342 is( fclose($fh), 0 );