Skip to content

Commit 5b8f5ec

Browse files
authored
Add Khatri Rao product (#106)
* Add Khatri Rao product * change blocksize -> blockaxes remove _ * change version
1 parent 1bf7e9b commit 5b8f5ec

File tree

5 files changed

+137
-2
lines changed

5 files changed

+137
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "BlockArrays"
22
uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
3-
version = "0.12.0"
3+
version = "0.12.1"
44

55
[deps]
66
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"

src/BlockArrays.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export PseudoBlockArray, PseudoBlockMatrix, PseudoBlockVector, PseudoBlockVecOrM
1414

1515
export undef_blocks, undef, findblock, findblockindex
1616

17+
export khatri_rao
18+
1719
import Base: @propagate_inbounds, Array, to_indices, to_index,
1820
unsafe_indices, first, last, size, length, unsafe_length,
1921
unsafe_convert,
@@ -45,6 +47,6 @@ include("show.jl")
4547
include("blockarrayinterface.jl")
4648
include("blockbroadcast.jl")
4749
include("blocklinalg.jl")
48-
50+
include("blockproduct.jl")
4951

5052
end # module

src/blockproduct.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
khatri_rao(A, B)
3+
4+
References
5+
* Liu, Shuangzhe, and Gõtz Trenkler (2008) Hadamard, Khatri-Rao, Kronecker and Other Matrix Products. International J. Information and Systems Sciences 4, 160–177.
6+
* Khatri, C. G., and Rao, C. Radhakrishna (1968) Solutions to Some Functional Equations and Their Applications to Characterization of Probability Distributions. Sankhya: Indian J. Statistics, Series A 30, 167–180.
7+
"""
8+
function khatri_rao(A::AbstractBlockMatrix, B::AbstractBlockMatrix)
9+
#
10+
Ablksize = blocksize(A)
11+
Bblksize = blocksize(B)
12+
13+
@assert Ablksize == Bblksize "A and B must have the same blocksize"
14+
15+
kblk = []
16+
for iblk in blockaxes(A,1)
17+
kblk_j = []
18+
for _jblk in blockaxes(A,2)
19+
Ablk = A[iblk, _jblk]
20+
Bblk = B[iblk, _jblk]
21+
push!(kblk_j, kron(Ablk, Bblk))
22+
end
23+
push!(kblk, tuple(kblk_j...))
24+
end
25+
mortar(kblk...)
26+
end
27+
28+
function khatri_rao(A::AbstractMatrix, B::AbstractMatrix)
29+
kron(A, B)
30+
end

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ using BlockArrays, LinearAlgebra, Test
88
include("test_blockarrayinterface.jl")
99
include("test_blockbroadcast.jl")
1010
include("test_blocklinalg.jl")
11+
include("test_blockproduct.jl")
1112
end

test/test_blockproduct.jl

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using BlockArrays, Test
2+
3+
@testset "Khatri Rao Product (size)" begin
4+
#A size
5+
m = 5
6+
n = 6
7+
8+
#A block size
9+
mi = [3, 2]
10+
ni = [4, 1, 1]
11+
#B size
12+
p = 8
13+
q = 7
14+
15+
#B block size
16+
pi = [5, 3]
17+
qi = [3, 2, 2]
18+
19+
@assert sum(mi) == m
20+
@assert sum(ni) == n
21+
@assert sum(qi) == q
22+
@assert sum(pi) == p
23+
24+
A = BlockArray(ones(m, n), mi, ni)
25+
B = BlockArray(ones(p, q), pi, qi)
26+
27+
AB = khatri_rao(A, B)
28+
29+
@test blocksize(AB) == blocksize(A)
30+
@test blocksize(AB) == blocksize(B)
31+
32+
#Test: Size of resulting blocks
33+
for i in blockaxes(AB,1)
34+
for j in blockaxes(AB,2)
35+
@test size(AB[i, j]) == (mi[Int(i)]*pi[Int(i)], ni[Int(j)]*qi[Int(j)])
36+
end
37+
end
38+
end
39+
40+
@testset "Khatri Rao Product (constant blocks)" begin
41+
#A size
42+
m = 5
43+
n = 6
44+
45+
#A block size
46+
mi = [3, 2]
47+
ni = [4, 1, 1]
48+
#B size
49+
p = 8
50+
q = 7
51+
52+
#B block size
53+
pi = [5, 3]
54+
qi = [3, 2, 2]
55+
56+
@assert sum(mi) == m
57+
@assert sum(ni) == n
58+
@assert sum(qi) == q
59+
@assert sum(pi) == p
60+
61+
A = BlockArray(ones(m, n), mi, ni)
62+
B = BlockArray(ones(p, q), pi, qi)
63+
64+
#Test: Resulting values for a matrix of constant sub-blocks
65+
for i in blockaxes(A,1)
66+
for j in blockaxes(A,2)
67+
A[i, j] .*= Int(i)+Int(j)
68+
end
69+
end
70+
71+
for i in blockaxes(B,1)
72+
for j in blockaxes(B,2)
73+
B[i, j] .*= Int(i)+Int(j)+10
74+
end
75+
end
76+
77+
AB = khatri_rao(A, B)
78+
79+
for i in blockaxes(AB,1)
80+
for j in blockaxes(AB,2)
81+
@test AB[i, j] (Int(i)+Int(j))*(Int(i)+Int(j)+10)*ones(mi[Int(i)]*pi[Int(i)], ni[Int(j)]*qi[Int(j)])
82+
end
83+
end
84+
85+
end
86+
87+
@testset "Khatri Rao Product (wrong blocksize)" begin
88+
89+
A = BlockArray(ones(1, 2), [1], [1,1])
90+
B = BlockArray(ones(2, 2), [1,1], [1,1])
91+
92+
@test_throws AssertionError khatri_rao(A, B)
93+
end
94+
95+
@testset "Khatri Rao Product (Matrix)" begin
96+
97+
A = ones(1, 2)
98+
B = ones(2, 2)
99+
100+
@test khatri_rao(A, B) kron(A, B)
101+
end
102+

0 commit comments

Comments
 (0)