Mentions légales du service

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

Impl. MEG/Rectangular matrix factorization simplified parameters.

matfaust.FaustFactory.fact_hierarchical(M,, {'rectmat', j, k, s})
pyfaust.FaustFactory.fact_hierarchical(M, (rectmat, j, k, s))

Rename also ParamsHierarchicalFactHadamard to ParamsHierarchicalFactSquareMat (used also for FFT).
parent 6fd439a4
Branches
Tags
No related merge requests found
......@@ -30,10 +30,7 @@ classdef ParamsHierarchicalFact < matfaust.factparams.ParamsFact
if(~ isa(stop_crit2, 'StoppingCriterion'))
error('stop_crit2 (argument 4) must a StoppingCriterion')
end
constraints = {fact_constraints{:}, res_constraints{:}};
stop_crits = {stop_crit1, stop_crit2};
% infer number of factors from constraints
num_facts = length(fact_constraints)+1;
parent_args = {};
opt_arg_map = containers.Map();
if(length(varargin) > 0)
......@@ -50,24 +47,45 @@ classdef ParamsHierarchicalFact < matfaust.factparams.ParamsFact
end
% parent constructor handles verification for its own arguments
end
p = p@matfaust.factparams.ParamsFact(num_facts, constraints, parent_args{:});
% data_num_rows/data_num_cols are set by FaustFactory.fact_hierarchical()
% set default values
is_fact_side_left = ParamsHierarchicalFact.DEFAULT_IS_FACT_SIDE_LEFT;
if(opt_arg_map.isKey(ParamsHierarchicalFact.OPT_ARG_NAMES2{p.IDX_IS_FACT_SIDE_LEFT}))
is_fact_side_left = opt_arg_map(ParamsHierarchicalFact.OPT_ARG_NAMES2{p.IDX_IS_FACT_SIDE_LEFT});
if(opt_arg_map.isKey(ParamsHierarchicalFact.OPT_ARG_NAMES2{ParamsHierarchicalFact.IDX_IS_FACT_SIDE_LEFT}))
is_fact_side_left = opt_arg_map(ParamsHierarchicalFact.OPT_ARG_NAMES2{ParamsHierarchicalFact.IDX_IS_FACT_SIDE_LEFT});
end
if(~ islogical(is_fact_side_left))
error('matfaust.factparams.ParamsHierarchicalFact: is_fact_side_left argument must be logical.')
end
if(is_fact_side_left)
constraints = {res_constraints{:}, fact_constraints{:}};
else
constraints = {fact_constraints{:}, res_constraints{:}};
end
stop_crits = {stop_crit1, stop_crit2};
% infer number of factors from constraints
num_facts = length(fact_constraints)+1;
p = p@matfaust.factparams.ParamsFact(num_facts, constraints, parent_args{:});
p.stop_crits = stop_crits;
p.is_fact_side_left = is_fact_side_left;
% auto-deduced to-factorize-matrix dim. sizes
p.data_num_rows = p.constraints{1}.num_rows;
p.data_num_cols = p.constraints{end}.num_cols;
if(p.is_fact_side_left)
p.data_num_rows = res_constraints{end}.num_rows;
p.data_num_cols = fact_constraints{1}.num_cols;
else
p.data_num_rows = p.constraints{1}.num_rows;
p.data_num_cols = p.constraints{end}.num_cols;
end
end
function bool = is_mat_consistent(this, M)
if(~ ismatrix(M))
error('M must be a matrix.')
else
% no need to take care of is_fact_side_left
% because data_num_rows and data_num_cols have been infered according to the constraints and is_fact_side_left
s = size(M);
bool = all(s == [this.data_num_rows, this.data_num_cols]);
end
end
end
end
classdef ParamsHierarchicalFactRectMat < matfaust.factparams.ParamsHierarchicalFact
properties(Constant)
DEFAULT_RHO = 0.8
DEFAULT_P_CONST_FACT = 1.4
IDX_RHO = 1
IDX_P = 2
OPT_ARG_NAMES3 = { 'rho', 'P' }
end
methods
function p = ParamsHierarchicalFactRectMat(m, n, j, k, s, varargin)
import matfaust.factparams.*
%TODO: verify arguments
opt_arg_map = containers.Map();
opt_arg_names = ParamsHierarchicalFactRectMat.OPT_ARG_NAMES3;
if(length(varargin) > 0)
% retrieve all optional argument key-value pairs
ParamsFact.parse_opt_args(varargin, opt_arg_names)
end
% set default values for optional args
rho = ParamsHierarchicalFactRectMat.DEFAULT_RHO;
P = ParamsHierarchicalFactRectMat.DEFAULT_P_CONST_FACT*m^2;
idx_rho = ParamsHierarchicalFactRectMat.IDX_RHO;
idx_P = ParamsHierarchicalFactRectMat.IDX_P;
% get customed values if provided
if(opt_arg_map.isKey(opt_arg_names{idx_rho}))
rho = opt_arg_map(opt_arg_names{idx_rho});
end
if(opt_arg_map.isKey(opt_arg_names{idx_P}))
P = opt_arg_map(opt_arg_names{idx_P});
end
S1_cons = ConstraintInt('spcol', m, n, k);
S_cons = {S1_cons};
for i=1:j-2
S_cons = [ S_cons, {ConstraintInt('sp', m, m, s*m)} ];
end
R_cons = {};
for i=1:j-1
R_cons = [ R_cons, {ConstraintInt('sp', m, m, P*rho^(i-1))} ];
end
stop_crit = StoppingCriterion(30);
p = p@matfaust.factparams.ParamsHierarchicalFact(S_cons, R_cons, stop_crit,...
stop_crit, 'is_update_way_R2L', true, 'is_fact_side_left', true);
end
end
end
classdef ParamsHierarchicalFactHadamard < matfaust.factparams.ParamsHierarchicalFact
classdef ParamsHierarchicalFactSquareMat < matfaust.factparams.ParamsHierarchicalFact
methods
function p = ParamsHierarchicalFactHadamard(n)
function p = ParamsHierarchicalFactSquareMat(n)
import matfaust.factparams.*
d = 2^floor(n);
fact_cons = {};
res_cons = {};
stop_crit = StoppingCriterion(30);
% ENOTE: cell concatenation
for i=0:(n-2)
fact_cons = [ fact_cons, {ConstraintInt('splincol',d,d,2)} ];
end
......
......@@ -147,12 +147,21 @@ classdef FaustFactory
function F = fact_hierarchical(M, p)
import matfaust.Faust
import matfaust.factparams.*
if(strcmp(p,'hadamard'))
transp = false;
if(ischar(p) && (strcmp(p,'hadamard') || strcmp(p, 'squaremat') || strcmp(p, 'fft')))
pot = log2(size(M,1));
if(size(M,1) ~= size(M,2) || pot-floor(pot) > 0)
error('For the Hadamard parameters, M must be a square matrix of order a power of two.')
end
p = ParamsHierarchicalFactHadamard(pot);
p = ParamsHierarchicalFactSquareMat(pot);
elseif(iscell(p) && length(p) == 4 && (strcmp(p{1}, 'rectmat') || strcmp(p{1}, 'meg')))
s = size(M)
transp = s(1) > s(2);
if(transp)
M = M.'
end
% p = {'rectmat', j, k, s}
p = ParamsHierarchicalFactRectMat(size(M,1), size(M,2), p{2}, p{3}, p{4})
end
mex_constraints = cell(2, p.num_facts-1);
matfaust.FaustFactory.check_fact_mat('FaustFactory.fact_hierarchical', M)
......@@ -190,6 +199,9 @@ classdef FaustFactory
[lambda, core_obj] = mexHierarchical_factCplx(M, mex_params);
end
F = Faust(core_obj, isreal(M));
if(transp)
F = F.'
end
end
%==========================================================================================
......
......@@ -1419,19 +1419,28 @@ class FaustFactory:
- 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
"""
if(isinstance(p, str) and p.lower() == "hadamard"):
"""
transp = False
if(isinstance(p, str) and p.lower() in ("hadamard", "fft", "squaremat")):
#TODO: FactParamFactory.create('hadamard')
from pyfaust.factparams import \
ParamsHierarchicalFactHadamard, StoppingCriterion
from pyfaust.factparams import ParamsHierarchicalFactSquareMat
pot = np.log2(M.shape[0])
if(pot > int(pot) or M.shape[0] != M.shape[1]):
raise ValueError('For the Hadamard parameters, M must be a '
'square matrix of order a power of '
'two.')
pot = int(pot)
p = ParamsHierarchicalFactHadamard(pot)
p = ParamsHierarchicalFactSquareMat(pot)
elif((isinstance(p, tuple) or isinstance(p, list)) and len(p) == 4 and isinstance(p[0],str)
and p[0].lower() in ("rectmat", "meg")):
from pyfaust.factparams import ParamsHierarchicalFactRectMat
s = M.shape
transp = s[0]>s[1]
if(transp):
M = M.T
# p = ('rectmat', j, k, s)
p = ParamsHierarchicalFactRectMat(M.shape[0], M.shape[1], p[1], p[2],
p[3])
if(not isinstance(p, pyfaust.factparams.ParamsHierarchicalFact)):
raise TypeError("p must be a ParamsHierarchicalFact object.")
FaustFactory._check_fact_mat('FaustFactory.fact_hierarchical()', M)
......@@ -1440,7 +1449,10 @@ class FaustFactory:
"the last residuum constraint defined in p. "
"Likewise its number of rows must be consistent "
"with the first factor constraint defined in p.")
return Faust(core_obj=FaustCorePy.FaustFact.fact_hierarchical(M, p))
F = Faust(core_obj=FaustCorePy.FaustFact.fact_hierarchical(M, p))
if(transp):
F = F.T
return F
@staticmethod
def wht(n):
......
......@@ -240,8 +240,14 @@ class ParamsHierarchicalFact(ParamsFact):
raise TypeError('fact_constraints must be a list.')
if(not isinstance(res_constraints, list)):
raise TypeError('res_constraints must be a list.')
if(len(fact_constraints) != len(res_constraints)):
raise ValueError('fact_constraints and res_constraints must have'
' same length.')
num_facts = len(fact_constraints)+1
constraints = fact_constraints + res_constraints
if(is_fact_side_left):
constraints = res_constraints + fact_constraints
else:
constraints = fact_constraints + res_constraints
stop_crits = [ stop_crit1, stop_crit2 ]
super(ParamsHierarchicalFact, self).__init__(num_facts,
is_update_way_R2L,
......@@ -251,7 +257,6 @@ class ParamsHierarchicalFact(ParamsFact):
is_verbose)
self.stop_crits = stop_crits
self.is_fact_side_left = is_fact_side_left
#TODO: verify number of constraints is consistent with num_facts in
if((not isinstance(stop_crits, list) and not isinstance(stop_crits,
tuple)) or
len(stop_crits) != 2 or
......@@ -266,15 +271,25 @@ class ParamsHierarchicalFact(ParamsFact):
raise TypeError('constraints argument must be a list/tuple of '
'ConstraintGeneric (or subclasses) objects')
# auto-infer matrix dimension sizes according to the constraints
self.data_num_rows = constraints[0]._num_rows
self.data_num_cols = constraints[-1]._num_cols
if(is_fact_side_left):
self.data_num_rows = res_constraints[-1]._num_rows
self.data_num_cols = fact_constraints[0]._num_cols
else:
self.data_num_rows = constraints[0]._num_rows
self.data_num_cols = constraints[-1]._num_cols
def is_mat_consistent(self, M):
if(not isinstance(M, np.ndarray)):
raise ValueError("M must be a numpy ndarray")
return M.shape[0] == self.data_num_rows and \
M.shape[1] == self.data_num_cols
class ParamsHierarchicalFactHadamard(ParamsHierarchicalFact):
class ParamsHierarchicalFactSquareMat(ParamsHierarchicalFact):
def __init__(self, n):
d = 2**int(n)
stop_crit = StoppingCriterion(num_its=30)
super(ParamsHierarchicalFactHadamard, self).__init__([ConstraintInt(ConstraintName(ConstraintName.SPLINCOL),d,d,2)
super(ParamsHierarchicalFactSquareMat, self).__init__([ConstraintInt(ConstraintName(ConstraintName.SPLINCOL),d,d,2)
for i in range(0,n-1)],
[ConstraintInt(ConstraintName(ConstraintName.SPLINCOL),d,d,int(d/2.**(i+1)))
for i in range(0,n-1)],
......@@ -282,6 +297,35 @@ class ParamsHierarchicalFactHadamard(ParamsHierarchicalFact):
is_update_way_R2L=True)
class ParamsHierarchicalFactRectMat(ParamsHierarchicalFact):
DEFAULT_P_CONST_FACT = 1.4
def __init__(self, m, n, j, k, s, rho=0.8, P=None):
#TODO: test args
from math import ceil
if(not P):
P=ParamsHierarchicalFactRectMat.DEFAULT_P_CONST_FACT*m**2
S1_cons = ConstraintInt('spcol', m, n, k)
S_cons = [S1_cons];
for i in range(j-2):
S_cons += [ ConstraintInt('sp', m, m, s*m) ]
R_cons = []
for i in range(j-1):
R_cons += [ConstraintInt('sp', m, m, ceil(P*rho**i))]
stop_crit = StoppingCriterion(num_its=30)
super(ParamsHierarchicalFactRectMat, self).__init__(S_cons, R_cons,
stop_crit,
stop_crit,
is_update_way_R2L=True,
is_fact_side_left=True)
class ParamsPalm4MSA(ParamsFact):
def __init__(self, constraints, stop_crit, init_facts=None,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment