// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_MATCOM #define tools_MATCOM /* NOTE : bof, no big improvement. #include //memcpy inline void vec_copy(double* a_to,const double* a_from,unsigned int a_number) { ::memcpy(a_to,a_from,a_number*sizeof(double)); } template inline void vec_copy(T* a_to,const T* a_from,unsigned int a_number) { T* pto = (T*)a_to; T* pfm = (T*)a_from; for(unsigned int i=0;i inline void vec_add(const float* a_1,const float* a_2,float* a_res,unsigned int a_number) { ::vDSP_vadd(a_1,1,a_2,1,a_res,1,a_number); } inline void vec_sub(const float* a_1,const float* a_2,float* a_res,unsigned int a_number) { ::vDSP_vsub(a_1,1,a_2,1,a_res,1,a_number); } */ /* template inline void vec_add(const T* a_1,const T* a_2,T* a_res,unsigned int a_number) { T* p1 = (T*)a_1; T* p2 = (T*)a_2; T* pr = (T*)a_res; for(unsigned int i=0;i inline void vec_sub(const T* a_1,const T* a_2,T* a_res,unsigned int a_number) { T* p1 = (T*)a_1; T* p2 = (T*)a_2; T* pr = (T*)a_res; for(unsigned int i=0;i\ void set_random(RANDOM& a_random) {\ for(unsigned int i=0;i\ 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* res = new T[dimension()];\ bool status = mul_vec(a_vec,res);\ delete [] res;\ 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;\ }\ \ 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 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;\ }\ \ 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=1) a_tmp_rs[r-1] = r-1;\ v_rc = value(r,c);\ if(v_rc!=zero()) {\ T subdet = sub_determinant(rord,a_tmp_rs,a_tmp_cs);\ if(sg) \ det += v_rc * subdet;\ else\ det -= v_rc * subdet;\ }\ sg = sg?false:true;\ }\ \ return det;\ }\ \ 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 v01 = *(m_vec+ord);\ T v10 = *(m_vec+1);\ T v11 = *(m_vec+1+ord);\ return (v00 * v11 - v10 * v01);\ } else if(ord==3) {\ T v01 = *(m_vec+ord);\ T v02 = *(m_vec+2*ord);\ T v11 = *(m_vec+1+ord);\ T v12 = *(m_vec+1+2*ord);\ T v21 = *(m_vec+2+ord);\ T v22 = *(m_vec+2+2*ord);\ T cof_00 = v11 * v22 - v21 * v12;\ T cof_10 = v01 * v22 - v21 * v02;\ T cof_20 = v01 * v12 - v11 * v02;\ T v00 = *m_vec;\ T v10 = *(m_vec+1);\ T v20 = *(m_vec+2);\ 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;\ }\ \ bool invert(TOOLS_MAT_CLASS& a_res) const {\ /*Generic invertion method.*/\ unsigned int ord = dimension();\ if(ord==0) return true;\ \ if(ord==1) {\ T v = value(0,0);\ if(v==zero()) return false;\ a_res.set_value(0,0,one()/v);\ return true;\ }\ \ unsigned int rord = ord-1;\ unsigned int* cs = new unsigned int[rord];\ unsigned int* rs = new unsigned int[rord];\ \ /* Get det with r = 0;*/\ T det = zero();\ {\ {for(unsigned int i=0;i=1) rs[r-1] = r-1;*/\ \ {for(unsigned int i=0;i=1) cs[c-1] = c-1;\ T subdet = sub_determinant(rord,rs,cs);\ T sgn = sg ? one() : minus_one();\ det += value(r,c) * subdet * sgn;\ T _value = subdet * sgn;\ a_res.set_value(c,r,_value);\ sg = sg?false:true;\ }}\ \ if(det==zero()) {\ delete [] cs;\ delete [] rs;\ return false;\ } \ \ {for(unsigned int c=0;c=1) rs[r-1] = r-1;\ {for(unsigned int i=0;i=1) cs[c-1] = c-1;\ T subdet = sub_determinant(rord,rs,cs);\ T sgn = sg ? one() : minus_one();\ T _value = (subdet * sgn)/det;\ a_res.set_value(c,r,_value);\ sg = sg?false:true;\ }\ sgr = sgr?false:true;\ }\ \ delete [] cs;\ delete [] rs;\ \ return true;\ }\ \ void power(unsigned int a_n,TOOLS_MAT_CLASS& a_res) const {\ a_res.set_identity();\ 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[](unsigned int a_index) { /*for inlib/sg/sf_vec*/\ /*WARNING : no check on a_index.*/\ return m_vec[a_index];\ }\ const T& operator[](unsigned int 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 and mat see inlib/tests/symbolic.cpp */\ /*vec_copy(m_vec,a_m,dim2());*/\ }\ \ void _add_mtx(const T a_m[]) { /* this = this + a_m, */\ {T* tp = (T*)m_vec;T* ap = (T*)a_m;\ 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(v_rc!=zero()) {\ T subdet = sub_determinant(rord,rs,cs);\ if(sg)\ det += v_rc * subdet;\ else\ det -= v_rc * subdet;\ }\ sg = sg?false:true;\ }\ \ delete [] cs;\ delete [] rs;\ \ return det;\ } #endif