def structured_product(self, x, OMEGA, OMEGA_CONJ): y = np.copy(x) #print(self._d_pr, self._d) if self._d_pr <= self._d: for block in self._BBB[::-1]: # matrix-vector product if block._hash_func == 'random': y = np.dot(block._A, y) if block._hash_func == 'circulant': y = StructuredMatrices.circulant_product(block._col, y) if block._hash_func == 'skew_circulant': y = StructuredMatrices.skew_circulant_product( block._col, y, OMEGA, OMEGA_CONJ) if block._hash_func == 'toeplitz': y = StructuredMatrices.toeplitz_product( block._col, block._row, y) if block._hash_func == 'hadamard': y = StructuredMatrices.hadamard_cross_polytope_product( y, block._D, block._nblocks) if block._hash_func == 'hankel': y = StructuredMatrices.hankel_product( block._col, block._row, y) if block._hash_func == 'low_displacement_rank': y = StructuredMatrices.low_displacement_product( block._G, block._H, block._r, y, OMEGA, OMEGA_CONJ) if block._hash_func == 'kronecker': y = StructuredMatrices.kronecker_product_rec( block._A_list, y) if block._hash_func == 'pure_hadamard': #y = fht.fht1(y) a = ffht.create_aligned(y.shape[0], np.float32) np.copyto(a, y) ffht.fht(a, min(y.shape[0], 1024, 2048)) y = a if block._hash_func == 'diagonal' or block._hash_func == 'diagonal_kronecker' or block._hash_func == 'diagonal_gaussian': y = block._D * y #print(block, y.shape) # all blocks have been handled. # dimensionality reduction y = y[:self._d_pr] if self._normalization: y *= self._norm_factor_list return y else: if len(self._BBB) == 1 and self._BBB[0]._hash_func == 'random': y = np.dot(self._BBB[0]._A, y) return y y_global = np.zeros(self._d_pr) div = self._d_pr // self._d # number of parameters div_real = self._d_pr / self._d #print(div, div_real, self._d_pr, self._d) assert div == div_real # we handle only this case # /!\ + d_pr should be an integral power of 2!!! for i_div in xrange(div): #print('i_div', i_div) y = np.copy(x) # if div_real != div, the last mini block should be truncated => never happened because of the case of hadamard # split y into small vectors and reunit all results after for block in self._BBB[::-1]: #if i_div == div or i_div < div -1: # easy # matrix-vector product if block._hash_func == 'circulant': y = StructuredMatrices.circulant_product( block._col[i_div], y) if block._hash_func == 'skew_circulant': y = StructuredMatrices.skew_circulant_product( block._col[i_div], y, OMEGA, OMEGA_CONJ) if block._hash_func == 'toeplitz': y = StructuredMatrices.toeplitz_product( block._col[i_div], block._row[i_div], y) if block._hash_func == 'hadamard': y = StructuredMatrices.hadamard_cross_polytope_product( y, block._D[i_div], block._nblocks) if block._hash_func == 'hankel': y = StructuredMatrices.hankel_product( block._col[i_div], block._row[i_div], y) if block._hash_func == 'low_displacement_rank': y = StructuredMatrices.low_displacement_product( block._G[i_div], block._H[i_div], block._r, y, OMEGA, OMEGA_CONJ) if block._hash_func == 'kronecker': y = StructuredMatrices.kronecker_product_rec( block._A_list[i_div], y) if block._hash_func == 'pure_hadamard': a = ffht.create_aligned(y.shape[0], np.float32) np.copyto(a, y) ffht.fht(a, min(x.shape[0], 1024, 2048)) y = a if block._hash_func == 'diagonal' or block._hash_func == 'diagonal_kronecker' or block._hash_func == 'diagonal_gaussian': y = block._D[i_div] * y y_global[i_div * self._d:i_div * self._d + self._d] = y #print(y_global) if self._normalization: y_global *= self._norm_factor_list return y_global
import numpy as np import ffht import timeit reps = 1000 n = 2**20 chunk_size = 1024 a = ffht.create_aligned(n, np.float32) np.copyto(a, np.random.randn(n)) t1 = timeit.default_timer() for i in range(reps): ffht.fht(a, chunk_size) t2 = timeit.default_timer() print(t2 - t1 + 0.0) / (reps + 0.0)
import numpy as np import ffht import timeit reps = 1000 n = 2**20 chunk_size = 1024 a = ffht.create_aligned(n, np.float32) np.copyto(a, np.random.randn(n)) t1 = timeit.default_timer() for i in range(reps): ffht.fht(a, chunk_size) t2 = timeit.default_timer() print (t2 - t1 + 0.0) / (reps + 0.0)