-
3.41.0
|
The pyfaust factorization module. More...
Functions | |
def | svdtj (M, nGivens=None, tol=0, err_period=100, relerr=True, nGivens_per_fac=None, enable_large_Faust=False, **kwargs) |
Performs a singular value decomposition and returns the left and right singular vectors as Faust transforms. More... | |
def | pinvtj (M, nGivens=None, tol=0, err_period=100, relerr=True, nGivens_per_fac=None, enable_large_Faust=False, **kwargs) |
Computes the pseudoinverse of M using svdtj. More... | |
def | eigtj (M, nGivens=None, tol=0, err_period=100, order='ascend', relerr=True, nGivens_per_fac=None, verbosity=0, enable_large_Faust=False) |
Performs an approximate eigendecomposition of M and returns the eigenvalues in W along with the corresponding normalized right eigenvectors (as the columns of the Faust object V). More... | |
def | palm4msa (M, p, ret_lambda=False, backend=2016, on_gpu=False) |
Factorizes the matrix M with Palm4MSA algorithm using the parameters set in p. More... | |
def | palm4msa_mhtp (M, palm4msa_p, mhtp_p, ret_lambda=False, on_gpu=False) |
Runs the MHTP-PALM4MSA algorithm to factorize the matrix M. More... | |
def | hierarchical_mhtp (M, hierar_p, mhtp_p, ret_lambda=False, ret_params=False, on_gpu=False) |
Runs the MHTP-PALM4MSA hierarchical factorization algorithm on the matrix M. More... | |
def | hierarchical (M, p, ret_lambda=False, ret_params=False, backend=2016, on_gpu=False) |
Factorizes the matrix M using the hierarchical PALM4MSA algorithm according to the parameters set in p. More... | |
def | butterfly (M, type="bbtree", perm=None, diag_opt=False, mul_perm=None) |
Factorizes M according to a butterfly support and optionally a permutation using the algorithms described in [1]. More... | |
def | fdb (np.ndarray matrix, int n_factors=4, int rank=1, bool orthonormalize=True, str hierarchical_order='left-to-right', bool bit_rev_perm=False, str backend='numpy') |
Return a Faust object corresponding to the factorization of matrix . More... | |
The pyfaust factorization module.
This module gives access to the main factorization algorithms of FAuST. These algorithms can factorize a dense matrix into a sparse product (i.e. a Faust object).
There are several factorization algorithms.
def pyfaust.fact.butterfly | ( | M, | |
type = "bbtree" , |
|||
perm = None , |
|||
diag_opt = False , |
|||
mul_perm = None |
|||
) |
Factorizes M according to a butterfly support and optionally a permutation using the algorithms described in [1].
The result is a Faust F of the form BP where B has a butterfly structure and P is a permutation matrix determined by the optional parameter perm.
M | (numpy ndarray) The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). M must be square and its dimension must be a power of two. |
type | (str) the type of factorization 'right'ward, 'left'ward or 'bbtree'. More precisely: if 'left' (resp. 'right') is used then at each stage of the factorization the most left factor (resp. the most right factor) is split in two. If 'bbtree' is used then the matrix is factorized according to a Balanced Binary Tree (which is faster as it allows parallelization). |
perm | five kinds of values are possible for this argument.
|
diag_opt | (bool) if True then the returned Faust is optimized using pyfaust.opt_butterfly_faust. |
mul_perm | (bool) decides if the permutation is multiplied into the rightest butterfly factor (mul_perm=True) or if this permutation is left apart as the rightest factor of the Faust (mul_perm=False). It can't be True if diag_opt is True (an error is raised otherwise). Defaultly, mul_perm=None which implies that mul_perm is True iff diag_opt is False. |
Examples
Use simple permutations:
Use butterfly with a permutation defined by a list of indices J:
def pyfaust.fact.eigtj | ( | M, | |
nGivens = None , |
|||
tol = 0 , |
|||
err_period = 100 , |
|||
order = 'ascend' , |
|||
relerr = True , |
|||
nGivens_per_fac = None , |
|||
verbosity = 0 , |
|||
enable_large_Faust = False |
|||
) |
Performs an approximate eigendecomposition of M and returns the eigenvalues in W along with the corresponding normalized right eigenvectors (as the columns of the Faust object V).
The output is such that V*numpy.diag(W)*V.H approximates M. V is a product of Givens rotations obtained by truncating the Jacobi algorithm.
The trade-off between accuracy and complexity of V can be set through the parameters nGivens and tol that define the targeted number of Givens rotations and targeted error.
M | (numpy.ndarray or csr_matrix) the matrix to diagonalize. Must be real and symmetric, or complex hermitian. Can be in dense or sparse format. The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
nGivens | (int) targeted number of Givens rotations (this argument is optional only if tol is set). |
tol | (float) the tolerance error at which the algorithm stops. The default value is zero so that stopping is based on reaching the targeted nGivens (this argument is optional only if nGivens is set). |
err_period | (int) it defines the period, in number of factors of V the error is compared to tol (reducing the period spares some factors but increases slightly the computational cost because the error is computed more often). |
order | (str) order of eigenvalues, possible choices are ‘ascend, 'descend' or 'undef' (to avoid a sorting operation and save some time). |
nGivens_per_fac | (int) targeted number of Givens rotations per factor of V. Must be an integer between 1 to floor(M.shape[0]/2) (the default value). |
relErr | (bool) the type of error used as stopping criterion. True for the relative error norm(V*D*V'-M, 'fro')/norm(M, 'fro'), False for the absolute error norm(V*D*V'-M, 'fro'). |
verbosity | (int) the level of verbosity. The greater the value the more info is displayed. It can be helpful to understand for example why the algorithm stopped before reaching the tol error or the number of Givens (nGivens). |
enable_large_Faust | (bool) if true, it allows to compute a transform that doesn't worth it regarding its complexity compared to the matrix M. Otherwise by default, an exception is raised before the algorithm starts. |
Examples
def pyfaust.fact.fdb | ( | np.ndarray | matrix, |
int | n_factors = 4 , |
||
int | rank = 1 , |
||
bool | orthonormalize = True , |
||
str | hierarchical_order = 'left-to-right' , |
||
bool | bit_rev_perm = False , |
||
str | backend = 'numpy' |
||
) |
Return a Faust object corresponding to the factorization of matrix
.
matrix | np.ndarray Matrix to factorize. |
n_factors | int , optional Number of factors (4 is default). |
rank | int , optional Rank of sub-blocks (1 is default), used by the underlying SVD. |
orthonormalize | bool , optional True (default)
str , optional |
bit_rev_perm: bool
, optional Use bit reversal permutations matrix (default is False
). It is useful when you would like to factorize DFT matrix. With no bit-reversal permutations you would have to tune the value of the rank as a function of the matrix size.
backend | str , optional Use numpy (default) or pytorch to compute SVD and QR decompositions. |
matrix
.NotImplementedError | hierarchical order must be either 'left-to-right' or 'balanced'. |
Exception | Number of rows and number of columns must be greater than the rank value. |
Exception | Because backend='numpy' matrix must be a NumPy array. |
def pyfaust.fact.hierarchical | ( | M, | |
p, | |||
ret_lambda = False , |
|||
ret_params = False , |
|||
backend = 2016 , |
|||
on_gpu = False |
|||
) |
Factorizes the matrix M using the hierarchical PALM4MSA algorithm according to the parameters set in p.
Basically, the hierarchical factorization works in a sequence of splits in two of the last factor. The first split consists to split the matrix M in two, when p.is_fact_side_left is False (which is the case by default), the factorization works toward right, so M is factorized as follows:
\[M \approx S_1 R_1\]
We call \(S_1\) the main factor and \(R_1\) the residual factor. On step 2, \(R_1\) is split in two such as \(R_1 \approx S_2 R_2\), which gives:
\[M \approx S_1 S_2 R_2 \]
And so on until the algorithm reaches the targeted number of factors:
\[M \approx S_1 S_2 ... S_{N-1} R_N \]
If p.is_fact_side_left
is False, the residual is factorized toward left, so it gives rather :
\[M \approx R_1 S_1 \\ \\ M \approx R_2 S_2 S_1 \\ \vdots \\ M \approx R_N S_{N-1} ... S_2 S_1 \]
M | (numpy array) the array to factorize. The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
p | (pyfaust.factparams.ParamsHierarchical, list or str) is a set of hierarchical factorization parameters. It might be a fully defined instance of parameters (pyfaust.factparams.ParamsHierarchical) or a simplified expression which designates a pre-defined parameterization:
|
backend | (int) the C++ implementation to use (default to 2016, 2020 backend should be faster for most of the factorizations). |
on_gpu | (bool) if True the GPU implementation is executed (this option applies only to 2020 backend). |
ret_lambda | (bool) set to True to ask the function to return the scale factor (False by default). |
ret_params | (bool) set to True to ask the function to return the ParamsHierarchical instance used (False by default). It is useful for consulting what precisely means the simplified parameterizations used to generate a pyfaust.factparams.ParamsHierarchical instance and possibly adjust its attributes to factorize again. |
1. Fully Defined Parameters for a Random Matrix Factorization
Faust size 500x32, density 0.189063, nnz_sum 3025, 4 factor(s):
2. Simplified Parameters for Hadamard Factorization
Faust size 32x32, density 0.3125, nnz_sum 320, 5 factor(s):
Faust size 32x32, density 0.3125, nnz_sum 320, 5 factor(s):
3. Simplified Parameters for a Rectangular Matrix Factorization (the BSL demo MEG matrix)
Faust size 204x8193, density 0.0631655, nnz_sum 105573, 9 factor(s):
4. Simplified Parameters for the Discrete Fourier Transform Factorization
Faust size 32x32, density 0.34375, nnz_sum 352, 6 factor(s):
Faust size 32x32, density 0.34375, nnz_sum 352, 6 factor(s):
5. Simplified Parameters for Hadamard Factorization without residual constraints
This factorization parameterization is the same as the one shown in 2. except that there is no constraints at all on residual factors. See pyfaust.factparams.ParamsHierarchicalNoResCons and pyfaust.factparams.ParamsHierarchicalWHTNoResCons for more details.
Faust size 32x32, density 0.3125, nnz_sum 320, 5 factor(s):
6. Simplified Parameters for a Rectangular Matrix Factorization (the BSL demo MEG matrix) without residual constraints
The factorization parameterization shown here is the same as in 3. except that there is no constraint at all on residual factors. See pyfaust.factparams.ParamsHierarchicalNoResCons and pyfaust.factparams.ParamsHierarchicalRectMatNoResCons for more details. In the example below the MEG matrix is factorized according to the parameterization shown in 3. (aka "MEG") and on the other hand with the parameterization of interest here (aka "MEG_SIMPLE", with no residual constraints), the approximate accuracy is quite the same so we can conclude that on this case (as in 5.) removing residual constraints can not only simplify the parameterization of hierarchical PALM4MSA but also be as efficient.
def pyfaust.fact.hierarchical_mhtp | ( | M, | |
hierar_p, | |||
mhtp_p, | |||
ret_lambda = False , |
|||
ret_params = False , |
|||
on_gpu = False |
|||
) |
Runs the MHTP-PALM4MSA hierarchical factorization algorithm on the matrix M.
This algorithm uses the MHTP-PALM4MSA (pyfaust.fact.palm4msa_mhtp) instead of only PALM4MSA as pyfaust.fact.hierarchical.
M | (np.ndarray) the numpy array to factorize. The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
p | (pyfaust.factparams.ParamsHierarchical) is a set of hierarchical factorization parameters. See |
hierarchical. | |
mhtp_p | (pypyfaust.factparams.MHTPParams) the instance to define the MHTP algorithm parameters. |
on_gpu | (bool) if True the GPU implementation is executed. |
ret_lambda | (bool) set to True to ask the function to return the scale factor (False by default). |
ret_params | (bool) set to True to ask the function to return the pyfaust.factparams.ParamsHierarchical instance used (False by default). |
Examples
def pyfaust.fact.palm4msa | ( | M, | |
p, | |||
ret_lambda = False , |
|||
backend = 2016 , |
|||
on_gpu = False |
|||
) |
Factorizes the matrix M with Palm4MSA algorithm using the parameters set in p.
M | (np.ndarray) the numpy array to factorize. The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
p | (pyfaust.factparams.ParamsPalm4MSA) parameters instance to define the algorithm parameters. |
ret_lambda | (bool) set to True to ask the function to return the scale factor (False by default). |
backend | (str) the C++ implementation to use (default to 2016, 2020 backend should be faster for most of the factorizations). |
on_gpu | (bool) if True the GPU implementation is executed (this option applies only to 2020 backend). |
Examples
Faust size 500x32, density 0.22025, nnz_sum 3524, 2 factor(s):
def pyfaust.fact.palm4msa_mhtp | ( | M, | |
palm4msa_p, | |||
mhtp_p, | |||
ret_lambda = False , |
|||
on_gpu = False |
|||
) |
Runs the MHTP-PALM4MSA algorithm to factorize the matrix M.
MHTP stands for Multilinear Hard Tresholding Pursuit. This is a generalization of the Bilinear HTP algorithm describe in [1].
[1] Quoc-Tung Le, Rémi Gribonval. Structured Support Exploration For Multilayer Sparse Matrix Factorization. ICASSP 2021 - IEEE International Conference on Acoustics, Speech and Signal Processing, Jun 2021, Toronto, Ontario, Canada. pp.1-5. hal-03132013
M | (np.ndarray) the numpy array to factorize. The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
palm4msa_p | (pyfaust.factparams.ParamsPalm4MSA) instance of parameters to define the PALM4MSA algorithm parameters. |
mhtp_p | (pyfaust.factparams.MHTPParams) instance of parameters to define the MHTP algorithm parameters. |
ret_lambda | (bool) set to True to ask the function to return the scale factor (False by default). |
on_gpu | (bool) if True the GPU implementation is executed. |
def pyfaust.fact.pinvtj | ( | M, | |
nGivens = None , |
|||
tol = 0 , |
|||
err_period = 100 , |
|||
relerr = True , |
|||
nGivens_per_fac = None , |
|||
enable_large_Faust = False , |
|||
** | kwargs | ||
) |
Computes the pseudoinverse of M using svdtj.
M | (np.ndarray) the matrix to compute the pseudoinverse. |
nGivens | (int or tuple(int,int)) see svdtj |
tol | (float) see svdtj (here the error is computed on U.H S^+ V). |
err_period | (int) see svdtj. |
relerr | (bool) see svdtj. |
nGivens_per_fac | (int or tuple(int,int)) see svdtj. |
enable_large_Faust | (bool) see svdtj. |
def pyfaust.fact.svdtj | ( | M, | |
nGivens = None , |
|||
tol = 0 , |
|||
err_period = 100 , |
|||
relerr = True , |
|||
nGivens_per_fac = None , |
|||
enable_large_Faust = False , |
|||
** | kwargs | ||
) |
Performs a singular value decomposition and returns the left and right singular vectors as Faust transforms.
M | (np.ndarray or scipy.sparse.csr_matrix) a real or complex matrix . The dtype must be float32, float64 or complex128 (the dtype might have a large impact on performance). |
nGivens | (int or tuple(int, int)) defines the number of Givens rotations that will be used at most to compute U and V. If it is an integer, it will apply both to U and V. If it is a tuple of two integers as nGivens = (JU, JV), JU will be the limit number of rotations for U and JV the same for V. nGivens argument is optional if tol is set but becomes mandatory otherwise. |
tol | (float) this is the error target on U S V' against M. if error <= tol, the algorithm stops. See relerr below for the error formula. This argument is optional if nGivens is set, otherwise it becomes mandatory. |
err_period | (int) it defines the period, in number of factors of U or V, the error is compared to tol (reducing the period spares some factors but increases slightly the computational cost because the error is computed more often). |
relerr | (bool) defines the type of error used to evaluate the stopping criterion defined by tol. true for a relative error ( \(\| U' S V - M\|_F \over \| M \|_F\)) otherwise this is an absolute error ( \(\| U' S V - M\|_F\)). |
nGivens_per_fac | (int or tuple(int, int)) this argument is the number of Givens rotations to set at most by factor of U and V. If this is an integer it will be the same number of U and V. Otherwise, if it is a tuple of integers (tU, tV), tU will be the number of Givens rotations per factor for U and tV the same for V. By default, this parameter is maximized for U and V, i.e. tU = M.shape[0] / 2, tV = M.shape[1] / 2. |
enable_large_Faust | see eigtj. |
os.environ['SVDTJ_ALL_TRUE_ERR'] = '1'
If we call svdtj on the matrix M, it makes two internal calls to eigtj. In Python it would be:
It gives the following equalities (ignoring the fact that eigtj computes approximations):
\[W_1 D_1 W_1^* = M M^*\]
\[W_2 D_2 W_2^* = M^* M\]
But because of the SVD \( M = USV^* \) we also have:
\[MM^* = U S V^* V S U^* = U S^2 U^* = W_1 D_1 W_1^*\]
\[M^* M = V S U^* U S V^* = V S^2 V^* = W_2 D_2 W_2^*\]
It allows to identify the left singular vectors of M to W1, and likewise the right singular vectors to W2.
To compute a consistent approximation of S we observe that U and V are orthogonal hence \(S = U^* M V\) so we ignore the off-diagonal coefficients of the approximation and take \(S = diag(U^* M V) \approx diag(W_1^* M W_2)\)