Skip to content

kron

Kronecker product of 2 sparse arrays.

Parameters:

Name Type Description Default
a SparseArray, scipy.sparse.spmatrix, or np.ndarray

The arrays over which to compute the Kronecker product.

required
b SparseArray, scipy.sparse.spmatrix, or np.ndarray

The arrays over which to compute the Kronecker product.

required

Returns:

Name Type Description
res COO

The kronecker product

Raises:

Type Description
ValueError

If all arguments are dense or arguments have nonzero fill-values.

Examples:

>>> from sparse import eye
>>> a = eye(3, dtype="i8")
>>> b = np.array([1, 2, 3], dtype="i8")
>>> res = kron(a, b)
>>> res.todense()
array([[1, 2, 3, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 2, 3, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 2, 3]], dtype=int64)
Source code in sparse/numba_backend/_coo/common.py
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def kron(a, b):
    """Kronecker product of 2 sparse arrays.

    Parameters
    ----------
    a, b : SparseArray, scipy.sparse.spmatrix, or np.ndarray
        The arrays over which to compute the Kronecker product.

    Returns
    -------
    res : COO
        The kronecker product

    Raises
    ------
    ValueError
        If all arguments are dense or arguments have nonzero fill-values.

    Examples
    --------
    >>> from sparse import eye
    >>> a = eye(3, dtype="i8")
    >>> b = np.array([1, 2, 3], dtype="i8")
    >>> res = kron(a, b)
    >>> res.todense()  # doctest: +SKIP
    array([[1, 2, 3, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 1, 2, 3, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 1, 2, 3]], dtype=int64)
    """
    from .._common import _is_sparse
    from .._umath import _cartesian_product
    from .core import COO

    check_zero_fill_value(a, b)

    a_sparse = _is_sparse(a)
    b_sparse = _is_sparse(b)
    a_ndim = np.ndim(a)
    b_ndim = np.ndim(b)

    if not (a_sparse or b_sparse):
        raise ValueError("Performing this operation would produce a dense result: kron")

    if a_ndim == 0 or b_ndim == 0:
        return a * b

    a = asCOO(a, check=False)
    b = asCOO(b, check=False)

    # Match dimensions
    max_dim = max(a.ndim, b.ndim)
    a = a.reshape((1,) * (max_dim - a.ndim) + a.shape)
    b = b.reshape((1,) * (max_dim - b.ndim) + b.shape)

    a_idx, b_idx = _cartesian_product(np.arange(a.nnz), np.arange(b.nnz))

    a_expanded_coords = a.coords[:, a_idx]
    b_expanded_coords = b.coords[:, b_idx]
    o_coords = a_expanded_coords * np.asarray(b.shape)[:, None] + b_expanded_coords
    o_data = a.data[a_idx] * b.data[b_idx]
    o_shape = tuple(i * j for i, j in zip(a.shape, b.shape, strict=True))

    return COO(o_coords, o_data, shape=o_shape, has_duplicates=False)