// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_mat #define tools_mat #include "MATCOM" namespace tools { template class mat { static const unsigned int _D2 = D*D; unsigned int dim2() const {return _D2;} #define TOOLS_MAT_CLASS mat TOOLS_MATCOM #undef TOOLS_MAT_CLASS private: public: mat() { #ifdef TOOLS_MAT_NEW m_vec = new T[D*D]; #endif for(unsigned int i=0;i<_D2;i++) m_vec[i] = zero(); } virtual ~mat() { #ifdef TOOLS_MAT_NEW delete [] m_vec; #endif } public: mat(const mat& a_from) { #ifdef TOOLS_MAT_NEW m_vec = new T[D*D]; #endif _copy(a_from.m_vec); } mat& operator=(const mat& a_from){ if(&a_from==this) return *this; _copy(a_from.m_vec); return *this; } public: mat(const T a_v[]){ #ifdef TOOLS_MAT_NEW m_vec = new T[D*D]; #endif _copy(a_v); } public: unsigned int dimension() const {return D;} protected: #ifdef TOOLS_MAT_NEW T* m_vec; #else T m_vec[D*D]; #endif private:static void check_instantiation() {mat dummy;} }; template class nmat { unsigned int dim2() const {return m_D2;} #define TOOLS_MAT_CLASS nmat TOOLS_MATCOM #undef TOOLS_MAT_CLASS private: public: nmat(unsigned int a_D):m_D(a_D),m_D2(a_D*a_D),m_vec(0) { m_vec = new T[m_D2]; for(unsigned int i=0;i dummy(2);} }; template inline nmat copy(const mat& a_from) { unsigned int D2 = D*D; nmat v(D); for(unsigned int i=0;i inline void multiply(VECTOR& a_vec,const typename VECTOR::value_type& a_mat) { typedef typename VECTOR::iterator it_t; for(it_t it=a_vec.begin();it!=a_vec.end();++it) *it *= a_mat; } template inline void multiply(VECTOR& a_vec,const typename VECTOR::value_type::elem_t& a_value) { typedef typename VECTOR::iterator it_t; for(it_t it=a_vec.begin();it!=a_vec.end();++it) (*it).multiply(a_value); } /////////////////////////////////////////////////////////////////////////////////////// /// related to complex numbers : ////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// template inline void conjugate(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) { typedef typename MAT::elem_t T; T* pos = const_cast(a_m.data()); unsigned int D2 = a_m.dimension()*a_m.dimension(); for(unsigned int i=0;i } } template inline bool is_real(MAT& a_m,typename MAT::elem_t::value_type (*a_imag)(const typename MAT::elem_t&)) { typedef typename MAT::elem_t T; T* pos = const_cast(a_m.data()); unsigned int D2 = a_m.dimension()*a_m.dimension(); for(unsigned int i=0;i inline bool is_real_prec(MAT& a_m,typename MAT::elem_t::value_type (*a_imag)(const typename MAT::elem_t&), const PREC& a_prec,PREC(*a_fabs)(const typename MAT::elem_t::value_type&)) {\ typedef typename MAT::elem_t T; T* pos = const_cast(a_m.data()); unsigned int D2 = a_m.dimension()*a_m.dimension(); for(unsigned int i=0;i=a_prec) return false;} return true; } template inline bool is_imag(MAT& a_m,typename MAT::elem_t::value_type (*a_real)(const typename MAT::elem_t&)) { typedef typename MAT::elem_t T; T* pos = const_cast(a_m.data()); unsigned int D2 = a_m.dimension()*a_m.dimension(); for(unsigned int i=0;i inline bool to_real(const CMAT& a_c,RMAT& a_r,typename CMAT::elem_t::value_type (*a_real)(const typename CMAT::elem_t&)) { if(a_r.dimension()!=a_c.dimension()) return false; typedef typename CMAT::elem_t CT; const CT* cpos = a_c.data(); typedef typename RMAT::elem_t RT; RT* rpos = const_cast(a_r.data()); unsigned int D2 = a_c.dimension()*a_c.dimension(); for(unsigned int i=0;i inline bool to_complex(const RMAT& a_r,CMAT& a_c) { if(a_c.dimension()!=a_r.dimension()) return false; typedef typename RMAT::elem_t RT; const RT* rpos = a_r.data(); typedef typename CMAT::elem_t CT; CT* cpos = const_cast(a_c.data()); unsigned int D2 = a_r.dimension()*a_r.dimension(); for(unsigned int i=0;i inline void dagger(MAT& a_m,typename MAT::elem_t (*a_conj)(const typename MAT::elem_t&)) { conjugate(a_m,a_conj); a_m.transpose(); } template inline bool decomplex(const CMAT& a_c,RMAT& a_r, typename CMAT::elem_t::value_type (*a_real)(const typename CMAT::elem_t&), typename CMAT::elem_t::value_type (*a_imag)(const typename CMAT::elem_t&)) { // CMAT = X+iY // RMAT = | X Y | // | -Y X | typedef typename CMAT::elem_t CT; //std::complex typedef typename RMAT::elem_t RT; //double unsigned int cdim = a_c.dimension(); if(a_r.dimension()!=2*cdim) {a_r.set_zero();return false;} RT value;unsigned int r,c; for(r=0;r inline bool decomplex( const VEC_CMAT& a_vc,VEC_RMAT& a_vr ,typename VEC_CMAT::value_type::elem_t::value_type (*a_real)(const typename VEC_CMAT::value_type::elem_t&) ,typename VEC_CMAT::value_type::elem_t::value_type (*a_imag)(const typename VEC_CMAT::value_type::elem_t&) ) { // CMAT = X+iY // RMAT = | X Y | // | -Y X | typedef typename VEC_CMAT::size_type sz_t; sz_t number = a_vc.size(); a_vr.resize(number); for(sz_t index=0;index inline MAT commutator(const MAT& a1,const MAT& a2) { return a1*a2-a2*a1; } template inline MAT anticommutator(const MAT& a1,const MAT& a2) { return a1*a2+a2*a1; } template inline void commutator(const MAT& a1,const MAT& a2,MAT& a_tmp,MAT& a_res) { a_res = a1; a_res *= a2; a_tmp = a2; a_tmp *= a1; a_res -= a_tmp; } template inline void commutator(const MAT& a1,const MAT& a2,MAT& a_tmp,T a_vtmp[],MAT& a_res) { a_res = a1; a_res.mul_mtx(a2,a_vtmp); a_tmp = a2; a_tmp.mul_mtx(a1,a_vtmp); a_res -= a_tmp; } template inline void anticommutator(const MAT& a1,const MAT& a2,MAT& a_tmp,MAT& a_res) { a_res = a1; a_res *= a2; a_tmp = a2; a_tmp *= a1; a_res += a_tmp; } template inline void anticommutator(const MAT& a1,const MAT& a2,MAT& a_tmp,T a_vtmp[],MAT& a_res) { a_res = a1; a_res.mul_mtx(a2,a_vtmp); a_tmp = a2; a_tmp.mul_mtx(a1,a_vtmp); a_res += a_tmp; } template inline bool commutator_equal(const mat& a_1,const mat& a_2,const mat& a_c,const T& a_prec) { unsigned int order = D; const T* p1 = a_1.data(); const T* p2 = a_2.data(); const T* pc = a_c.data(); for(unsigned int r=0;r=a_prec) return false; } } return true; } template inline bool anticommutator_equal(const mat& a_1,const mat& a_2,const mat& a_c,const T& a_prec) { unsigned int order = D; const T* p1 = a_1.data(); const T* p2 = a_2.data(); const T* pc = a_c.data(); for(unsigned int r=0;r=a_prec) return false; } } return true; } template inline mat operator-(const mat& a1,const mat& a2) { mat res(a1); res -= a2; return res; } template inline mat operator+(const mat& a1,const mat& a2) { mat res(a1); res += a2; return res; } template inline mat operator*(const mat& a1,const mat& a2) { mat res(a1); res *= a2; return res; } template inline mat operator*(const T& a_fac,const mat& a_m) { mat res(a_m); res *= a_fac; return res; } template inline nmat operator-(const nmat& a1,const nmat& a2) { nmat res(a1); res -= a2; return res; } template inline nmat operator+(const nmat& a1,const nmat& a2) { nmat res(a1); res += a2; return res; } template inline nmat operator*(const nmat& a1,const nmat& a2) { nmat res(a1); res *= a2; return res; } template inline nmat operator*(const T& a_fac,const nmat& a_m) { nmat res(a_m); res *= a_fac; return res; } template inline bool mat_fabs(const MAT& a_in,MAT& a_ou,REAL(*a_fabs)(const typename MAT::elem_t&)) { if(a_in.dimension()!=a_ou.dimension()) {a_ou.set_zero();return false;} typedef typename MAT::elem_t T; T* in_pos = const_cast(a_in.data()); T* ou_pos = const_cast(a_ou.data()); unsigned int D2 = a_in.dimension()*a_in.dimension(); for(unsigned int i=0;i inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01 ,TOOLS_MELEM a_10,TOOLS_MELEM a_11 ){ //a_ //vec[R + C * 2]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[2] = a_01; vec[1] = a_10;vec[3] = a_11; } //////////////////////////////////////////////// /// specific D=3 /////////////////////////////// //////////////////////////////////////////////// template inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01,TOOLS_MELEM a_02 //1 row ,TOOLS_MELEM a_10,TOOLS_MELEM a_11,TOOLS_MELEM a_12 //2 row ,TOOLS_MELEM a_20,TOOLS_MELEM a_21,TOOLS_MELEM a_22 //3 row ){ //a_ //vec[R + C * 3]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[3] = a_01;vec[6] = a_02; vec[1] = a_10;vec[4] = a_11;vec[7] = a_12; vec[2] = a_20;vec[5] = a_21;vec[8] = a_22; } //////////////////////////////////////////////// /// specific D=4 /////////////////////////////// //////////////////////////////////////////////// template inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01,TOOLS_MELEM a_02,TOOLS_MELEM a_03 //1 row ,TOOLS_MELEM a_10,TOOLS_MELEM a_11,TOOLS_MELEM a_12,TOOLS_MELEM a_13 //2 row ,TOOLS_MELEM a_20,TOOLS_MELEM a_21,TOOLS_MELEM a_22,TOOLS_MELEM a_23 //3 row ,TOOLS_MELEM a_30,TOOLS_MELEM a_31,TOOLS_MELEM a_32,TOOLS_MELEM a_33 //4 row ){ //a_ //vec[R + C * 4]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[4] = a_01;vec[ 8] = a_02;vec[12] = a_03; vec[1] = a_10;vec[5] = a_11;vec[ 9] = a_12;vec[13] = a_13; vec[2] = a_20;vec[6] = a_21;vec[10] = a_22;vec[14] = a_23; vec[3] = a_30;vec[7] = a_31;vec[11] = a_32;vec[15] = a_33; } //////////////////////////////////////////////// /// specific D=5 /////////////////////////////// //////////////////////////////////////////////// template inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01,TOOLS_MELEM a_02,TOOLS_MELEM a_03,TOOLS_MELEM a_04 //1 row ,TOOLS_MELEM a_10,TOOLS_MELEM a_11,TOOLS_MELEM a_12,TOOLS_MELEM a_13,TOOLS_MELEM a_14 //2 row ,TOOLS_MELEM a_20,TOOLS_MELEM a_21,TOOLS_MELEM a_22,TOOLS_MELEM a_23,TOOLS_MELEM a_24 //3 row ,TOOLS_MELEM a_30,TOOLS_MELEM a_31,TOOLS_MELEM a_32,TOOLS_MELEM a_33,TOOLS_MELEM a_34 //4 row ,TOOLS_MELEM a_40,TOOLS_MELEM a_41,TOOLS_MELEM a_42,TOOLS_MELEM a_43,TOOLS_MELEM a_44 //5 row ){ //a_ //vec[R + C * 5]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[5] = a_01;vec[10] = a_02;vec[15] = a_03;vec[20] = a_04; vec[1] = a_10;vec[6] = a_11;vec[11] = a_12;vec[16] = a_13;vec[21] = a_14; vec[2] = a_20;vec[7] = a_21;vec[12] = a_22;vec[17] = a_23;vec[22] = a_24; vec[3] = a_30;vec[8] = a_31;vec[13] = a_32;vec[18] = a_33;vec[23] = a_34; vec[4] = a_40;vec[9] = a_41;vec[14] = a_42;vec[19] = a_43;vec[24] = a_44; } //////////////////////////////////////////////// /// specific D=6 /////////////////////////////// //////////////////////////////////////////////// template inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01,TOOLS_MELEM a_02,TOOLS_MELEM a_03,TOOLS_MELEM a_04,TOOLS_MELEM a_05 //1 row ,TOOLS_MELEM a_10,TOOLS_MELEM a_11,TOOLS_MELEM a_12,TOOLS_MELEM a_13,TOOLS_MELEM a_14,TOOLS_MELEM a_15 //2 row ,TOOLS_MELEM a_20,TOOLS_MELEM a_21,TOOLS_MELEM a_22,TOOLS_MELEM a_23,TOOLS_MELEM a_24,TOOLS_MELEM a_25 //3 row ,TOOLS_MELEM a_30,TOOLS_MELEM a_31,TOOLS_MELEM a_32,TOOLS_MELEM a_33,TOOLS_MELEM a_34,TOOLS_MELEM a_35 //4 row ,TOOLS_MELEM a_40,TOOLS_MELEM a_41,TOOLS_MELEM a_42,TOOLS_MELEM a_43,TOOLS_MELEM a_44,TOOLS_MELEM a_45 //5 row ,TOOLS_MELEM a_50,TOOLS_MELEM a_51,TOOLS_MELEM a_52,TOOLS_MELEM a_53,TOOLS_MELEM a_54,TOOLS_MELEM a_55 //6 row ){ //a_ //vec[R + C * 6]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[ 6] = a_01;vec[12] = a_02;vec[18] = a_03;vec[24] = a_04;vec[30] = a_05; vec[1] = a_10;vec[ 7] = a_11;vec[13] = a_12;vec[19] = a_13;vec[25] = a_14;vec[31] = a_15; vec[2] = a_20;vec[ 8] = a_21;vec[14] = a_22;vec[20] = a_23;vec[26] = a_24;vec[32] = a_25; vec[3] = a_30;vec[ 9] = a_31;vec[15] = a_32;vec[21] = a_33;vec[27] = a_34;vec[33] = a_35; vec[4] = a_40;vec[10] = a_41;vec[16] = a_42;vec[22] = a_43;vec[28] = a_44;vec[34] = a_45; vec[5] = a_50;vec[11] = a_51;vec[17] = a_52;vec[23] = a_53;vec[29] = a_54;vec[35] = a_55; } //////////////////////////////////////////////// /// specific D=10 ////////////////////////////// //////////////////////////////////////////////// template inline void matrix_set(MAT& a_m ,TOOLS_MELEM a_00,TOOLS_MELEM a_01,TOOLS_MELEM a_02,TOOLS_MELEM a_03,TOOLS_MELEM a_04,TOOLS_MELEM a_05,TOOLS_MELEM a_06,TOOLS_MELEM a_07,TOOLS_MELEM a_08,TOOLS_MELEM a_09 //1 row ,TOOLS_MELEM a_10,TOOLS_MELEM a_11,TOOLS_MELEM a_12,TOOLS_MELEM a_13,TOOLS_MELEM a_14,TOOLS_MELEM a_15,TOOLS_MELEM a_16,TOOLS_MELEM a_17,TOOLS_MELEM a_18,TOOLS_MELEM a_19 //2 row ,TOOLS_MELEM a_20,TOOLS_MELEM a_21,TOOLS_MELEM a_22,TOOLS_MELEM a_23,TOOLS_MELEM a_24,TOOLS_MELEM a_25,TOOLS_MELEM a_26,TOOLS_MELEM a_27,TOOLS_MELEM a_28,TOOLS_MELEM a_29 //3 row ,TOOLS_MELEM a_30,TOOLS_MELEM a_31,TOOLS_MELEM a_32,TOOLS_MELEM a_33,TOOLS_MELEM a_34,TOOLS_MELEM a_35,TOOLS_MELEM a_36,TOOLS_MELEM a_37,TOOLS_MELEM a_38,TOOLS_MELEM a_39 //4 row ,TOOLS_MELEM a_40,TOOLS_MELEM a_41,TOOLS_MELEM a_42,TOOLS_MELEM a_43,TOOLS_MELEM a_44,TOOLS_MELEM a_45,TOOLS_MELEM a_46,TOOLS_MELEM a_47,TOOLS_MELEM a_48,TOOLS_MELEM a_49 //5 row ,TOOLS_MELEM a_50,TOOLS_MELEM a_51,TOOLS_MELEM a_52,TOOLS_MELEM a_53,TOOLS_MELEM a_54,TOOLS_MELEM a_55,TOOLS_MELEM a_56,TOOLS_MELEM a_57,TOOLS_MELEM a_58,TOOLS_MELEM a_59 //6 row ,TOOLS_MELEM a_60,TOOLS_MELEM a_61,TOOLS_MELEM a_62,TOOLS_MELEM a_63,TOOLS_MELEM a_64,TOOLS_MELEM a_65,TOOLS_MELEM a_66,TOOLS_MELEM a_67,TOOLS_MELEM a_68,TOOLS_MELEM a_69 //7 row ,TOOLS_MELEM a_70,TOOLS_MELEM a_71,TOOLS_MELEM a_72,TOOLS_MELEM a_73,TOOLS_MELEM a_74,TOOLS_MELEM a_75,TOOLS_MELEM a_76,TOOLS_MELEM a_77,TOOLS_MELEM a_78,TOOLS_MELEM a_79 //8 row ,TOOLS_MELEM a_80,TOOLS_MELEM a_81,TOOLS_MELEM a_82,TOOLS_MELEM a_83,TOOLS_MELEM a_84,TOOLS_MELEM a_85,TOOLS_MELEM a_86,TOOLS_MELEM a_87,TOOLS_MELEM a_88,TOOLS_MELEM a_89 //9 row ,TOOLS_MELEM a_90,TOOLS_MELEM a_91,TOOLS_MELEM a_92,TOOLS_MELEM a_93,TOOLS_MELEM a_94,TOOLS_MELEM a_95,TOOLS_MELEM a_96,TOOLS_MELEM a_97,TOOLS_MELEM a_98,TOOLS_MELEM a_99 //10 row ){ //a_ //vec[R + C * 10]; typename MAT::elem_t* vec = const_cast(a_m.data()); vec[0] = a_00;vec[10] = a_01;vec[20] = a_02;vec[30] = a_03;vec[40] = a_04;vec[50] = a_05;vec[60] = a_06;vec[70] = a_07;vec[80] = a_08;vec[90] = a_09; vec[1] = a_10;vec[11] = a_11;vec[21] = a_12;vec[31] = a_13;vec[41] = a_14;vec[51] = a_15;vec[61] = a_16;vec[71] = a_17;vec[81] = a_18;vec[91] = a_19; vec[2] = a_20;vec[12] = a_21;vec[22] = a_22;vec[32] = a_23;vec[42] = a_24;vec[52] = a_25;vec[62] = a_26;vec[72] = a_27;vec[82] = a_28;vec[92] = a_29; vec[3] = a_30;vec[13] = a_31;vec[23] = a_32;vec[33] = a_33;vec[43] = a_34;vec[53] = a_35;vec[63] = a_36;vec[73] = a_37;vec[83] = a_38;vec[93] = a_39; vec[4] = a_40;vec[14] = a_41;vec[24] = a_42;vec[34] = a_43;vec[44] = a_44;vec[54] = a_45;vec[64] = a_46;vec[74] = a_47;vec[84] = a_48;vec[94] = a_49; vec[5] = a_50;vec[15] = a_51;vec[25] = a_52;vec[35] = a_53;vec[45] = a_54;vec[55] = a_55;vec[65] = a_56;vec[75] = a_57;vec[85] = a_58;vec[95] = a_59; vec[6] = a_60;vec[16] = a_61;vec[26] = a_62;vec[36] = a_63;vec[46] = a_64;vec[56] = a_65;vec[66] = a_66;vec[76] = a_67;vec[86] = a_68;vec[96] = a_69; vec[7] = a_70;vec[17] = a_71;vec[27] = a_72;vec[37] = a_73;vec[47] = a_74;vec[57] = a_75;vec[67] = a_76;vec[77] = a_77;vec[87] = a_78;vec[97] = a_79; vec[8] = a_80;vec[18] = a_81;vec[28] = a_82;vec[38] = a_83;vec[48] = a_84;vec[58] = a_85;vec[68] = a_86;vec[78] = a_87;vec[88] = a_88;vec[98] = a_89; vec[9] = a_90;vec[19] = a_91;vec[29] = a_92;vec[39] = a_93;vec[49] = a_94;vec[59] = a_95;vec[69] = a_96;vec[79] = a_97;vec[89] = a_98;vec[99] = a_99; } #undef TOOLS_MELEM } //////////////////////////////////////////////// //////////////////////////////////////////////// //////////////////////////////////////////////// #include namespace tools { //NOTE : print is a Python keyword. template inline void dump(std::ostream& a_out,const std::string& aCMT,const MAT& a_matrix) { if(aCMT.size()) a_out << aCMT << std::endl; unsigned int D = a_matrix.dimension(); for(unsigned int r=0;r inline bool check_invert(const MAT& a_matrix,std::ostream& a_out) { MAT I;I.set_identity(); MAT tmp; if(!a_matrix.invert(tmp)) return false; tmp.mul_mtx(a_matrix); if(!tmp.equal(I)) { dump(a_out,"problem with inv of :",a_matrix); return false; } return true; } } #endif