Mentions légales du service

Skip to content
Snippets Groups Projects
Commit bd5a643f authored by hhakim's avatar hhakim
Browse files

Delete file of abandoned class matfaust.FaustFactory.

parent 10cb1982
No related branches found
No related tags found
No related merge requests found
%% class FaustFactory
%%
% ======================================================================
%> @brief This factory class provides methods for generating a Faust especially by factorization of a dense matrix.
%>
%>
%> This class gives access to the main factorization algorithms of
%> FAuST. Those algorithms can factorize a dense matrix to a sparse product
%> (i.e. a Faust object).
%>
%> There are several factorization algorithms.
%>
%> - The first one is Palm4MSA :
%> which stands for Proximal Alternating Linearized Minimization for
%> Multi-layer Sparse Approximation. Note that Palm4MSA is not
%> intended to be used directly. You should rather rely on the second algorithm.
%>
%> - The second one is the Hierarchical Factorization algorithm:
%> this is the central algorithm to factorize a dense matrix to a Faust.
%> It makes iterative use of Palm4MSA to proceed with the factorization of a given
%> dense matrix.
%>
%> - The third group of algorithms is for FGFT computing: FaustFactory.fgft_palm FaustFactory.fgft_givens FaustFactory.eigtj
%>
%>
% ======================================================================
classdef FaustFactory
properties (SetAccess = public)
end
methods(Static)
%==========================================================================================
%> @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
%> @code
%> import matfaust.*
%> import matfaust.factparams.*
%> M = rand(500, 32);
%> fact_cons = ConstraintList('splin', 5, 500, 32, 'sp', 96, 32, 32, 'sp', 96, 32, 32);
%> res_cons = ConstraintList('normcol', 1, 32, 32, 'sp', 666, 32, 32, 'sp', 333, 32, 32);
%> stop_crit = StoppingCriterion(200);
%> stop_crit2 = StoppingCriterion(200);
%> params = ParamsHierarchicalFact(fact_cons, res_cons, stop_crit, stop_crit2, 'is_update_way_R2L', false, 'init_lambda', 1.0);
%> F = FaustFactory.fact_hierarchical(M, params)
%> @endcode
%> Faust::HierarchicalFact<FPP,DEVICE>::compute_facts : factorization 1/3<br/>
%> Faust::HierarchicalFact<FPP,DEVICE>::compute_facts : factorization 2/3<br/>
%> Faust::HierarchicalFact<FPP,DEVICE>::compute_facts : factorization 3/3<br/>
%>
%> F =
%>
%> Faust size 500x32, density 0.189063, nnz_sum 3025, 4 factor(s):
%> - FACTOR 0 (real) SPARSE, size 500x32, density 0.15625, nnz 2500
%> - FACTOR 1 (real) SPARSE, size 32x32, density 0.09375, nnz 96
%> - FACTOR 2 (real) SPARSE, size 32x32, density 0.09375, nnz 96
%> - FACTOR 3 (real) SPARSE, size 32x32, density 0.325195, nnz 333
%>
%> @b Example 2: Simplified Parameters for Hadamard Factorization
%>@code
%> import matfaust.*
%> import matfaust.FaustFactory.*
%> % generate a Hadamard Faust of size 32x32
%> FH = wh(32);
%> H = full(FH); % the full matrix version
%> % factorize it
%> FH2 = FaustFactory.fact_hierarchical(H, 'squaremat');
%> % test the relative error
%> norm(FH-FH2, 'fro')/norm(FH, 'fro') % the result is 1.1015e-16, the factorization is accurate
%>@endcode
%>FH =
%>
%>Faust size 32x32, density 0.3125, nnz_sum 320, 5 factor(s):
%>- FACTOR 0 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 1 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 2 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 3 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 4 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>
%>FH2 =
%>
%>Faust size 32x32, density 0.3125, nnz_sum 320, 5 factor(s):
%>- FACTOR 0 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 1 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 2 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 3 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>- FACTOR 4 (real) SPARSE, size 32x32, density 0.0625, nnz 64
%>
%>
%>@b Example 3: Simplified Parameters for a Rectangular Matrix Factorization (the BSL demo MEG matrix)
%>
%> @code
%> >> % in a matlab terminal
%> >> import matfaust.*
%> >> load('matrix_MEG.mat')
%> >> MEG = matrix;
%> >> num_facts = 9;
%> >> k = 10;
%> >> s = 8;
%> >> MEG16 = FaustFactory.fact_hierarchical(MEG, {'rectmat', num_facts, k, s})
%> @endcode
%> MEG16 =
%>
%> Faust size 204x8193, density 0.0631655, nnz_sum 105573, 9 factor(s):
%> - FACTOR 0 (real) SPARSE, size 204x204, density 0.293613, nnz 12219
%> - FACTOR 1 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 2 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 3 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 4 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 5 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 6 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 7 (real) SPARSE, size 204x204, density 0.0392157, nnz 1632
%> - FACTOR 8 (real) SPARSE, size 204x8193, density 0.0490196, nnz 81930
%>
%> @code
%> >> % verify the constraint k == 10, on column 5
%> >> fac9 = factors(MEG16,9);
%> >> numel(nonzeros(fac9(:,5)))
%> @endcode
%> ans =
%>
%> 10
%>
%> @code
%> >> % now verify the s constraint is respected on MEG16 factor 2
%> >> numel(nonzeros(factors(MEG16, 2)))/size(MEG16,1)
%> @endcode
%>
%>ans =
%>
%> 8
%> <p> @b See @b also matfaust.faust_fact, factparams.ParamsHierarchicalFact, factparams.ParamsHierarchicalFactSquareMat, factparams.ParamsHierarchicalFactRectMat
%==========================================================================================
function varargout = fact_hierarchical(M, p)
import matfaust.Faust
import matfaust.factparams.*
matfaust.FaustFactory.check_fact_mat('FaustFactory.fact_hierarchical', M)
if(~ isa(p, 'ParamsHierarchicalFact') && ParamsFactFactory.is_a_valid_simplification(p))
p = ParamsFactFactory.createParams(M, p);
end
mex_constraints = cell(2, p.num_facts-1);
if(~ isa(p ,'ParamsHierarchicalFact'))
error('p must be a ParamsHierarchicalFact object.')
end
%mex_fact_constraints = cell(1, p.num_facts-1)
for i=1:p.num_facts-1
cur_cell = cell(1, 4);
cur_cell{1} = p.constraints{i}.name.conv2str();
cur_cell{2} = p.constraints{i}.param;
cur_cell{3} = p.constraints{i}.num_rows;
cur_cell{4} = p.constraints{i}.num_cols;
%mex_fact_constraints{i} = cur_cell;
mex_constraints{1,i} = cur_cell;
end
%mex_residuum_constraints = cell(1, p.num_facts-1)
for i=1:p.num_facts-1
cur_cell = cell(1, 4);
cur_cell{1} = p.constraints{i+p.num_facts-1}.name.conv2str();
cur_cell{2} = p.constraints{i+p.num_facts-1}.param;
cur_cell{3} = p.constraints{i+p.num_facts-1}.num_rows;
cur_cell{4} = p.constraints{i+p.num_facts-1}.num_cols;
%mex_residuum_constraints{i} = cur_cell;
mex_constraints{2,i} = cur_cell;
end
if(~ p.is_mat_consistent(M))
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
mex_params = struct('nfacts', p.num_facts, 'cons', {mex_constraints}, 'niter1', p.stop_crits{1}.num_its,'niter2', p.stop_crits{2}.num_its, 'sc_is_criterion_error', p.stop_crits{1}.is_criterion_error, 'sc_error_treshold', p.stop_crits{1}.error_treshold, 'sc_max_num_its', p.stop_crits{1}.max_num_its, 'sc_is_criterion_error2', p.stop_crits{2}.is_criterion_error, 'sc_error_treshold2', p.stop_crits{2}.error_treshold, 'sc_max_num_its2', p.stop_crits{2}.max_num_its, 'nrow', p.data_num_rows, 'ncol', p.data_num_cols, 'fact_side', p.is_fact_side_left, 'update_way', p.is_update_way_R2L, 'verbose', p.is_verbose, 'init_lambda', p.init_lambda);
if(isreal(M))
[lambda, core_obj] = mexHierarchical_factReal(M, mex_params);
else
[lambda, core_obj] = mexHierarchical_factCplx(M, mex_params);
end
F = Faust(core_obj, isreal(M));
varargout = {F, lambda, p};
end
%==========================================================================================
%> @brief Approximates M by A S_1 … S_n B using FaustFactory.fact_palm4msa.
%>
%>
%> @Example
%> @code
%> import matfaust.*
%> import matfaust.factparams.*
%>
%> p = ParamsPalm4MSA(…
%> ConstraintList('spcol', 2, 10, 20, 'sp', 30, 20, 20),…
%> StoppingCriterion(50), 'is_verbose', false);
%> M = rand(10,10);
%> A = rand(10,10);
%> B = rand(20, 10);
%> [F, lamdba] = FaustFactory.fact_palm4msa_constends(M, p, A, B)
%>
%> assert(norm(A - factors(F,1))/norm(A) <= eps(double(1)))
%> assert(norm(B - factors(F,4))/norm(B) <= eps(double(1)))
%>
%> @endcode
%==========================================================================================
function [F, lambda] = fact_palm4msa_constends(M, p, A, varargin)
import matfaust.factparams.*
import matfaust.FaustFactory
if(~ ismatrix(A))
error('A must be a matrix.')
end
consA = ConstraintList('const', A, size(A,1), size(A,2));
new_consts = {};
new_consts = [ {consA.clist{:}}, {p.constraints{:}} ];
if(length(varargin) > 0)
B = varargin{1};
if(~ ismatrix(B))
error('B must be a matrix.')
end
consB = ConstraintList('const', B, size(B,1), size(B,2));
new_consts = [ new_consts, {consB.clist{:}} ];
end
new_consts = ConstraintList(new_consts{:});
p = ParamsPalm4MSA(new_consts, p.stop_crit, 'is_update_way_R2L', p.is_update_way_R2L, ...
'init_lambda', p.init_lambda, 'step_size', p.step_size, 'constant_step_size', ...
p.constant_step_size, 'is_verbose', p.is_verbose);
[F, lambda ] = FaustFactory.fact_palm4msa(M, p);
f1 = factors(F, 1);
f1 = f1 / lambda;
nF = cell(1, numfactors(F));
nF{1} = f1;
for i=2:numfactors(F)
nF{i} = factors(F, i);
end
nF{2} = nF{2}*lambda;
F = matfaust.Faust(nF);
end
%==========================================================================================
%> @brief Approximates M by A S_1 ... S_n B using FaustFactory.fact_hierarchical.
%>
%> @Example
%> @code
%> import matfaust.*
%> import matfaust.factparams.*
%>
%> p = ParamsHierarchicalFact(…
%> ConstraintList('spcol', 2, 10, 20, 'sp', 30, 10, 10), ConstraintList('sp', 4, 10, 20, 'splin', 5, 10, 10),…
%> StoppingCriterion(50), StoppingCriterion(50),…
%> 'is_fact_side_left', true, 'is_verbose', false…
%> );
%> M = rand(10,10);
%> A = rand(10,10);
%> B = rand(20, 10);
%> [F, lamdba, ~] = FaustFactory.fact_hierarchical_constends(M, p, A, B)
%>
%> assert(norm(A - factors(F,1))/norm(A) <= eps(double(1)))
%> assert(norm(B - factors(F,4))/norm(B) <= eps(double(1)))
%> @endcode
%>
%==========================================================================================
function varargout = fact_hierarchical_constends(M, p, A, B)
import matfaust.factparams.*
import matfaust.FaustFactory
if(~ ismatrix(A) || ~ ismatrix(B))
error('A and B must be matrices.')
end
consA = ConstraintList('const', A, size(A, 1), size(A, 2));
consB = ConstraintList('const', B, size(B, 1), size(B, 2));
consts = p.constraints;
nconsts = length(p.constraints);
% consts: factor constraints + residuum constraints
fac_cons = {};
res_cons = {};
for i=1:p.num_facts-1
fac_cons = { fac_cons{:}, consts{i} };
end
for i=p.num_facts:length(consts)
res_cons = { res_cons{:}, consts{i} };
end
assert(length(fac_cons) == length(res_cons))
% add two constants factor constraints for A and B to the old constraints
% According to the factorization direction, switch A and B positions
if(p.is_fact_side_left)
new_fact_cons = { consB.clist{:}, fac_cons{:} };
new_res_cons = { res_cons{:}, consA.clist{:} };
else
new_fact_cons = { consA.clist{:}, fac_cons{:} };
new_res_cons = { res_cons{:}, consB.clist{:} };
end
p = ParamsHierarchicalFact(new_fact_cons, new_res_cons,...
p.stop_crits{1}, p.stop_crits{2}, 'is_update_way_R2L', p.is_update_way_R2L, ...
'init_lambda', p.init_lambda, 'step_size', p.step_size, 'constant_step_size', ...
p.constant_step_size, 'is_verbose', p.is_verbose, 'is_fact_side_left', p.is_fact_side_left);
[F, lambda, p] = FaustFactory.fact_hierarchical(M, p);
f1 = factors(F, 1);
f1 = f1 / lambda;
nF = cell(1, numfactors(F));
nF{1} = f1;
for i=2:numfactors(F)
nF{i} = factors(F, i);
end
nF{2} = nF{2}*lambda;
F = matfaust.Faust(nF);
varargout = {F, lambda, p};
end
end
methods(Access = private, Static)
function check_fact_mat(funcname, M)
if(~ ismatrix(M) || isscalar(M))
error([funcname,'() 1st argument (M) must be a matrix.'])
end
if(~ isnumeric(M))
error([funcname, '() 1st argument (M) must be real or complex.'])
end
% if(~ isreal(M))
% error([funcname, '() doesn''t yet support complex matrix factorization.'])
% end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment