aboutsummaryrefslogtreecommitdiff
path: root/challenge-068/jo-37/perl/ch-1.pl
blob: 741ee1cc660febe415d1c47548c845e2946b0d73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/perl

use strict;
use warnings;
use Math::Matrix;

# let:
# A . B the matrix product of A and B
# M  be a R x C matrix
# r1 an all-1 column vector of size C
# l1 an all-1 row vector of size R
# RS a diagonal matrix of size R x R. Elements in the diagonal are zero
#    or one and act as a row selector for a matrix M1 having R rows
#    by multiplying RS . M
# CS a diagonal matrix of size C x C. Elements in the diagonal are zero
#    or one and act as a column selector for a matrix M2 having C
#    columns by multiplying M . CS
#
# The matrix product M . r1 gives the row sums of M.  For a matrix of
# only zeros and ones a row sum equals C if and only if all elements of
# the row are ones.
# Analogous, the matrix product l1 . M gives the column sums of M and
# here a column sum of R indicates all-one in the corresponding column.
#
# The selector matrices can be constructed from the row sums and
# column sums of M by mapping the sums to zero or one as described.
# Let Rsel(c) and Csel(r) be the corresponding selector matrices for
# given row and columns sum vectors.
#
# The requested matrix from the challenge then can be written as:
# RSel(M . r1) . M . CSel(l1 . M)

sub zero_matrix {
	my $m = shift;
	my ($rows, $cols) = $m->size;

	Math::Matrix->diagonal(map $_->[0] == $cols,
		@{$m->multiply(Math::Matrix->new([(1) x $cols])->transpose)})->
	multiply($m)->
	multiply(Math::Matrix->diagonal(map $_ == $rows,
			@{Math::Matrix->new([(1) x $rows])->multiply($m)->[0]}));
}

my $m1 = Math::Matrix->new([1, 0, 1], [1, 1, 1], [1, 1, 1]);
$m1->print("M1:\n");
my $z1 = zero_matrix $m1;
$z1->print("Z1:\n");

my $m2 = Math::Matrix->new([1, 0, 1], [1, 1, 1], [1, 0, 1]);
$m2->print("M2:\n");
my $z2 = zero_matrix $m2;
$z2->print("Z2:\n");

my $m3 = Math::Matrix->new([1, 0, 1], [1, 1, 1], [1, 1, 1], [1, 1, 0]);
$m3->print("M3:\n");
my $z3 = zero_matrix $m3;
$z3->print("Z3:\n");