If you solve k to a vector m ^ 2 and expand X, you get:
- a
m**2 vector k - a
((nm)**2, m**2) for unrolled_X
where unrolled_X can be obtained with the following Python code:
from numpy import zeros def unroll_matrix(X, m): flat_X = X.flatten() n = X.shape[0] unrolled_X = zeros(((n - m) ** 2, m**2)) skipped = 0 for i in range(n ** 2): if (i % n) < n - m and ((i / n) % n) < n - m: for j in range(m): for l in range(m): unrolled_X[i - skipped, j * m + l] = flat_X[i + j * n + l] else: skipped += 1 return unrolled_X
Deploying X and not k allows for a more compact representation (smaller matrices) than vice versa for each X, but you need to expand each X. You may prefer to expand k depending on what you want to do.
Here unrolled_X not sparse, while unrolled_k will be sparse, but in size ((n-m+1)^2,n^2) , as mentioned by @Salvador Dali.
Scan k can be performed as follows:
from scipy.sparse import lil_matrix from numpy import zeros import scipy def unroll_kernel(kernel, n, sparse=True): m = kernel.shape[0] if sparse: unrolled_K = lil_matrix(((n - m)**2, n**2)) else: unrolled_K = zeros(((n - m)**2, n**2)) skipped = 0 for i in range(n ** 2): if (i % n) < n - m and((i / n) % n) < n - m: for j in range(m): for l in range(m): unrolled_K[i - skipped, i + j * n + l] = kernel[j, l] else: skipped += 1 return unrolled_K
source share