1#ifndef FSTINDEXEDMATRIX_H
2#define FSTINDEXEDMATRIX_H
91template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
94template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
97template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
101template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
102class Indexed_Matrix {
110 void reset(
const DIMTYPE n_max,
bool LUstorage=
false);
111 void redim(
const DIMTYPE n=0);
113 DATATYPE&
at_raw(
const DIMTYPE row,
const DIMTYPE col) {assert(row<
_n); assert(col<
_n); assert(
_data);
return _data[(std::size_t)row*
_n+col];}
175 friend std::ostream& operator<< <>(std::ostream& os,
const Indexed_Matrix& mr);
203template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
204Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET>::Indexed_Matrix(
const Indexed_Matrix& im) :
210 notify(
"Indexed_Matrix copy-constructor.");
223template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
226 notify(
"Indexed_Matrix operator=.");
271template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
274 notify(
"Indexed_Matrix reset.");
291 else if(LUstorage && !
_permut) {
304template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
307 notify(
"Indexed_Matrix redim.");
312 for(DIMTYPE i=0;i<
_n;i++)
_index[i]=i;
318template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
321 assert(
_n>=sub->get_d_raw());
324 for(DIMTYPE f : sub->selected_features())
_index[
_d++]=f;
328template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
332 for(DIMTYPE i=0;i<
_n;i++)
_index[i]=i;
336template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
340 for(std::size_t i=0;i<(std::size_t)
_n*
_n;i++)
_data[i]=val;
343template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
349 for(std::size_t i=0;i<(std::size_t)
_n*
_n;i++)
_data[i]+=mr.
_data[i];
352template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
358 for(std::size_t i=0;i<(std::size_t)
_n*
_n;i++)
_data[i]+=mul * mr.
_data[i];
361template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
367 for(std::size_t i=0;i<(std::size_t)
_n*
_n;i++)
_data[i]=mul * mr.
_data[i];
370template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
376 for(std::size_t i=0;i<(std::size_t)
_n*
_n;i++)
_data[i]=mr.
_data[i];
379template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
397 notify(
"Indexed_Matrix::LUdecompose");
398 assert(result.
_n==
_d);
399 assert(result.
_data);
414 for(DIMTYPE i1=0;i1<
_d;i1++) {
415 for(DIMTYPE i2=0;i2<
_d;i2++) {
416 assert(pROW+i2<(std::size_t)
_d*
_d);
431 DIMTYPE j,i1,i2,tmpi;
432 std::size_t pROW,pROWK,pCOL;
436 for(i1=0;i1<
_d;i1++) {
437 for(i2=0;i2<
_d;i2++) {
438 assert(pROW+i2<(std::size_t)
_d*
_d);
456 for(j=0;j<
_d;j++) {assert(pROW+j<(std::size_t)
_d*
_d);
if((pom=fabs(result.
_data[pROW+j]))>max) max=pom;}
461 if(max<std::numeric_limits<DATATYPE>::min())
throw fst_error(
"Indexed_Matrix::LUdecompose() value too small/matrix singular or near-singular",23);
474 assert(pROW+j<(std::size_t)
_d*
_d);
475 sum=result.
_data[pROW+j];
480 assert(pROW+i2<(std::size_t)
_d*
_d);
481 assert(pROWK+j<(std::size_t)
_d*
_d);
482 sum-=result.
_data[pROW+i2]*result.
_data[pROWK+j];
484 result.
_data[pROW+j]=sum;
495 assert(pROW+j<(std::size_t)
_d*
_d);
496 sum=result.
_data[pROW+j];
501 assert(pROW+i2<(std::size_t)
_d*
_d);
502 assert(pROWK+j<(std::size_t)
_d*
_d);
503 sum-=result.
_data[pROW+i2]*result.
_data[pROWK+j];
505 result.
_data[pROW+j]=sum;
507 if(pom>max) {max=pom; idxmax=i1;}
545 assert(pCOL+j<(std::size_t)
_d*
_d);
553 if(fabs(result.
_data[pCOL+j])<=std::numeric_limits<DATATYPE>::min()) {
554 if(result.
_data[pCOL+j]<0.0) pom=-std::numeric_limits<DATATYPE>::max();
555 else pom=std::numeric_limits<DATATYPE>::max();
556 notify(
"NOTE: division by too small a number - result set to maximum representable number.");
558 pom=1.0/result.
_data[pCOL+j];
560 for(i1=j+1;i1<
_d;i1++)
563 assert(pROW+j<(std::size_t)
_d*
_d);
564 result.
_data[pROW+j] *= pom;
571template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
572void Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET>::solve_equations(
Indexed_Vector<DATATYPE,DIMTYPE,SUBSET> &result_vec,
const Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET> &LU_matrix,
Indexed_Vector<DATATYPE,DIMTYPE,SUBSET> &coef_vec)
576 notify(
"Indexed_Matrix::solve_equations");
577 assert(result_vec.
_data);
578 assert(result_vec.
_n>=
_d);
579 assert(coef_vec.
_data);
580 assert(coef_vec.
_n>=
_d);
581 assert(LU_matrix.
_n==
_d);
587 typedef Eigen::Matrix<DATATYPE,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> FST_EMat;
588 typedef Eigen::Matrix<DATATYPE,Eigen::Dynamic,1> FST_EVec;
589 Eigen::Map<const FST_EMat> A_e(LU_matrix.
_data.get(),(Eigen::Index)
_d,(Eigen::Index)
_d);
590 Eigen::Map<const FST_EVec> b_e(coef_vec.
_data.get(),(Eigen::Index)
_d);
591 Eigen::Map<FST_EVec> x_e(result_vec.
_data.get(),(Eigen::Index)
_d);
592 x_e=Eigen::PartialPivLU<FST_EMat>(A_e).solve(b_e);
607 assert(pROW+j<(std::size_t)
_d*
_d);
608 sum+=LU_matrix.
_data[pROW+j]*result_vec[j];
617 assert(pROW+i-1<(std::size_t)
_d*
_d);
619 for(j=i;j<
_d;j++) sum+=LU_matrix.
_data[pROW+j]*result_vec[j];
620 if(fabs(LU_matrix.
_data[pROW+i-1])<=std::numeric_limits<DATATYPE>::min()) {
621 if(LU_matrix.
_data[pROW+i-1]*(result_vec[i-1]-sum)<0.0) result_vec[i-1]=-std::numeric_limits<DATATYPE>::max();
622 else result_vec[i-1]=std::numeric_limits<DATATYPE>::max();
623 notify(
"NOTE: division by too small number - result set to maximum representable number.");
625 result_vec[i-1]=(result_vec[i-1]-sum)/LU_matrix.
_data[pROW+i-1];
631template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
636 notify(
"Indexed_Matrix::invert");
637 assert(result.
_data);
638 assert(result.
_n==
_d);
639 assert(LU_Matrix.
_data);
642 assert(LU_Matrix.
_d==
_d);
646 typedef Eigen::Matrix<DATATYPE,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> FST_EMat;
647 Eigen::Map<const FST_EMat> A_e(LU_Matrix.
_data.get(),(Eigen::Index)
_d,(Eigen::Index)
_d);
648 Eigen::Map<FST_EMat> R_e(result.
_data.get(),(Eigen::Index)
_d,(Eigen::Index)
_d);
649 R_e=Eigen::PartialPivLU<FST_EMat>(A_e).inverse();
663 (*_tmp_eq_coefs)[j]=1.0;
670 result.
_data[pROW+j]=(*_tmp_eq_roots)[i];
677template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
681 assert(LU_matrix.
_data);
683 assert(LU_matrix.
_d==
_d);
685 notify(
"Indexed_Matrix::determinant");
688 typedef Eigen::Matrix<DATATYPE,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> FST_EMat;
689 Eigen::Map<const FST_EMat> A_e(LU_matrix.
_data.get(),(Eigen::Index)
_d,(Eigen::Index)
_d);
690 return (DATATYPE)Eigen::PartialPivLU<FST_EMat>(A_e).determinant();
702 assert(pROW<(std::size_t)
_d*
_d);
703 det*=LU_matrix.
_data[pROW];
709template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
716 assert(LU_matrix.
_data);
718 assert(LU_matrix.
_d==
_d);
720 notify(
"Indexed_Matrix::log_determinant");
723 typedef Eigen::Matrix<DATATYPE,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> FST_EMat;
724 Eigen::Map<const FST_EMat> A_e(LU_matrix.
_data.get(),(Eigen::Index)
_d,(Eigen::Index)
_d);
725 Eigen::PartialPivLU<FST_EMat> lu_e(A_e);
727 for(DIMTYPE j=0;j<
_d;j++) logdet+=std::log(std::fabs(lu_e.matrixLU()((Eigen::Index)j,(Eigen::Index)j)));
732 for(DIMTYPE j=0;j<
_d;j++)
735 assert(pROW<(std::size_t)
_d*
_d);
736 logdet+=std::log(std::fabs(LU_matrix.
_data[pROW]));
745template<
typename DATATYPE,
typename DIMTYPE,
class SUBSET>
746std::ostream&
operator<<(std::ostream& os,
const Indexed_Matrix<DATATYPE,DIMTYPE,SUBSET>& mr)
752 os <<
"----------------"<<std::endl;
753 os <<
"Indexed_Matrix::";
754 os <<
"_index: ";
for(DIMTYPE j=0;j<mr.
_d;j++) {os << mr.
_index[j] <<
" ";} os<<std::endl;
755 os <<
"_data (indexed):"<<std::endl;
756 for(DIMTYPE i=0;i<mr.
_d;i++) {
for(DIMTYPE j=0;j<mr.
_d;j++) {os << mr.
_data[(std::size_t)mr.
_index[i]*mr.
_n+mr.
_index[j]] <<
" ";} os << std::endl;}
757 os <<
"----------------"<<std::endl;
Matrix representation and operations, allows operation in selected subspace.
Definition indexed_matrix.hpp:102
void add_constmul_raw(const Indexed_Matrix &mr, const DATATYPE mul)
this += mul * mr, elementwise over the raw get_n()*get_n() entries (requires mr.get_n()==get_n())
Definition indexed_matrix.hpp:353
std::shared_ptr< SUBSET > PSubset
shared pointer to the feature subset consumed by narrow_to()
Definition indexed_matrix.hpp:104
void invert(Indexed_Matrix &result, const Indexed_Matrix &LU_matrix)
Definition indexed_matrix.hpp:632
DIMTYPE _n_max
allocated space can hold _n_max*_n_max matrix
Definition indexed_matrix.hpp:184
void redim(const DIMTYPE n=0)
keeps main allocations, just resets index arrays and adjusts _n; n==0 here equals _n_max
Definition indexed_matrix.hpp:305
void denarrow()
reset _index[] -> access is reset to the full matrix
Definition indexed_matrix.hpp:329
std::unique_ptr< DIMTYPE[]> _index
maps virtual sub-matrix _d dimensions to original _n dimensions
Definition indexed_matrix.hpp:193
std::unique_ptr< Indexed_Vector< DATATYPE, DIMTYPE, SUBSET > > _tmp_eq_coefs
right-hand side handed to solve_equations() by invert() (allocated on first use)
Definition indexed_matrix.hpp:199
void reset(const DIMTYPE n_max, bool LUstorage=false)
reallocates
Definition indexed_matrix.hpp:272
DATATYPE * get_row(const DIMTYPE row)
pointer to the start of matrix row _index[row] (only the row is subset-mapped – the returned row stil...
Definition indexed_matrix.hpp:116
std::unique_ptr< DIMTYPE[]> _permut
LU row permutation, physical row -> logical row (the inverse of _tmp_whereis); allocated only for an ...
Definition indexed_matrix.hpp:188
std::unique_ptr< DIMTYPE[]> _tmp_whereis
LU row permutation, logical row -> physical row in _data (the map that replaces physical row swapping...
Definition indexed_matrix.hpp:197
DATATYPE & at_raw(const DIMTYPE row, const DIMTYPE col)
raw (unindexed) element access, row and col in [0,get_n())
Definition indexed_matrix.hpp:113
int _sign
sign of the LU row permutation (+1/-1; 0 before any decomposition), the factor determinant() needs
Definition indexed_matrix.hpp:189
std::unique_ptr< DATATYPE[]> _data
raw matrix data, _n_max*_n_max entries, row by row
Definition indexed_matrix.hpp:186
void narrow_to(const PSubset sub)
fill _index[] -> access to data is then mapped to sub-matrix
Definition indexed_matrix.hpp:319
void LUdecompose(Indexed_Matrix &result)
Definition indexed_matrix.hpp:380
std::unique_ptr< Indexed_Vector< DATATYPE, DIMTYPE, SUBSET > > _tmp_eq_roots
solution vector returned by solve_equations() to invert() (allocated on first use)
Definition indexed_matrix.hpp:200
DIMTYPE get_n_max() const
the allocated capacity (max n the matrix can reset()/redim() to without reallocating)
Definition indexed_matrix.hpp:120
void copy_constmul_raw(const Indexed_Matrix &mr, const DATATYPE mul)
this = mul * mr, elementwise over the raw get_n()*get_n() entries (an assignment, not an accumulation...
Definition indexed_matrix.hpp:362
Indexed_Matrix & operator=(Indexed_Matrix const &im)
deep-copy assignment (reallocates only where capacity or LU-storage presence differs from im's)
Definition indexed_matrix.hpp:224
DIMTYPE _d
virtual sub-matrix (as represented by _index) dimensionality
Definition indexed_matrix.hpp:192
DIMTYPE get_d() const
the current virtual (narrow_to()'d) dimensionality, get_d()<=get_n()
Definition indexed_matrix.hpp:122
DATATYPE * get_row_raw(const DIMTYPE row)
pointer to the start of raw row row (unindexed, get_n() entries), row in [0,get_n())
Definition indexed_matrix.hpp:115
std::unique_ptr< DATATYPE[]> _tmp_rowscale
reciprocals of the row maxima (implicit row scaling used for pivot choice); allocated on the first LU...
Definition indexed_matrix.hpp:196
DIMTYPE get_n() const
the full ("raw") dimensionality currently in use, get_n()<=get_n_max()
Definition indexed_matrix.hpp:121
DIMTYPE _n
full feature set dimensionality
Definition indexed_matrix.hpp:185
void add_raw(const Indexed_Matrix &mr)
this += mr, elementwise over the raw get_n()*get_n() entries (requires mr.get_n()==get_n())
Definition indexed_matrix.hpp:344
void solve_equations(Indexed_Vector< DATATYPE, DIMTYPE, SUBSET > &result_vec, const Indexed_Matrix &LU_matrix, Indexed_Vector< DATATYPE, DIMTYPE, SUBSET > &coef_vec)
Definition indexed_matrix.hpp:572
DATATYPE & at(const DIMTYPE row, const DIMTYPE col)
indexed access through the narrow_to() subset map – both row and col are mapped, row/col in [0,...
Definition indexed_matrix.hpp:114
void set_all_raw_to(const DATATYPE val)
sets all get_n()*get_n() raw entries to val (ignores the index map)
Definition indexed_matrix.hpp:337
void copy_raw(const Indexed_Matrix &mr)
this = mr, elementwise over the raw get_n()*get_n() entries (requires mr.get_n()==get_n())
Definition indexed_matrix.hpp:371
DATATYPE determinant(const Indexed_Matrix &LU_matrix)
Definition indexed_matrix.hpp:678
DATATYPE log_determinant(const Indexed_Matrix &LU_matrix)
Definition indexed_matrix.hpp:710
Indexed_Matrix(const DIMTYPE n, bool LUstorage=false)
allocates for an n x n matrix; LUstorage true also allocates the permutation/whereis buffers LUdecomp...
Definition indexed_matrix.hpp:106
Vector representation and operations, allows operation in selected subspace. Also serves as the helpe...
Definition indexed_vector.hpp:100
DIMTYPE _n
full ("raw") dimensionality currently in use, _n<=_n_max; see get_n()
Definition indexed_vector.hpp:143
std::unique_ptr< DATATYPE[]> _data
raw vector data buffer (_n_max entries allocated)
Definition indexed_vector.hpp:144
FST4 specific error passing class.
Definition error.hpp:61
FST4 specific error passing class.
Vector representation and operations, allows operation in selected subspace.
The Feature Selection Toolbox 4 library: every library component – data access, criteria and classifi...
Definition data_accessor.hpp:80
void notify(const std::string msg)
Prints msg followed by a newline via syncout::print(); a no-op unless the preprocessor macro DEBUG is...
Definition global.hpp:112
std::ostream & operator<<(std::ostream &os, const Data_Intervaller< CONTAINER, IDXTYPE > &ia)
Streams every contained interval as "si:<startidx>, c:<count>" lines to os.
Definition data_intervaller.hpp:152