%> @brief Factorizes the matrix M with Hierarchical Factorization using the parameters set in p.
%>
%>
%> @param M the dense matrix to factorize.
%> @param p is a set of factorization parameters. It might be a fully defined instance of parameters (matfaust.factparams.ParamsHierarchicalFact) or a simplified expression which designates a pre-defined parametrization:
%> - 'squaremat' to use pre-defined parameters typically used to factorize a Hadamard square matrix of order a power of two (see matfaust.demo.hadamard).
%> - {'rectmat', j, k, s} to use pre-defined parameters used for instance in factorization of the MEG matrix which is a rectangular matrix of size m*n such that m < n (see matfaust.demo.bsl); j is the number of factors, k the sparsity of the main factor's columns, and s the sparsity of rows for all other factors except the residuum (that is the first factor here because the factorization is made toward the left -- is_side_fact_left == true, cf. matfaust.factparams.ParamsHierarchicalFact).
%> </br>The residuum has a sparsity of P*rho^(num_facts-1). <br/> By default, rho == .8 and P = 1.4. It's possible to set custom values with for example p == { 'rectmat', j, k, s, 'rho', .4, 'P', .7}. <br/>The sparsity is here the number of non-zero elements.
%> @note - The fully defined parameters (ParamsHierarchicalFact instance) used/generated by the function are available in the return result (so one can consult what precisely mean the simplified parameterizations and possibly adjust the attributes to factorize again).
%> @note - This function has its shorthand matfaust.faust_fact(). For convenience you might use it like this:
%> @code
%> import matfaust.*
%> F = faust_fact(M, p) % equiv. to FaustFactory.fact_hierarchical(M, p)
%> @endcode
%>
%> @retval F The Faust object result of the factorization.
%> @retval [F, lambda, p_obj] = fact_hierarchical(M, p) to optionally get lambda (scale) and the p_obj ParamsHierarchicalFact instance used to factorize.
%>
%> @b Example 1: Fully Defined Parameters for a Random Matrix Factorization
%> <p> @b See @b also matfaust.faust_fact, factparams.ParamsHierarchicalFact, factparams.ParamsHierarchicalFactSquareMat, factparams.ParamsHierarchicalFactRectMat
error('M''s number of columns must be consistent with the last residuum constraint defined in p. Likewise its number of rows must be consistent with the first factor constraint defined in p.')
end
% the setters for num_rows/cols verifies consistency with constraints