Skip to content

Commit cfdd275

Browse files
committed
MatrixOps tests replace tapprox with is_pdl - #34 #393
1 parent 19cca0f commit cfdd275

File tree

1 file changed

+61
-97
lines changed

1 file changed

+61
-97
lines changed

Basic/t/matrixops.t

+61-97
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,9 @@ use warnings;
33
use PDL::LiteF;
44
use Test::More;
55
use Test::Exception;
6-
use Config;
6+
use Test::PDL;
77
use PDL::MatrixOps;
88

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-
179
sub check_inplace {
1810
my ($in, $cb, $expected, $label) = @_;
1911
local $Test::Builder::Level = $Test::Builder::Level + 1;
@@ -24,12 +16,7 @@ sub check_inplace {
2416
$inplace
2517
? lives_ok { $cb->($in_copy->inplace); $got = $in_copy->copy } "$label inplace=$inplace runs"
2618
: 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\nexpected:$expected";
19+
is_pdl $got, $expected, "$label inplace=$inplace";
3320
}
3421
}
3522

@@ -39,41 +26,32 @@ my $pa = pdl([1,2,3],[4,5,6],[7,1,1]);
3926
my ($lu, $perm, $par);
4027
lives_ok { ($lu,$perm,$par) = lu_decomp($pa); } "lu_decomp 3x3 ran OK";
4128
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";
4330
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;
4934
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)";
5338
}
5439

5540
{
5641
### Check LU decomposition of an OK singular matrix
5742
my $pb = pdl([1,2,3],[4,5,6],[7,8,9]);
5843
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";
6145
}
6246

6347
{
6448
### Check inversion -- this also checks lu_backsub
6549
my $pa = pdl([1,2,3],[4,5,6],[7,1,1]);
6650
my $opt ={s=>1,lu=>\my @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';
7452
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";
7755
}
7856
7957
{
@@ -112,7 +90,7 @@ my $a334 = pdl <<'EOF';
11290
EOF
11391
my $a334inv;
11492
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";
11694
}
11795
11896
{
@@ -125,34 +103,29 @@ is $idc->type, 'cdouble';
125103
my $p = pdl [[ 1+i(), 0], [0, 2+2*i() ] ];
126104
my $p_inv;
127105
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";
129107
}
130108
131109
{
132110
### Check LU backsubstitution (bug #2023711 on sf.net)
133111
my $pa = pdl([[1,2],[1,1]]); # asymmetric to see if need transpose
134112
my ($lu,$perm,$par);
135113
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";
138116
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';
145118
check_inplace($bb, sub { lu_backsub($lu,$perm,$_[0]) }, $xx_expected, "lu_backsub");
146119
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";
148121
}
149122
150123
{
151124
my $A = identity(4) + ones(4, 4); $A->slice('2,0') .= 0;
152125
my $B = sequence(1, 4);
153126
my ($x) = simq($A->copy, $B->transpose, 0);
154127
$x = $x->inplace->transpose;
155-
ok tapprox($A x $x, $B), 'simq right result';
128+
is_pdl $A x $x, $B, 'simq right result';
156129
}
157130
158131
{
@@ -167,11 +140,11 @@ ok(!defined $b2, "inv of singular matrix undefined if s=>1");
167140
### Check that det will save lu_decomp and reuse it
168141
my $m1 = pdl [[1,2],[3,4]]; # det -2
169142
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";
172145
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";
175148
}
176149
177150
{
@@ -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
182155
my $d = pdl([1,2,3,4],[5,4,3,2],[0,0,3,0],[3,0,1,6]); # det=-216
183156
my $e = ($pa->cat($pb)) -> cat( $c->cat($d) );
184157
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";
186159
}
187160
188161
{
@@ -192,13 +165,12 @@ isa_ok $m2->det, 'PDL', 'det of singular always returns ndarray';
192165
193166
{
194167
### 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";
202174
}
203175
204176
{
@@ -207,8 +179,8 @@ my $pa = pdl([3,4],[4,-3]);
207179
### Check that eigens runs OK
208180
my ($vec,$val);
209181
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'};
212184
}
213185
214186
{
@@ -223,53 +195,46 @@ my $m = pdl(
223195
[ -0.71, -0.493, 0.248, 0.576, 8.622, 1.357, 20.8, -0.622],
224196
[ 1.983, 2.434, 1.738, 2.471, -0.254, -2.915, -0.622, 3.214]);
225197
{
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"};
233200
}
234201
235202
{
236203
my $esum=0;
237204
lives_ok {
238205
$esum = sum scalar eigens_sym($m);
239206
} "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"};
241208
}
242209
}
243210
244211
{
245212
#Check an asymmetric matrix:
246213
my $pa = pdl ([4,-1], [2,1]);
247214
my $esum;
248-
my ($vec,$val);
249215
lives_ok {
250-
($vec,$val) = eigens $pa;
251-
$esum=sprintf "%.3f", sum($val);
216+
my ($vec,$val) = eigens $pa;
217+
$esum=sum($val);
252218
};
253-
ok($esum == 5);
219+
is_pdl $esum, cdouble(5);
254220
}
255221
256222
{
257223
#The below matrix has complex eigenvalues
258224
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};
261227
}
262228
263229
throws_ok { eigens(pdl '243 -54 0; 126 72 10; 144 -72 135') } qr/hqr2 function/;
264230
265231
{
266232
#asymmetric case with complex eigenvectors
267233
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');
269235
for my $i (0..3) {
270236
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;
273238
}
274239
}
275240
@@ -284,7 +249,7 @@ my $this_svd_in = $svd_in->slice("0:1","0:1");
284249
my ($u,$s,$v) = svd($this_svd_in);
285250
my $ess = zeroes($this_svd_in->dim(0),$this_svd_in->dim(0));
286251
$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";
288253
}
289254
290255
{
@@ -293,7 +258,7 @@ my $this_svd_in = $svd_in->slice("0:2","0:2");
293258
my ($u,$s,$v) = svd($this_svd_in);
294259
my $ess = zeroes($this_svd_in->dim(0),$this_svd_in->dim(0));
295260
$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";
297262
}
298263
299264
{
@@ -302,7 +267,7 @@ my $this_svd_in = $svd_in;
302267
my ($u,$s,$v) = svd($this_svd_in);
303268
my $ess =zeroes($this_svd_in->dim(0),$this_svd_in->dim(0));
304269
$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";
306271
}
307272
308273
{
@@ -311,7 +276,7 @@ my $this_svd_in = $svd_in->slice("0:1","0:2");
311276
my ($u,$s,$v) = svd($this_svd_in);
312277
my $ess = zeroes($this_svd_in->dim(0),$this_svd_in->dim(0));
313278
$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";
315280
}
316281
317282
{
@@ -320,7 +285,7 @@ my $this_svd_in = $svd_in->slice("0:2","0:1");
320285
my ($u,$s,$v) = svd($this_svd_in->transpose);
321286
my $ess = zeroes($this_svd_in->dim(1),$this_svd_in->dim(1));
322287
$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";
324289
}
325290
326291
}
@@ -334,7 +299,7 @@ my $x_expected = pdl([[-1, 1]]);
334299
check_inplace($B, sub { lu_backsub($A->lu_decomp, $_[0]) }, $x_expected, "lu_backsub dims");
335300
check_inplace($B, sub { lu_backsub($A1->lu_decomp, $_[0]) }, $x_expected, "lu_backsub dims 2");
336301
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";
338303
}
339304
340305
{
@@ -364,21 +329,20 @@ is $y.'', "
364329
my $A = pdl '[1 2 3; 4 5 6; 7 8 9]';
365330
my $up = pdl '[1 2 3; 0 5 6; 0 0 9]';
366331
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';
373337
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]');
377341
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]);
382346
}
383347
384348
done_testing;

0 commit comments

Comments
 (0)