@@ -3,17 +3,9 @@ use warnings;
3
3
use PDL::LiteF;
4
4
use Test::More;
5
5
use Test::Exception;
6
- use Config ;
6
+ use Test::PDL ;
7
7
use PDL::MatrixOps;
8
8
9
- sub tapprox {
10
- my ($pa ,$pb ,$tol ) = @_ ;
11
- $tol //= 1e-14;
12
- all approx $pa , $pb , $tol ;
13
- }
14
-
15
- my $tol = 1e-6;
16
-
17
9
sub check_inplace {
18
10
my ($in , $cb , $expected , $label ) = @_ ;
19
11
local $Test::Builder::Level = $Test::Builder::Level + 1;
@@ -24,12 +16,7 @@ sub check_inplace {
24
16
$inplace
25
17
? lives_ok { $cb -> ($in_copy -> inplace); $got = $in_copy -> copy } " $label inplace=$inplace runs"
26
18
: lives_ok { $got = $cb -> ($in_copy ) } " $label inplace=$inplace runs" ;
27
- fail(" got non-PDL " .explain($got )." back" ), next if !UNIVERSAL::isa($got , ' PDL' );
28
- my @got_dims = $got -> dims;
29
- is_deeply \@got_dims , \@expected_dims , " got and expected same shape inplace=$inplace "
30
- or diag ' got: ' , explain \@got_dims , ' expected: ' , explain \@expected_dims ;
31
- ok tapprox($got , $expected , $tol ), " $label inplace=$inplace "
32
- or diag " got:$got \n expected:$expected " ;
19
+ is_pdl $got , $expected , " $label inplace=$inplace " ;
33
20
}
34
21
}
35
22
@@ -39,41 +26,32 @@ my $pa = pdl([1,2,3],[4,5,6],[7,1,1]);
39
26
my ($lu , $perm , $par );
40
27
lives_ok { ($lu ,$perm ,$par ) = lu_decomp($pa ); } " lu_decomp 3x3 ran OK" ;
41
28
is($par , -1, " lu_decomp 3x3 correct parity" );
42
- ok(all( $perm == pdl(2,1,0)) , " lu_decomp 3x3 correct permutation" ) ;
29
+ is_pdl $perm , pdl(2,1,0), " lu_decomp 3x3 correct permutation" ;
43
30
my $l = $lu -> copy;
44
- my $ldiag ;
45
- ($ldiag = $l -> diagonal(0,1)) .= 1;
46
- my $tmp ;
47
- ($tmp = $l -> slice(" 2,1" )) .= 0;
48
- ($tmp = $l -> slice(" 1:2,0" )) .= 0;
31
+ $l -> diagonal(0,1) .= 1;
32
+ $l -> slice(" 2,1" ) .= 0;
33
+ $l -> slice(" 1:2,0" ) .= 0;
49
34
my $u = $lu -> copy;
50
- ( $tmp = $ u-> slice(" 1,2" ) ) .= 0;
51
- ( $tmp = $ u-> slice(" 0,1:2" ) ) .= 0;
52
- ok(tapprox( $pa , matmult($l ,$u )-> slice(" :,-1:0" ),$tol ) , " LU = A (after depermutation)" ) ;
35
+ $ u-> slice(" 1,2" ) .= 0;
36
+ $ u-> slice(" 0,1:2" ) .= 0;
37
+ is_pdl matmult($l ,$u )-> slice(" :,-1:0" ), $pa , " LU = A (after depermutation)" ;
53
38
}
54
39
55
40
{
56
41
# ## Check LU decomposition of an OK singular matrix
57
42
my $pb = pdl([1,2,3],[4,5,6],[7,8,9]);
58
43
my ($lu ,$perm ,$par ) = lu_decomp($pb );
59
- ok(defined $lu , " lu_decomp singular matrix defined" );
60
- ok($lu -> flat-> abs-> at(-1) < $tol , " lu_decomp singular matrix small value" );
44
+ is_pdl $lu , pdl(' 7 8 9; 0.142857 0.857142 1.714285; 0.571428 0.5 0' ), " lu_decomp singular matrix" ;
61
45
}
62
46
63
47
{
64
48
# ## Check inversion -- this also checks lu_backsub
65
49
my $pa = pdl([1,2,3],[4,5,6],[7,1,1]);
66
50
my $opt ={s = >1,lu= >\m y @a };
67
- my $inv_expected = pdl <<'EOF';
68
- [
69
- [ 0.055555556 -0.055555556 0.16666667]
70
- [ -2.1111111 1.1111111 -0.33333333]
71
- [ 1.7222222 -0.72222222 0.16666667]
72
- ]
73
- EOF
51
+ my $inv_expected = pdl '0.055555556 -0.055555556 0.16666667; -2.1111111 1.1111111 -0.33333333; 1.7222222 -0.72222222 0.16666667';
74
52
check_inplace($pa , sub { inv($_ [0], $opt ) }, $inv_expected , "inv 3x3");
75
- ok(ref ( $opt ->{lu}-> [0]) eq 'PDL',"inverse: lu_decomp first entry is an ndarray") ;
76
- ok(tapprox( matmult($inv_expected ,$pa ),identity(3),$tol ), "matrix mult by its inverse gives identity matrix") ;
53
+ isa_ok $opt ->{lu}[0], 'PDL', "inverse: lu_decomp first entry is an ndarray";
54
+ is_pdl matmult($inv_expected ,$pa ),identity(3),"matrix mult by its inverse gives identity matrix";
77
55
}
78
56
79
57
{
@@ -112,7 +90,7 @@ my $a334 = pdl <<'EOF';
112
90
EOF
113
91
my $a334inv ;
114
92
lives_ok { $a334inv = $a334 ->inv } "3x3x4 inv ran OK";
115
- ok(tapprox( matmult($a334 ,$a334inv ),identity(3)->dummy(2,4)) , "3x3x4 inv gave correct answer") ;
93
+ is_pdl matmult($a334 ,$a334inv ),identity(3)->dummy(2,4), "3x3x4 inv" ;
116
94
}
117
95
118
96
{
@@ -125,34 +103,29 @@ is $idc->type, 'cdouble';
125
103
my $p = pdl [[ 1+i(), 0], [0, 2+2*i() ] ];
126
104
my $p_inv ;
127
105
lives_ok { $p_inv = $p ->inv } "native-complex inv runs OK";
128
- ok(tapprox( matmult($p ,$p_inv ),identity(2)) , "native-complex inv gave correct answer") ;
106
+ is_pdl matmult($p ,$p_inv ),identity(2)->cdouble , "native-complex inv" ;
129
107
}
130
108
131
109
{
132
110
### Check LU backsubstitution (bug #2023711 on sf.net)
133
111
my $pa = pdl([[1,2],[1,1]]); # asymmetric to see if need transpose
134
112
my ($lu ,$perm ,$par );
135
113
lives_ok { ($lu ,$perm ,$par ) = lu_decomp($pa ) } "lu_decomp 2x2 ran OK";
136
- ok( $par == 1, "lu_decomp 2x2 correct parity") ;
137
- ok(all( $perm == pdl(0,1)) , "lu_decomp 2x2 correct permutation") ;
114
+ is $par , 1, "lu_decomp 2x2 correct parity";
115
+ is_pdl $perm , pdl(0,1), "lu_decomp 2x2 correct permutation";
138
116
my $bb = pdl([1,0], [3, 4]);
139
- my $xx_expected = pdl <<'EOF';
140
- [
141
- [-1 1]
142
- [ 5 -1]
143
- ]
144
- EOF
117
+ my $xx_expected = pdl '-1 1; 5 -1';
145
118
check_inplace($bb , sub { lu_backsub($lu ,$perm ,$_ [0]) }, $xx_expected , "lu_backsub");
146
119
my $got = $pa x $xx_expected ->transpose;
147
- ok(tapprox( $got ,$bb ->transpose,$tol ), "A x actually == B") or diag "got: $got ";
120
+ is_pdl $got , $bb ->transpose, "A x actually == B";
148
121
}
149
122
150
123
{
151
124
my $A = identity(4) + ones(4, 4); $A ->slice('2,0') .= 0;
152
125
my $B = sequence(1, 4);
153
126
my ($x ) = simq($A ->copy, $B ->transpose, 0);
154
127
$x = $x ->inplace->transpose;
155
- ok tapprox( $A x $x , $B ) , 'simq right result';
128
+ is_pdl $A x $x , $B , 'simq right result';
156
129
}
157
130
158
131
{
@@ -167,11 +140,11 @@ ok(!defined $b2, "inv of singular matrix undefined if s=>1");
167
140
### Check that det will save lu_decomp and reuse it
168
141
my $m1 = pdl [[1,2],[3,4]]; # det -2
169
142
my $opt1 = {lu=>undef};
170
- ok( $m1 ->det($opt1 ) == -2 , "det([[1,2],[3,4]]") ;
171
- ok( $opt1 ->{lu}[0]->index2d(0,0) == 3 , "set lu") ;
143
+ is_pdl $m1 ->det($opt1 ), pdl(-2) , "det([[1,2],[3,4]]";
144
+ is_pdl $opt1 ->{lu}[0]->index2d(0,0), pdl(3) , "set lu";
172
145
my $m2 = pdl [[2,1],[4,3]]; # det 2
173
- ok( $m2 ->det == 2 , "det([[2,1],[3,4]]") ;
174
- ok( $m2 ->det($opt1 ) == -2 , "correctly used wrong lu") ;
146
+ is_pdl $m2 ->det, pdl(2) , "det([[2,1],[3,4]]";
147
+ is_pdl $m2 ->det($opt1 ), pdl(-2) , "correctly used wrong lu";
175
148
}
176
149
177
150
{
@@ -182,7 +155,7 @@ my $c = pdl([0,1,0,0],[1,0,0,0],[0,0,1,0],[0,0,0,1]); # det=-1
182
155
my $d = pdl([1,2,3,4],[5,4,3,2],[0,0,3,0],[3,0,1,6]); # det=-216
183
156
my $e = ($pa ->cat($pb )) -> cat( $c ->cat($d ) );
184
157
my $det = $e ->determinant;
185
- ok(all( $det == pdl([48,1],[-1,-216])) , "broadcasted determinant") ;
158
+ is_pdl $det , pdl([48,1],[-1,-216]), "broadcasted determinant";
186
159
}
187
160
188
161
{
@@ -192,13 +165,12 @@ isa_ok $m2->det, 'PDL', 'det of singular always returns ndarray';
192
165
193
166
{
194
167
### Check identity and stretcher matrices...
195
- ok((identity(2)->flat == pdl(1,0,0,1))->all, "identity matrix");
196
- ok((identity(pdl 2)->flat == pdl(1,0,0,1))->all, "identity matrix with scalar ndarray");
197
- ok((identity(zeroes 2, 3)->flat == pdl(1,0,0,1))->all, "identity matrix with dimensioned ndarray");
198
- my @deep_identity_dims = identity(zeroes 2, 3, 4)->dims;
199
- is_deeply \@ deep_identity_dims, [2, 2, 4], "identity matrix with multi-dimensioned ndarray" or diag 'got: ', explain \@ deep_identity_dims;
200
- ok((stretcher(pdl(2,3))->flat == pdl(2,0,0,3))->all, "stretcher 2x2");
201
- ok((stretcher(pdl([2,3],[3,4]))->flat == pdl(2,0,0,3,3,0,0,4))->all, "stretcher 2x2x2");
168
+ is_pdl identity(2), pdl('1 0; 0 1'), "identity matrix";
169
+ is_pdl identity(pdl 2), pdl('1 0; 0 1'), "identity matrix with scalar ndarray";
170
+ is_pdl identity(zeroes 2, 3), pdl('1 0; 0 1'), "identity matrix with dimensioned ndarray";
171
+ is_pdl identity(zeroes 2, 3, 4)->shape, indx([2,2,4]), "identity matrix with multi-dimensioned ndarray";
172
+ is_pdl stretcher(pdl(2,3)), pdl('2 0;0 3'), "stretcher 2x2";
173
+ is_pdl stretcher(pdl('2 3;3 4')), pdl('[2 0;0 3][3 0;0 4]'), "stretcher 2x2x2";
202
174
}
203
175
204
176
{
@@ -207,8 +179,8 @@ my $pa = pdl([3,4],[4,-3]);
207
179
### Check that eigens runs OK
208
180
my ($vec ,$val );
209
181
lives_ok { ($vec ,$val ) = eigens $pa } "eigens runs OK";
210
- ok tapprox( $vec , pdl('[0.8944 -0.4472; 0.4472 0.8944]'), 1e-4), 'vec ok' ;
211
- ok tapprox( $val , pdl('[5 -5]'), 1e-4), 'val ok' ;
182
+ is_pdl $vec , pdl('[0.8944 -0.4472; 0.4472 0.8944]'), {atol=> 1e-4, test_name=> 'vec'} ;
183
+ is_pdl $val , pdl('[5 -5]'), {atol=> 1e-4, test_name=> 'val'} ;
212
184
}
213
185
214
186
{
@@ -223,53 +195,46 @@ my $m = pdl(
223
195
[ -0.71, -0.493, 0.248, 0.576, 8.622, 1.357, 20.8, -0.622],
224
196
[ 1.983, 2.434, 1.738, 2.471, -0.254, -2.915, -0.622, 3.214]);
225
197
{
226
- my $esum =0;
227
- my ($vec ,$val );
228
- eval {
229
- ($vec ,$val ) = eigens($m );
230
- $esum = sum($val ); #signature of eigenvalues
231
- };
232
- ok tapprox($esum , 61.308, 1e-3),"eigens sum for 8x8 correct answer";
198
+ my ($vec ,$val ) = eigens($m );
199
+ is_pdl sum($val ), pdl(61.308), {atol=>1e-3, test_name=>"eigens sum for 8x8 correct answer"};
233
200
}
234
201
235
202
{
236
203
my $esum =0;
237
204
lives_ok {
238
205
$esum = sum scalar eigens_sym($m );
239
206
} "eigens_sym for 8x8 ran OK";
240
- ok tapprox( $esum , 61.308, 1e-3), "eigens_sym sum for 8x8 correct answer";
207
+ is_pdl $esum , pdl( 61.308), {atol=> 1e-3, test_name=> "eigens_sym sum for 8x8 correct answer"} ;
241
208
}
242
209
}
243
210
244
211
{
245
212
#Check an asymmetric matrix:
246
213
my $pa = pdl ([4,-1], [2,1]);
247
214
my $esum ;
248
- my ($vec ,$val );
249
215
lives_ok {
250
- ($vec ,$val ) = eigens $pa ;
251
- $esum =sprintf "%.3f", sum($val );
216
+ my ($vec ,$val ) = eigens $pa ;
217
+ $esum =sum($val );
252
218
};
253
- ok( $esum == 5);
219
+ is_pdl $esum , cdouble( 5);
254
220
}
255
221
256
222
{
257
223
#The below matrix has complex eigenvalues
258
224
my ($rvec , $val ) = eigens(pdl([1,1],[-1,1]));
259
- ok all(approx $rvec , pdl('[0.707i -0.707i; 0.707 0.707]'), 1e-3) ;
260
- ok all(approx $val , pdl('[1-i 1+i]'), 1e-3) ;
225
+ is_pdl $rvec , pdl('[0.707i -0.707i; 0.707 0.707]'), {atol=> 1e-3} ;
226
+ is_pdl $val , pdl('[1-i 1+i]'), {atol=> 1e-3} ;
261
227
}
262
228
263
229
throws_ok { eigens(pdl '243 -54 0; 126 72 10; 144 -72 135') } qr/hqr2 function/;
264
230
265
231
{
266
232
#asymmetric case with complex eigenvectors
267
233
my ($rvec , $val ) = eigens(my $A = pdl '1 0 0 0; 0 1 0 0; 0 0 0 -1; 0 0 1 0');
268
- ok all(approx $val , pdl('-i i 1 1'), 1e-3) or diag $val ;
234
+ is_pdl $val , pdl('-i i 1 1');
269
235
for my $i (0..3) {
270
236
my ($vals , $vecs ) = ($val ->slice($i ), $rvec ->slice($i ));
271
- ok all(approx $vals * $vecs , $A x $vecs , 1e-3)
272
- or diag "index=$i vals=$vals vecs=$vecs ";
237
+ is_pdl $vals * $vecs , $A x $vecs ;
273
238
}
274
239
}
275
240
@@ -284,7 +249,7 @@ my $this_svd_in = $svd_in->slice("0:1","0:1");
284
249
my ($u ,$s ,$v ) = svd($this_svd_in );
285
250
my $ess = zeroes($this_svd_in ->dim(0),$this_svd_in ->dim(0));
286
251
$ess ->diagonal(0,1).=$s ;
287
- ok(all( $this_svd_in == ($u x $ess x $v ->transpose)) , "svd 2x2") ;
252
+ is_pdl $this_svd_in , ($u x $ess x $v ->transpose), "svd 2x2";
288
253
}
289
254
290
255
{
@@ -293,7 +258,7 @@ my $this_svd_in = $svd_in->slice("0:2","0:2");
293
258
my ($u ,$s ,$v ) = svd($this_svd_in );
294
259
my $ess = zeroes($this_svd_in ->dim(0),$this_svd_in ->dim(0));
295
260
$ess ->diagonal(0,1).=$s ;
296
- ok(all(approx( $this_svd_in ,$u x $ess x $v ->transpose, 1e-8)), "svd 3x3") ;
261
+ is_pdl $this_svd_in , $u x $ess x $v ->transpose, "svd 3x3";
297
262
}
298
263
299
264
{
@@ -302,7 +267,7 @@ my $this_svd_in = $svd_in;
302
267
my ($u ,$s ,$v ) = svd($this_svd_in );
303
268
my $ess =zeroes($this_svd_in ->dim(0),$this_svd_in ->dim(0));
304
269
$ess ->diagonal(0,1).=$s ;
305
- ok(all(approx( $this_svd_in ,($u x $ess x $v ->transpose),1e-8)), "svd 4x4") ;
270
+ is_pdl $this_svd_in ,($u x $ess x $v ->transpose),"svd 4x4";
306
271
}
307
272
308
273
{
@@ -311,7 +276,7 @@ my $this_svd_in = $svd_in->slice("0:1","0:2");
311
276
my ($u ,$s ,$v ) = svd($this_svd_in );
312
277
my $ess = zeroes($this_svd_in ->dim(0),$this_svd_in ->dim(0));
313
278
$ess ->slice("$_ ","$_ ").=$s ->slice("$_ ") foreach (0,1); #generic diagonal
314
- ok(all(approx( $this_svd_in , $u x $ess x $v ->transpose,1e-8)), "svd 3x2") ;
279
+ is_pdl $this_svd_in , $u x $ess x $v ->transpose, "svd 3x2";
315
280
}
316
281
317
282
{
@@ -320,7 +285,7 @@ my $this_svd_in = $svd_in->slice("0:2","0:1");
320
285
my ($u ,$s ,$v ) = svd($this_svd_in ->transpose);
321
286
my $ess = zeroes($this_svd_in ->dim(1),$this_svd_in ->dim(1));
322
287
$ess ->slice("$_ ","$_ ").=$s ->slice("$_ ") foreach (0..$this_svd_in ->dim(1)-1); #generic diagonal
323
- ok(all(approx( $this_svd_in , $v x $ess x $u ->transpose,1e-8)), "svd 2x3") ;
288
+ is_pdl $this_svd_in , $v x $ess x $u ->transpose, "svd 2x3";
324
289
}
325
290
326
291
}
@@ -334,7 +299,7 @@ my $x_expected = pdl([[-1, 1]]);
334
299
check_inplace($B , sub { lu_backsub($A ->lu_decomp, $_ [0]) }, $x_expected , "lu_backsub dims");
335
300
check_inplace($B , sub { lu_backsub($A1 ->lu_decomp, $_ [0]) }, $x_expected , "lu_backsub dims 2");
336
301
my $got = $A x $x_expected ->transpose;
337
- ok(tapprox( $got ,$B ->transpose,$tol ), "A x actually == B") or diag "got: $got ";
302
+ is_pdl $got ,$B ->transpose, "A x actually == B";
338
303
}
339
304
340
305
{
@@ -364,21 +329,20 @@ is $y.'', "
364
329
my $A = pdl '[1 2 3; 4 5 6; 7 8 9]';
365
330
my $up = pdl '[1 2 3; 0 5 6; 0 0 9]';
366
331
my $lo = pdl '[1 0 0; 4 5 0; 7 8 9]';
367
- my $got ;
368
- ok tapprox($got = $A ->tricpy(0), $up ), 'upper triangle #1' or diag "got: $got ";
369
- tricpy($A , 0, $got = null);
370
- ok tapprox($got , $up ), 'upper triangle #2' or diag "got: $got ";
371
- ok tapprox($got = $A ->tricpy, $up ), 'upper triangle #3' or diag "got: $got ";
372
- ok tapprox($got = $A ->tricpy(1), $lo ), 'lower triangle #1' or diag "got: $got ";
332
+ is_pdl $A ->tricpy(0), $up , 'upper triangle #1';
333
+ tricpy($A , 0, my $got = null);
334
+ is_pdl $got , $up , 'upper triangle #2';
335
+ is_pdl $A ->tricpy, $up , 'upper triangle #3';
336
+ is_pdl $A ->tricpy(1), $lo , 'lower triangle #1';
373
337
tricpy($A , 1, $got = null);
374
- ok tapprox( $got , $lo ) , 'lower triangle #2' or diag "got: $got " ;
375
- ok tapprox( $got = $ A ->mstack($up ), pdl('[1 2 3; 4 5 6; 7 8 9; 1 2 3; 0 5 6; 0 0 9]')) or diag "got: $got " ;
376
- ok tapprox( $got = sequence(2,3)->augment(sequence(3,3)+10), pdl('[0 1 10 11 12; 2 3 13 14 15; 4 5 16 17 18]')) or diag "got: $got " ;
338
+ is_pdl $got , $lo , 'lower triangle #2';
339
+ is_pdl $ A ->mstack($up ), pdl('[1 2 3; 4 5 6; 7 8 9; 1 2 3; 0 5 6; 0 0 9]');
340
+ is_pdl sequence(2,3)->augment(sequence(3,3)+10), pdl('[0 1 10 11 12; 2 3 13 14 15; 4 5 16 17 18]');
377
341
my $B = pdl('[i 2+4i 3+5i; 0 3i 7+9i]');
378
- ok tapprox( $got = $ B ->t, pdl('[i 0; 2+4i 3i; 3+5i 7+9i]')) or diag "got: $got " ;
379
- ok tapprox( $got = $ B ->t(1), pdl('[-i 0; 2-4i -3i; 3-5i 7-9i]')) or diag "got: $got " ;
380
- ok tapprox( $got = sequence(3)->t, pdl('[0; 1; 2]')) or diag "got: $got " ;
381
- is_deeply $got = [ pdl(3)->t->dims], [1,1] or diag "got: ", explain $got ;
342
+ is_pdl $ B ->t, pdl('[i 0; 2+4i 3i; 3+5i 7+9i]');
343
+ is_pdl $ B ->t(1), pdl('[-i 0; 2-4i -3i; 3-5i 7-9i]');
344
+ is_pdl sequence(3)->t, pdl('[0; 1; 2]');
345
+ is_pdl pdl(3)->t->shape, indx( [1,1]) ;
382
346
}
383
347
384
348
done_testing;
0 commit comments