// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_MATCOM #define tools_MATCOM #include "../eqT" #include //size_t // common code to class mat and nmat. #define TOOLS_MATCOM \ protected:\ static T zero() {return T();}\ static T one() {return T(1);}\ static T minus_one() {return T(-1);}\ static T two() {return T(2);}\ public:\ typedef T elem_t;\ typedef unsigned int size_type;\ public:\ unsigned int rows() const {return dimension();}\ unsigned int cols() const {return dimension();}\ \ void set_value(unsigned int aR,unsigned int aC,const T& a_value) { \ m_vec[aR + aC * dimension()] = a_value;\ }\ \ const T& value(unsigned int aR,unsigned int aC) const { \ return m_vec[aR + aC * dimension()];\ }\ \ T value(unsigned int aR,unsigned int aC) { \ return m_vec[aR + aC * dimension()];\ }\ \ void set_matrix(const TOOLS_MAT_CLASS& a_m){ /*optimization.*/\ _copy(a_m.m_vec);\ }\ \ void set_constant(const T& a_v){\ for(unsigned int i=0;i\ void set_random(RANDOM& a_random) {\ for(unsigned int i=0;i\ void set_symmetric_random(RANDOM& a_random) {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) set_value(r,r,a_random.shoot());}\ T rd;\ {for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ rd = a_random.shoot();\ set_value(r,c,rd);\ set_value(c,r,rd);\ }\ }}\ }\ template \ void set_antisymmetric_random(RANDOM& a_random) {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) set_value(r,r,zero());}\ T rd;\ {for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ rd = a_random.shoot();\ set_value(r,c,rd);\ set_value(c,r,minus_one()*rd);\ }\ }}\ }\ public:\ template \ bool mul_array(ARRAY& a_array,T a_tmp[]) const {\ /* a_array = this *= a_array */\ unsigned int _dim = dimension();\ T* pos = a_tmp;\ for(unsigned int r=0;r<_dim;r++,pos++) {\ *pos = T();\ for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_array[c];\ }\ {for(unsigned int i=0;i<_dim;i++) a_array[i] = a_tmp[i];}\ return true;\ }\ template \ bool mul_vec(VEC& a_vec,T a_tmp[]) const {\ /* a_vec = this *= a_vec */\ unsigned int _dim = dimension();\ if(a_vec.dimension()!=_dim) return false;\ T* pos = a_tmp;\ for(unsigned int r=0;r<_dim;r++,pos++) {\ *pos = T();\ for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_vec[c];\ }\ {for(unsigned int i=0;i<_dim;i++) a_vec[i] = a_tmp[i];}\ return true;\ }\ template \ bool mul_vec(VEC& a_vec) const {\ T* _tmp = new T[dimension()];\ bool status = mul_vec(a_vec,_tmp);\ delete [] _tmp;\ return status;\ }\ \ bool mul_array(T a_vec[],T a_tmp[]) const {\ /* a_vec = this *= a_vec */\ unsigned int _dim = dimension();\ T* pos = a_tmp;\ for(unsigned int r=0;r<_dim;r++,pos++) {\ *pos = T();\ for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_vec[c];\ }\ {for(unsigned int i=0;i<_dim;i++) a_vec[i] = a_tmp[i];}\ return true;\ }\ bool mul_array(T a_vec[]) const {\ T* _tmp = new T[dimension()];\ bool status = mul_array(a_vec,_tmp);\ delete [] _tmp;\ return status;\ }\ \ void mul_mtx(const TOOLS_MAT_CLASS& a_m) {\ _mul_mtx(a_m.m_vec);\ }\ void mul_mtx(const TOOLS_MAT_CLASS& a_m,T a_tmp[]) {\ _mul_mtx(a_m.m_vec,a_tmp);\ }\ void left_mul_mtx(const TOOLS_MAT_CLASS& a_m) { \ /* this = a_m * this :*/\ _left_mul_mtx(a_m.m_vec);\ }\ bool equal(const TOOLS_MAT_CLASS& a_m) const {\ if(&a_m==this) return true;\ for(unsigned int i=0;i=a_prec) return false;\ }\ return true;\ }\ \ template \ bool equal_prec(const TOOLS_MAT_CLASS& a_m,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ if(&a_m==this) return true;\ T* tp = (T*)m_vec;\ T* mp = (T*)a_m.m_vec;\ for(unsigned int i=0;i=a_prec) return false;\ }\ return true;\ }\ \ void mx_diff(const TOOLS_MAT_CLASS& a_m,T& a_mx_diff) const {\ T* tp = (T*)m_vec;\ T* mp = (T*)a_m.m_vec;\ a_mx_diff = (*tp) - (*mp);\ if(a_mx_diffa_mx_diff?diff:a_mx_diff);\ }\ }\ \ bool to_rm_is_proportional(const TOOLS_MAT_CLASS& a_m,const T& a_prec,T& a_factor) const {\ if(&a_m==this) {a_factor=one();return true;}\ /* If true, then : a_m = a_factor * this.*/\ a_factor = zero();\ T* tp = (T*)m_vec;\ T* mp = (T*)a_m.m_vec;\ bool first = true;\ for(unsigned int i=0;i=a_prec) return false;\ }\ }\ }\ return true;\ }\ \ public:\ bool is_proportional(const TOOLS_MAT_CLASS& a_right,T& a_factor) const {\ /* If true, then : a_right = a_factor * this. a_factor could be zero.*/\ if(this==&a_right) {a_factor=T(1);return true;}\ a_factor = zero();\ if(dimension()!=a_right.dimension()) return false;\ T* lp = (T*)m_vec;\ T* rp = (T*)a_right.m_vec;\ bool first = true;\ size_t _data_size = data_size();\ for(size_t i=0;i<_data_size;i++,lp++,rp++) {\ if(*lp==zero()) {\ if(*rp==zero()) continue;\ return false;\ }\ if(first) {\ a_factor = (*rp)/(*lp);\ first = false;\ continue;\ }\ if((*lp)*a_factor!=(*rp)) return false;\ }\ return true;\ }\ \ template \ bool is_proportional_prec(const TOOLS_MAT_CLASS& a_right,const PREC& a_prec,PREC(*a_fabs)(const T&),T& a_factor) const {\ /* If true, then : a_right = a_factor * this. a_factor could be zero.*/\ if(this==&a_right) {a_factor=T(1);return true;}\ a_factor = zero();\ if(dimension()!=a_right.dimension()) return false;\ T* lp = (T*)m_vec;\ T* rp = (T*)a_right.m_vec;\ bool first = true;\ size_t _data_size = data_size();\ for(size_t i=0;i<_data_size;i++,lp++,rp++) {\ if(is_zero(*lp,a_prec,a_fabs)) {\ if(is_zero(*rp,a_prec,a_fabs)) continue;\ return false;\ }\ if(first) {\ a_factor = (*rp)/(*lp);\ first = false;\ continue;\ }\ if(!numbers_are_equal((*lp)*a_factor,*rp,a_prec,a_fabs)) return false;\ }\ return true;\ }\ \ bool is_diagonal() const {\ unsigned int _D = dimension();\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=0;c<_D;c++) {\ if(c!=r) {if(value(r,c)!=zero()) return false;}\ }\ }\ return true;\ }\ \ template \ bool is_diagonal_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int _D = dimension();\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=0;c<_D;c++) {\ if(c!=r) {if(!is_zero(value(r,c),a_prec,a_fabs)) return false;}\ }\ }\ return true;\ }\ \ bool is_identity() const {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) {\ if(value(r,r)!=one()) return false;\ }}\ {for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=0;c<_D;c++) {\ if(c!=r) {if(value(r,c)!=zero()) return false;}\ }\ }}\ return true;\ }\ \ template \ bool is_identity_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) {\ if(!numbers_are_equal(value(r,r),one(),a_prec,a_fabs)) return false;\ }}\ {for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=0;c<_D;c++) {\ if(c!=r) {if(!is_zero(value(r,c),a_prec,a_fabs)) return false;}\ }\ }}\ return true;\ }\ \ const T* data() const {return m_vec;}\ unsigned int size() const {return dim2();}\ unsigned int data_size() const {return dim2();} /*for mathz*/\ \ T trace() const {\ T _value = zero();\ unsigned int _D = dimension();\ for(unsigned int c=0;c<_D;c++) _value += m_vec[c+c*_D];\ return _value;\ }\ \ void transpose() {\ unsigned int _D = dimension();\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ T vrc = value(r,c);\ T vcr = value(c,r);\ set_value(r,c,vcr);\ set_value(c,r,vrc);\ }\ }\ }\ \ void multiply(const T& a_T) {\ for(unsigned int i=0;i\ bool is_symmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int _D = dimension();\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ T diff = value(r,c)-value(c,r);\ if(a_fabs(diff)>=a_prec) return false;\ }\ }\ return true;\ }\ \ bool is_antisymmetric() const {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) {\ if(value(r,r)!=zero()) return false;\ }}\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ if(value(r,c)!=minus_one()*value(c,r)) return false;\ }\ }\ return true;\ }\ \ template \ bool is_antisymmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int _D = dimension();\ {for(unsigned int r=0;r<_D;r++) {\ if(a_fabs(value(r,r))>=a_prec) return false;\ }}\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=(r+1);c<_D;c++) {\ T diff = value(r,c)-minus_one()*value(c,r);\ if(a_fabs(diff)>=a_prec) return false;\ }\ }\ return true;\ }\ \ void symmetric_part(TOOLS_MAT_CLASS& a_res) const {\ a_res = *this;\ a_res.transpose();\ a_res += *this;\ a_res.multiply(one()/two());\ }\ \ void antisymmetric_part(TOOLS_MAT_CLASS& a_res) const {\ a_res = *this;\ a_res.transpose();\ a_res.multiply(minus_one());\ a_res += *this;\ a_res.multiply(one()/two());\ }\ \ template \ bool is_block_UL_DR(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ /* Look if even dim matrix is of the form : |X 0|\ |0 Y|*/\ unsigned int _D = dimension();\ unsigned int _D_2 = _D/2;\ if(2*_D_2!=_D) return false;\ for(unsigned int r=0;r<_D_2;r++) {\ for(unsigned int c=_D_2;c<_D;c++) {\ if(a_fabs(value(r,c))>=a_prec) return false;\ }\ }\ for(unsigned int r=_D_2;r<_D;r++) {\ for(unsigned int c=0;c<_D_2;c++) {\ if(a_fabs(value(r,c))>=a_prec) return false;\ }\ }\ return true;\ }\ \ template \ bool is_block_UR_DL(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ /* Look if even dim matrix is of the form : |0 X|\ |Y 0|*/\ unsigned int _D = dimension();\ unsigned int _D_2 = _D/2;\ if(2*_D_2!=_D) return false;\ for(unsigned int r=0;r<_D_2;r++) {\ for(unsigned int c=0;c<_D_2;c++) {\ if(a_fabs(value(r,c))>=a_prec) return false;\ }\ }\ for(unsigned int r=_D_2;r<_D;r++) {\ for(unsigned int c=_D_2;c<_D;c++) {\ if(a_fabs(value(r,c))>=a_prec) return false;\ }\ }\ return true;\ }\ \ template \ bool is_decomplex(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ /* Look if even dim matrix is of the form : | X Y|\ |-Y X|*/\ unsigned int _D = dimension();\ unsigned int _D_2 = _D/2;\ if(2*_D_2!=_D) return false;\ for(unsigned int r=0;r<_D_2;r++) {\ for(unsigned int c=0;c<_D_2;c++) {\ if(a_fabs(value(r,c)-value(r+_D_2,c+_D_2))>=a_prec) return false;\ }\ }\ for(unsigned int r=0;r<_D_2;r++) {\ for(unsigned int c=_D_2;c<_D;c++) {\ if(a_fabs(value(r,c)+value(r+_D_2,c-_D_2))>=a_prec) return false;\ }\ }\ return true;\ }\ \ template \ T determinant_prec(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[], /*[rord=dim-1]*/\ const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int ord = dimension();\ if(ord==0) {\ return zero();\ } else if(ord==1) {\ return *m_vec;\ } else if(ord==2) {\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v01 = *(m_vec+2);\ T v11 = *(m_vec+3);\ return (v00 * v11 - v10 * v01);\ } else if(ord==3) {\ /* 00 01 02 \ 10 11 12 \ 20 21 22 \ */\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v20 = *(m_vec+2);\ T v01 = *(m_vec+3);\ T v11 = *(m_vec+4);\ T v21 = *(m_vec+5);\ T v02 = *(m_vec+6);\ T v12 = *(m_vec+7);\ T v22 = *(m_vec+8);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ return (v00*cof_00-v10*cof_10+v20*cof_20);\ }\ \ unsigned int rord = ord-1;\ \ T v_rc;\ \ T det = zero();\ {for(unsigned int i=0;i=1) a_tmp_rs[r-1] = r-1;\ v_rc = value(r,c);\ if(!is_zero(v_rc,a_prec,a_fabs)) {\ T subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\ if(sg) \ det += v_rc * subdet;\ else\ det -= v_rc * subdet;\ }\ sg = sg?false:true;\ }\ \ return det;\ }\ \ T determinant(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \ return determinant_prec(a_tmp_rs,a_tmp_cs,0,zero_fabs);\ }\ \ T determinant() const {\ unsigned int ord = dimension();\ if(ord==0) {\ return zero();\ } else if(ord==1) {\ return *m_vec;\ } else if(ord==2) {\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v01 = *(m_vec+2);\ T v11 = *(m_vec+3);\ return (v00 * v11 - v10 * v01);\ } else if(ord==3) {\ /* 00 01 02 \ 10 11 12 \ 20 21 22 \ */\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v20 = *(m_vec+2);\ T v01 = *(m_vec+3);\ T v11 = *(m_vec+4);\ T v21 = *(m_vec+5);\ T v02 = *(m_vec+6);\ T v12 = *(m_vec+7);\ T v22 = *(m_vec+8);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ return (v00*cof_00-v10*cof_10+v20*cof_20);\ }\ unsigned int rord = ord-1;\ unsigned int* rs = new unsigned int[rord];\ unsigned int* cs = new unsigned int[rord];\ T det = determinant(rs,cs);\ delete [] rs;\ delete [] cs;\ return det;\ }\ \ template \ bool invert_prec(TOOLS_MAT_CLASS& a_res,\ unsigned int a_tmp_rs[],unsigned int a_tmp_cs[], /*[rord=dim-1]*/\ const PREC& a_prec,PREC(*a_fabs)(const T&) /*for det=?zero*/ \ ) const { \ unsigned int ord = dimension();\ if(ord==0) return true;\ \ if(ord==1) {\ T det = value(0,0);\ if(is_zero(det,a_prec,a_fabs)) return false;\ a_res.set_value(0,0,one()/det);\ return true;\ } else if(ord==2) {\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v01 = *(m_vec+2);\ T v11 = *(m_vec+3);\ T det = (v00 * v11 - v10 * v01);\ if(is_zero(det,a_prec,a_fabs)) return false;\ a_res.set_value(0,0,v11/det);\ a_res.set_value(1,1,v00/det);\ a_res.set_value(0,1,minus_one()*v01/det);\ a_res.set_value(1,0,minus_one()*v10/det);\ return true;\ } else if(ord==3) {\ /* 00 01 02 \ 10 11 12 \ 20 21 22 \ */\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v20 = *(m_vec+2);\ T v01 = *(m_vec+3);\ T v11 = *(m_vec+4);\ T v21 = *(m_vec+5);\ T v02 = *(m_vec+6);\ T v12 = *(m_vec+7);\ T v22 = *(m_vec+8);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ T det = (v00*cof_00-v10*cof_10+v20*cof_20);\ if(is_zero(det,a_prec,a_fabs)) return false;\ T cof_01 = v10 * v22 - v20 * v12;\ T cof_11 = v00 * v22 - v20 * v02;\ T cof_21 = v00 * v12 - v10 * v02;\ T cof_02 = v10 * v21 - v20 * v11;\ T cof_12 = v00 * v21 - v20 * v01;\ T cof_22 = v00 * v11 - v10 * v01;\ a_res.set_value(0,0,cof_00/det);\ a_res.set_value(1,0,minus_one()*cof_01/det);\ a_res.set_value(2,0,cof_02/det);\ a_res.set_value(0,1,minus_one()*cof_10/det);\ a_res.set_value(1,1,cof_11/det);\ a_res.set_value(2,1,minus_one()*cof_12/det);\ a_res.set_value(0,2,cof_20/det);\ a_res.set_value(1,2,minus_one()*cof_21/det);\ a_res.set_value(2,2,cof_22/det);\ return true;\ }\ \ /*Generic invertion method.*/\ \ unsigned int rord = ord-1;\ \ /* Get det with r = 0;*/\ T det = zero();\ T subdet;\ {\ {for(unsigned int i=0;i=1) a_tmp_cs[c-1] = c-1;\ subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\ if(sg) {\ det += value(r,c) * subdet;\ a_res.set_value(c,r,subdet);\ sg = false;\ } else {\ det += value(r,c) * subdet * minus_one();\ a_res.set_value(c,r,subdet * minus_one());\ sg = true;\ }\ }}\ \ if(is_zero(det,a_prec,a_fabs)) return false;\ \ {for(unsigned int c=0;c=1) a_tmp_rs[r-1] = r-1;\ {for(unsigned int i=0;i=1) a_tmp_cs[c-1] = c-1;\ subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\ if(sg) {\ a_res.set_value(c,r,subdet/det);\ sg = false;\ } else {\ a_res.set_value(c,r,(subdet * minus_one())/det);\ sg = true;\ }\ }\ sgr = sgr?false:true;\ }\ \ return true;\ }\ \ template \ bool invert_prec(TOOLS_MAT_CLASS& a_res,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ unsigned int ord = dimension();\ if(ord==0) return true;\ \ if(ord==1) {\ T det = value(0,0);\ if(is_zero(det,a_prec,a_fabs)) return false;\ a_res.set_value(0,0,one()/det);\ return true;\ } else if(ord==2) {\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v01 = *(m_vec+2);\ T v11 = *(m_vec+3);\ T det = (v00 * v11 - v10 * v01);\ if(is_zero(det,a_prec,a_fabs)) return false;\ a_res.set_value(0,0,v11/det);\ a_res.set_value(1,1,v00/det);\ a_res.set_value(0,1,minus_one()*v01/det);\ a_res.set_value(1,0,minus_one()*v10/det);\ return true;\ } else if(ord==3) {\ /* 00 01 02 \ 10 11 12 \ 20 21 22 \ */\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v20 = *(m_vec+2);\ T v01 = *(m_vec+3);\ T v11 = *(m_vec+4);\ T v21 = *(m_vec+5);\ T v02 = *(m_vec+6);\ T v12 = *(m_vec+7);\ T v22 = *(m_vec+8);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ T det = (v00*cof_00-v10*cof_10+v20*cof_20);\ if(is_zero(det,a_prec,a_fabs)) return false;\ T cof_01 = v10 * v22 - v20 * v12;\ T cof_11 = v00 * v22 - v20 * v02;\ T cof_21 = v00 * v12 - v10 * v02;\ T cof_02 = v10 * v21 - v20 * v11;\ T cof_12 = v00 * v21 - v20 * v01;\ T cof_22 = v00 * v11 - v10 * v01;\ a_res.set_value(0,0,cof_00/det);\ a_res.set_value(1,0,minus_one()*cof_01/det);\ a_res.set_value(2,0,cof_02/det);\ a_res.set_value(0,1,minus_one()*cof_10/det);\ a_res.set_value(1,1,cof_11/det);\ a_res.set_value(2,1,minus_one()*cof_12/det);\ a_res.set_value(0,2,cof_20/det);\ a_res.set_value(1,2,minus_one()*cof_21/det);\ a_res.set_value(2,2,cof_22/det);\ return true;\ }\ \ unsigned int rord = ord-1;\ unsigned int* cs = new unsigned int[rord];\ unsigned int* rs = new unsigned int[rord];\ bool status = invert_prec(a_res,rs,cs,a_prec,a_fabs);\ delete [] cs;\ delete [] rs;\ return status;\ }\ \ bool invert(TOOLS_MAT_CLASS& a_res,unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \ return invert_prec(a_res,a_tmp_rs,a_tmp_cs,0,zero_fabs);\ }\ \ bool invert(TOOLS_MAT_CLASS& a_res) const {\ return invert_prec(a_res,0,zero_fabs);\ }\ \ void power(unsigned int a_n,TOOLS_MAT_CLASS& a_res) const {\ a_res.set_identity();\ T* _tmp = new T[dim2()];\ for(unsigned int i=0;i\ bool copy(const MAT& a_from) {\ /*for exa from a double matrix to a symbol matrix*/\ unsigned int _D = dimension();\ if(a_from.dimension()!=_D) return false;\ for(unsigned int r=0;r<_D;r++) {\ for(unsigned int c=0;c<_D;c++) {\ set_value(r,c,a_from.value(r,c));\ }\ }\ return true;\ }\ public: /*operators*/\ T operator()(unsigned int a_r,unsigned int a_c) const {\ /*WARNING : no check on a_r,a_c.*/\ return m_vec[a_r + a_c * dimension()];\ }\ \ T& operator[](size_t a_index) { /*for tools/sg/sf_vec*/\ /*WARNING : no check on a_index.*/\ return m_vec[a_index];\ }\ const T& operator[](size_t a_index) const {\ /*WARNING : no check on a_index.*/\ return m_vec[a_index];\ }\ bool operator==(const TOOLS_MAT_CLASS& a_array) const {\ return equal(a_array);\ }\ bool operator!=(const TOOLS_MAT_CLASS& a_array) const {\ return !operator==(a_array);\ }\ TOOLS_MAT_CLASS& operator*=(const TOOLS_MAT_CLASS& a_m) {\ _mul_mtx(a_m.m_vec);\ return *this;\ }\ TOOLS_MAT_CLASS& operator+=(const TOOLS_MAT_CLASS& a_m) {\ _add_mtx(a_m.m_vec);\ return *this;\ }\ TOOLS_MAT_CLASS& operator-=(const TOOLS_MAT_CLASS& a_m) {\ _sub_mtx(a_m.m_vec);\ return *this;\ }\ TOOLS_MAT_CLASS& operator*=(const T& a_fac) {\ for(unsigned int i=0;i\ T sub_determinant_prec(unsigned int a_ord,unsigned int aRs[],unsigned int aCs[],\ const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\ /*WARNING : to optimize, we do not check the content of aRs, aCs.*/\ unsigned int ord = a_ord;\ if(ord==0) return zero();\ else if(ord==1) return value(aRs[0],aCs[0]);\ else if(ord==2) {\ /*return (value(aRs[0],aCs[0]) * value(aRs[1],aCs[1]) -\ value(aRs[1],aCs[0]) * value(aRs[0],aCs[1])); \ Optimize the upper :*/\ \ unsigned int _ord = dimension();\ \ return ( (*(m_vec+aRs[0]+aCs[0]*_ord)) * (*(m_vec+aRs[1]+aCs[1]*_ord)) -\ (*(m_vec+aRs[1]+aCs[0]*_ord)) * (*(m_vec+aRs[0]+aCs[1]*_ord)) );\ \ } else if(ord==3) {\ /* 00 01 02 \ 10 11 12 \ 20 21 22 \ */\ unsigned int _ord = dimension();\ \ T v00 = *(m_vec+aRs[0]+aCs[0]*_ord);\ T v10 = *(m_vec+aRs[1]+aCs[0]*_ord);\ T v20 = *(m_vec+aRs[2]+aCs[0]*_ord);\ T v01 = *(m_vec+aRs[0]+aCs[1]*_ord);\ T v11 = *(m_vec+aRs[1]+aCs[1]*_ord);\ T v21 = *(m_vec+aRs[2]+aCs[1]*_ord);\ T v02 = *(m_vec+aRs[0]+aCs[2]*_ord);\ T v12 = *(m_vec+aRs[1]+aCs[2]*_ord);\ T v22 = *(m_vec+aRs[2]+aCs[2]*_ord);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ return (v00*cof_00-v10*cof_10+v20*cof_20);\ }\ \ unsigned int rord = ord-1;\ unsigned int* cs = new unsigned int[rord];\ unsigned int* rs = new unsigned int[rord];\ \ T v_rc;\ \ T det = zero();\ {for(unsigned int i=0;i=1) cs[c-1] = c-1;*/\ \ {for(unsigned int i=0;i=1) rs[r-1] = aRs[r-1];\ v_rc = value(aRs[r],aCs[c]);\ if(!is_zero(v_rc,a_prec,a_fabs)) {\ T subdet = sub_determinant_prec(rord,rs,cs,a_prec,a_fabs);\ if(sg)\ det += v_rc * subdet;\ else\ det -= v_rc * subdet;\ }\ sg = sg?false:true;\ }\ \ delete [] cs;\ delete [] rs;\ \ return det;\ }\ \ static double zero_fabs(const T& a_number) {return a_number==zero()?0:1000000;} #endif