Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Khatri-Rao (columnwise Kronecker) products #91

Open
PythonNut opened this issue Mar 18, 2021 · 2 comments
Open

Khatri-Rao (columnwise Kronecker) products #91

PythonNut opened this issue Mar 18, 2021 · 2 comments

Comments

@PythonNut
Copy link

PythonNut commented Mar 18, 2021

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:

@MichielStock
Copy link
Owner

MichielStock commented Mar 31, 2021

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

?

@dkarrasch
Copy link
Contributor

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(LinearMapkronecker, eachcol(A), eachcol(B))...)

I strongly recommend benchmarking for your use case, which Kronecker product implementation works best for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants