Khatri-Rao (columnwise Kronecker) products
The Khatri-Rao product is a matrix product that is closely related to the Kronecker product. Although the definition of Khatri-Rao product applies to partitioned matrices, it is common to use the trivial partition (where every element is in its own partition). In this case, the Khatri-Rao product becomes the column-wise Kronecker product. One (probably pretty inefficient) way to implement the Khatri-Rao product in this case would be:
khatri_rao(A, B) = mapreduce(kron, hcat, eachcol(A), eachcol(B))
This means that a lazy Khatri-Rao product could be created using existing tools, but this would require a lot of reshaping and a lot of lazy hcats which are slow, and of course the real benefits come when we encode algebraic optimizations using multiple dispatch. There is also an analogous row-wise product called the transposed Khatri-Rao product (or the "face-splitting" product).
References:
- person asking for this functionality on JuliaLang Discourse
- paper with some detailed discussion of the Kronecker and Khatri-Rao products and efficient (eager) implementations in Julia of Khatri-Rao matrix and vector products.
- It sounds a bit like this might be relevant to https://github.com/MichielStock/Kronecker.jl/issues/88?
Hmmm, I don't really know this product but would it not possible to directly reproduce it using block matrices and the dot syntax, for example:
A = [rand(2,2) for i in 1:2, j in 1:2]
B = [randn(2,2) for i in 1:2, j in 1:2]
kronecker.(A, B)
Which would mean that we can implement this as:
⋆(A::AbstractMatrix{<:AbstractMatrix}, B::AbstractMatrix{<:AbstractMatrix}) = A ⊗. B
?
You can implement it with LinearMaps.jl as follows:
using LinearMaps
khatri_rao(A::AbstractMatrix, B::AbstractMatrix) = hcat(map(⊗, eachcol(A), eachcol(B))...)
# alternatively
using Kronecker
khatri_rao(A::AbstractMatrix, B::AbstractMatrix) = hcat(map(LinearMap∘kronecker, eachcol(A), eachcol(B))...)
I strongly recommend benchmarking for your use case, which Kronecker product implementation works best for you.