The Khatri-Rao Product Visualized
The Khatri-Rao product takes two matrices with the same number of columns and pairs their columns up, replacing each pair by its Kronecker product. The result is a tall matrix with the same number of columns as the inputs. As a result it keeps the width fixed while the heights are multiplied.
1. Definition: the column-wise Kronecker product
Write A = [ a 1 a 2 ⋯ a K ] \textcolor{#0d9488}{A} = \begin{bmatrix} \textcolor{#0d9488}{a_1} & \textcolor{#0d9488}{a_2} & \cdots & \textcolor{#0d9488}{a_K} \end{bmatrix} A = [ a 1 a 2 ⋯ a K ] and B = [ b 1 b 2 ⋯ b K ] \textcolor{#b45309}{B} = \begin{bmatrix} \textcolor{#b45309}{b_1} & \textcolor{#b45309}{b_2} & \cdots & \textcolor{#b45309}{b_K} \end{bmatrix} B = [ b 1 b 2 ⋯ b K ] as lists of columns, with a k ∈ R I \textcolor{#0d9488}{a_k} \in \mathbb{R}^{I} a k ∈ R I and b k ∈ R J \textcolor{#b45309}{b_k} \in \mathbb{R}^{J} b k ∈ R J . On a matrix, a subscript picks a column and a superscript picks a row : a k \textcolor{#0d9488}{a_k} a k is the k k k -th column of A \textcolor{#0d9488}{A} A , and a i \textcolor{#0d9488}{a^i} a i (section 3) is its i i i -th row. The Khatri-Rao product is defined column by column:
A ⊙ B ⏟ I J × K = [ a 1 ⊗ b 1 ⏟ I J × 1 a 2 ⊗ b 2 ⋯ a K ⊗ b K ] \underbrace{\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B}}_{IJ \times K} = \begin{bmatrix} \underbrace{\textcolor{#0d9488}{a_1} \otimes \textcolor{#b45309}{b_1}}_{IJ \times 1} & \textcolor{#0d9488}{a_2} \otimes \textcolor{#b45309}{b_2} & \cdots & \textcolor{#0d9488}{a_K} \otimes \textcolor{#b45309}{b_K} \end{bmatrix} I J × K A ⊙ B = [ I J × 1 a 1 ⊗ b 1 a 2 ⊗ b 2 ⋯ a K ⊗ b K ]
Column k k k of the output depends only on column k k k of each input. Nothing mixes across columns.
The two inputs have K = 2 K = 2 K = 2 columns each. In the figure below, matching columns share a color: the entries of A A A are circles, the columns of B B B are blocks.
An example with 2 × 2 2 \times 2 2 × 2 inputs
[ a 11 a 12 a 21 a 22 ] ⊙ [ b 11 b 12 b 21 b 22 ] = [ a 1 ⊗ b 1 ⏟ first columns a 2 ⊗ b 2 ⏟ second columns ] = [ a 11 [ b 11 b 21 ] a 12 [ b 12 b 22 ] a 21 [ b 11 b 21 ] a 22 [ b 12 b 22 ] ] = [ a 11 b 11 a 12 b 12 a 11 b 21 a 12 b 22 a 21 b 11 a 22 b 12 a 21 b 21 a 22 b 22 ] \begin{aligned}
\begin{bmatrix} \textcolor{#0d9488}{a_{11}} & \textcolor{#0d9488}{a_{12}} \\ \textcolor{#0d9488}{a_{21}} & \textcolor{#0d9488}{a_{22}} \end{bmatrix} \odot \begin{bmatrix} \textcolor{#b45309}{b_{11}} & \textcolor{#b45309}{b_{12}} \\ \textcolor{#b45309}{b_{21}} & \textcolor{#b45309}{b_{22}} \end{bmatrix}
&= \begin{bmatrix} \underbrace{\textcolor{#0d9488}{a_1} \otimes \textcolor{#b45309}{b_1}}_{\text{first columns}} & \underbrace{\textcolor{#0d9488}{a_2} \otimes \textcolor{#b45309}{b_2}}_{\text{second columns}} \end{bmatrix} \\ \\
&= \begin{bmatrix}
\textcolor{#0d9488}{a_{11}} \textcolor{#b45309}{\begin{bmatrix} b_{11} \\ b_{21} \end{bmatrix}} & \textcolor{#0d9488}{a_{12}} \textcolor{#b45309}{\begin{bmatrix} b_{12} \\ b_{22} \end{bmatrix}} \\[6pt]
\textcolor{#0d9488}{a_{21}} \textcolor{#b45309}{\begin{bmatrix} b_{11} \\ b_{21} \end{bmatrix}} & \textcolor{#0d9488}{a_{22}} \textcolor{#b45309}{\begin{bmatrix} b_{12} \\ b_{22} \end{bmatrix}}
\end{bmatrix} \\ \\
&= \begin{bmatrix}
\textcolor{#0d9488}{a_{11}}\textcolor{#b45309}{b_{11}} & \textcolor{#0d9488}{a_{12}}\textcolor{#b45309}{b_{12}} \\
\textcolor{#0d9488}{a_{11}}\textcolor{#b45309}{b_{21}} & \textcolor{#0d9488}{a_{12}}\textcolor{#b45309}{b_{22}} \\
\textcolor{#0d9488}{a_{21}}\textcolor{#b45309}{b_{11}} & \textcolor{#0d9488}{a_{22}}\textcolor{#b45309}{b_{12}} \\
\textcolor{#0d9488}{a_{21}}\textcolor{#b45309}{b_{21}} & \textcolor{#0d9488}{a_{22}}\textcolor{#b45309}{b_{22}}
\end{bmatrix}
\end{aligned} [ a 11 a 21 a 12 a 22 ] ⊙ [ b 11 b 21 b 12 b 22 ] = [ first columns a 1 ⊗ b 1 second columns a 2 ⊗ b 2 ] = a 11 [ b 11 b 21 ] a 21 [ b 11 b 21 ] a 12 [ b 12 b 22 ] a 22 [ b 12 b 22 ] = a 11 b 11 a 11 b 21 a 21 b 11 a 21 b 21 a 12 b 12 a 12 b 22 a 22 b 12 a 22 b 22
The second step is a 2 × 2 2 \times 2 2 × 2 grid of blocks , not of numbers: each block is one whole column of B \textcolor{#b45309}{B} B , written out as a stacked pair and scaled by a single entry of A \textcolor{#0d9488}{A} A . Column 1 1 1 of the answer therefore only ever sees b 1 \textcolor{#b45309}{b_1} b 1 , and column 2 2 2 only ever sees b 2 \textcolor{#b45309}{b_2} b 2 , never the whole of B \textcolor{#b45309}{B} B . That single difference is what separates ⊙ \odot ⊙ from ⊗ \otimes ⊗ .
2. One column at a time: the Kronecker product of two columns
Zoom in on a single column pair a \textcolor{#0d9488}{a} a , b \textcolor{#b45309}{b} b . Inside this section a subscript indexes an entry of that one column, not a column of a matrix. The Kronecker product a ⊗ b \textcolor{#0d9488}{a} \otimes \textcolor{#b45309}{b} a ⊗ b stacks one scaled copy of b \textcolor{#b45309}{b} b per entry of a \textcolor{#0d9488}{a} a :
a ⊗ b = [ a 1 a 2 a 3 ] ⊗ b = [ a 1 b a 2 b a 3 b ] \begin{aligned}
\textcolor{#0d9488}{a} \otimes \textcolor{#b45309}{b}
&= \begin{bmatrix} \textcolor{#0d9488}{a_1} \\ \textcolor{#0d9488}{a_2} \\ \textcolor{#0d9488}{a_3} \end{bmatrix} \otimes \textcolor{#b45309}{b} \\ \\
&= \begin{bmatrix} \textcolor{#0d9488}{a_1} \textcolor{#b45309}{b} \\ \textcolor{#0d9488}{a_2} \textcolor{#b45309}{b} \\ \textcolor{#0d9488}{a_3} \textcolor{#b45309}{b} \end{bmatrix}
\end{aligned} a ⊗ b = a 1 a 2 a 3 ⊗ b = a 1 b a 2 b a 3 b
Laying those same three blocks side by side instead of stacking them gives the outer product b a T \textcolor{#b45309}{b}\textcolor{#0d9488}{a^T} b a T :
b a T = [ b 1 b 2 ] [ a 1 a 2 a 3 ] = [ a 1 b 1 a 2 b 1 a 3 b 1 a 1 b 2 a 2 b 2 a 3 b 2 ] \begin{aligned}
\textcolor{#b45309}{b}\textcolor{#0d9488}{a^T}
&= \begin{bmatrix} \textcolor{#b45309}{b_1} \\ \textcolor{#b45309}{b_2} \end{bmatrix} \begin{bmatrix} \textcolor{#0d9488}{a_1} & \textcolor{#0d9488}{a_2} & \textcolor{#0d9488}{a_3} \end{bmatrix} \\ \\
&= \begin{bmatrix} \textcolor{#0d9488}{a_1}\textcolor{#b45309}{b_1} & \textcolor{#0d9488}{a_2}\textcolor{#b45309}{b_1} & \textcolor{#0d9488}{a_3}\textcolor{#b45309}{b_1} \\ \textcolor{#0d9488}{a_1}\textcolor{#b45309}{b_2} & \textcolor{#0d9488}{a_2}\textcolor{#b45309}{b_2} & \textcolor{#0d9488}{a_3}\textcolor{#b45309}{b_2} \end{bmatrix}
\end{aligned} b a T = [ b 1 b 2 ] [ a 1 a 2 a 3 ] = [ a 1 b 1 a 1 b 2 a 2 b 1 a 2 b 2 a 3 b 1 a 3 b 2 ]
Its columns are a 1 b \textcolor{#0d9488}{a_1}\textcolor{#b45309}{b} a 1 b , a 2 b \textcolor{#0d9488}{a_2}\textcolor{#b45309}{b} a 2 b and a 3 b \textcolor{#0d9488}{a_3}\textcolor{#b45309}{b} a 3 b , the very blocks that the Kronecker product stacks.
Three copies of b \textcolor{#b45309}{b} b , each tinted by the entry of a \textcolor{#0d9488}{a} a that scales it. The output length is the product of the two input lengths.
Both layouts hold the same numbers in the same order, because vec \operatorname{vec} vec reads a matrix one column at a time and stacks those columns into a single long vector. That is why the Khatri-Rao product has a natural interpretation as an outer product in disguise :
a ⊗ b ⏟ blocks stacked = vec ( b a T ⏟ blocks side by side ) \underbrace{\textcolor{#0d9488}{a} \otimes \textcolor{#b45309}{b}}_{\text{blocks stacked}} = \operatorname{vec}\big(\underbrace{\textcolor{#b45309}{b}\textcolor{#0d9488}{a^T}}_{\text{blocks side by side}}\big) blocks stacked a ⊗ b = vec ( blocks side by side b a T )
Each column of A ⊙ B \textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B} A ⊙ B is a flattened outer product matrix.
3. The row-wise variant
Swapping rows for columns gives the face-splitting product. For A ∈ R I × J \textcolor{#0d9488}{A} \in \mathbb{R}^{I \times J} A ∈ R I × J and B ∈ R I × K \textcolor{#b45309}{B} \in \mathbb{R}^{I \times K} B ∈ R I × K , the matrix A ∙ B ∈ R I × J K \textcolor{#0d9488}{A} \bullet \textcolor{#b45309}{B} \in \mathbb{R}^{I \times JK} A ∙ B ∈ R I × J K has rows a i ⊗ b i \textcolor{#0d9488}{a^i} \otimes \textcolor{#b45309}{b^i} a i ⊗ b i , where a i \textcolor{#0d9488}{a^i} a i is the i i i -th row of A \textcolor{#0d9488}{A} A . The two are transposes of each other:
A ∙ B = ( A T ⊙ B T ) T \textcolor{#0d9488}{A} \bullet \textcolor{#b45309}{B} = (\textcolor{#0d9488}{A^T} \odot \textcolor{#b45309}{B^T})^T A ∙ B = ( A T ⊙ B T ) T
Its defining property is that it turns a Kronecker product of inputs into an elementwise product of outputs:
( A ∙ B ) ( x ⊗ y ) ⏟ Kronecker in = ( A x ) ∗ ( B y ) ⏟ Hadamard out (\textcolor{#0d9488}{A} \bullet \textcolor{#b45309}{B})\underbrace{(\textcolor{#0d9488}{x} \otimes \textcolor{#b45309}{y})}_{\text{Kronecker in}} = \underbrace{(\textcolor{#0d9488}{Ax}) * (\textcolor{#b45309}{By})}_{\text{Hadamard out}} ( A ∙ B ) Kronecker in ( x ⊗ y ) = Hadamard out ( A x ) ∗ ( B y )
where ∗ * ∗ is the elementwise (Hadamard) product.
Proof
The identity holds row by row, so watch a single row i i i , with a \textcolor{#0d9488}{a} a short for a i \textcolor{#0d9488}{a^i} a i and b \textcolor{#b45309}{b} b short for b i \textcolor{#b45309}{b^i} b i .
Both Kronecker products are indexed by the pair ( j , k ) (j,k) ( j , k ) : entry ( j , k ) (j,k) ( j , k ) is a j b k \textcolor{#0d9488}{a_j}\textcolor{#b45309}{b_k} a j b k on one side and x j y k \textcolor{#0d9488}{x_j}\textcolor{#b45309}{y_k} x j y k on the other:
[ ( A ∙ B ) ( x ⊗ y ) ] i = ( a ⊗ b ) ⋅ ( x ⊗ y ) = ∑ j , k a j b k x j y k = ∑ j , k ( a j x j ) ⏟ depends on j ( b k y k ) ⏟ depends on k = ( ∑ j a j x j ) ( ∑ k b k y k ) = ( a ⋅ x ) ( b ⋅ y ) = [ ( A x ) ∗ ( B y ) ] i \begin{aligned}
\big[(\textcolor{#0d9488}{A} \bullet \textcolor{#b45309}{B})(\textcolor{#0d9488}{x} \otimes \textcolor{#b45309}{y})\big]_i
&= (\textcolor{#0d9488}{a} \otimes \textcolor{#b45309}{b}) \cdot (\textcolor{#0d9488}{x} \otimes \textcolor{#b45309}{y}) \\ \\
&= \sum_{j,k} \textcolor{#0d9488}{a_j} \textcolor{#b45309}{b_k} \textcolor{#0d9488}{x_j} \textcolor{#b45309}{y_k} \\
&= \sum_{j,k} \underbrace{(\textcolor{#0d9488}{a_j x_j})}_{\textcolor{#0d9488}{\text{depends on } j}} \underbrace{(\textcolor{#b45309}{b_k y_k})}_{\textcolor{#b45309}{\text{depends on } k}} \\ \\
&= \Big(\sum_j \textcolor{#0d9488}{a_j x_j}\Big) \Big(\sum_k \textcolor{#b45309}{b_k y_k}\Big) \\ \\
&= (\textcolor{#0d9488}{a} \cdot \textcolor{#0d9488}{x})(\textcolor{#b45309}{b} \cdot \textcolor{#b45309}{y}) \\
&= \big[(\textcolor{#0d9488}{Ax}) * (\textcolor{#b45309}{By})\big]_i
\end{aligned} [ ( A ∙ B ) ( x ⊗ y ) ] i = ( a ⊗ b ) ⋅ ( x ⊗ y ) = j , k ∑ a j b k x j y k = j , k ∑ depends on j ( a j x j ) depends on k ( b k y k ) = ( j ∑ a j x j ) ( k ∑ b k y k ) = ( a ⋅ x ) ( b ⋅ y ) = [ ( A x ) ∗ ( B y ) ] i
4. Three properties worth remembering
4.1 The Gram matrix collapses to a Hadamard product
( A ⊙ B ) T ( A ⊙ B ) = ( A T A ) ∗ ( B T B ) (\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B})^T (\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B}) = (\textcolor{#0d9488}{A^TA}) * (\textcolor{#b45309}{B^TB}) ( A ⊙ B ) T ( A ⊙ B ) = ( A T A ) ∗ ( B T B )
Proof
Entry ( k , l ) (k,l) ( k , l ) of the left side is the dot product of column k k k with column l l l , and the two families separate:
[ ( A ⊙ B ) T ( A ⊙ B ) ] k l = ( a k ⊗ b k ) T ( a l ⊗ b l ) = ( a k T a l ) ⏟ [ A T A ] k l ( b k T b l ) ⏟ [ B T B ] k l = [ ( A T A ) ∗ ( B T B ) ] k l \begin{aligned}
\big[(\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B})^T (\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B})\big]_{kl}
&= (\textcolor{#0d9488}{a_k} \otimes \textcolor{#b45309}{b_k})^T (\textcolor{#0d9488}{a_l} \otimes \textcolor{#b45309}{b_l}) \\ \\
&= \underbrace{(\textcolor{#0d9488}{a_k^T a_l})}_{\textcolor{#0d9488}{[A^TA]_{kl}}} \underbrace{(\textcolor{#b45309}{b_k^T b_l})}_{\textcolor{#b45309}{[B^TB]_{kl}}} \\ \\
&= \big[(\textcolor{#0d9488}{A^TA}) * (\textcolor{#b45309}{B^TB})\big]_{kl}
\end{aligned} [ ( A ⊙ B ) T ( A ⊙ B ) ] k l = ( a k ⊗ b k ) T ( a l ⊗ b l ) = [ A T A ] k l ( a k T a l ) [ B T B ] k l ( b k T b l ) = [ ( A T A ) ∗ ( B T B ) ] k l
A K × K K \times K K × K answer that never touches the I J × K IJ \times K I J × K matrix A ⊙ B \textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B} A ⊙ B . This is the single most useful fact about ⊙ \odot ⊙ .
4.2 It expresses a weighted sum of outer products as a matrix-vector product
( A ⊙ B ) x = vec ( B diag ( x ) A T ) (\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B})x = \operatorname{vec}\big(\textcolor{#b45309}{B} \operatorname{diag}(x) \textcolor{#0d9488}{A^T}\big) ( A ⊙ B ) x = vec ( B diag ( x ) A T )
Proof
Read the left side one column at a time, then replace each Kronecker column by the outer product it flattens:
( A ⊙ B ) x = ∑ k x k ( a k ⊗ b k ) ⏟ weighted sum of the columns = ∑ k x k vec ( b k a k T ) = vec ( ∑ k x k b k a k T ) = vec ( B diag ( x ) A T ) \begin{aligned}
(\textcolor{#0d9488}{A} \odot \textcolor{#b45309}{B})x
&= \underbrace{\sum_k x_k \, (\textcolor{#0d9488}{a_k} \otimes \textcolor{#b45309}{b_k})}_{\text{weighted sum of the columns}} \\ \\
&= \sum_k x_k \operatorname{vec}(\textcolor{#b45309}{b_k}\textcolor{#0d9488}{a_k^T}) \\ \\
&= \operatorname{vec}\Big(\sum_k x_k \, \textcolor{#b45309}{b_k}\textcolor{#0d9488}{a_k^T}\Big) \\ \\
&= \operatorname{vec}\big(\textcolor{#b45309}{B} \operatorname{diag}(x) \textcolor{#0d9488}{A^T}\big)
\end{aligned} ( A ⊙ B ) x = weighted sum of the columns k ∑ x k ( a k ⊗ b k ) = k ∑ x k vec ( b k a k T ) = vec ( k ∑ x k b k a k T ) = vec ( B diag ( x ) A T )
The last step is the outer-product reading of a matrix product: diag ( x ) \operatorname{diag}(x) diag ( x ) hands weight x k x_k x k to the k k k -th pairing of a column of B \textcolor{#b45309}{B} B with a row of A T \textcolor{#0d9488}{A^T} A T .
4.3 The mixed product rule carries over
( A ⊗ B ) ( C ⊙ D ) = ( A C ) ⊙ ( B D ) (\textcolor{#0d9488}{A} \otimes \textcolor{#b45309}{B})(\textcolor{#0d9488}{C} \odot \textcolor{#b45309}{D}) = (\textcolor{#0d9488}{AC}) \odot (\textcolor{#b45309}{BD}) ( A ⊗ B ) ( C ⊙ D ) = ( A C ) ⊙ ( B D )
Proof
Column k k k of C ⊙ D \textcolor{#0d9488}{C} \odot \textcolor{#b45309}{D} C ⊙ D is itself a Kronecker product, so the mixed product rule for ⊗ \otimes ⊗ applies to it directly:
[ ( A ⊗ B ) ( C ⊙ D ) ] k = ( A ⊗ B ) ( c k ⊗ d k ) = A c k ⊗ B d k = [ ( A C ) ⊙ ( B D ) ] k \begin{aligned}
\big[(\textcolor{#0d9488}{A} \otimes \textcolor{#b45309}{B})(\textcolor{#0d9488}{C} \odot \textcolor{#b45309}{D})\big]_k
&= (\textcolor{#0d9488}{A} \otimes \textcolor{#b45309}{B})(\textcolor{#0d9488}{c_k} \otimes \textcolor{#b45309}{d_k}) \\ \\
&= \textcolor{#0d9488}{Ac_k} \otimes \textcolor{#b45309}{Bd_k} \\ \\
&= \big[(\textcolor{#0d9488}{AC}) \odot (\textcolor{#b45309}{BD})\big]_k
\end{aligned} [ ( A ⊗ B ) ( C ⊙ D ) ] k = ( A ⊗ B ) ( c k ⊗ d k ) = A c k ⊗ B d k = [ ( A C ) ⊙ ( B D ) ] k
The Khatri-Rao product is also associative: ( A ⊙ B ) ⊙ C = A ⊙ ( B ⊙ C ) (A \odot B) \odot C = A \odot (B \odot C) ( A ⊙ B ) ⊙ C = A ⊙ ( B ⊙ C ) .