Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/lina/MATCOM is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_MATCOM
0005 #define tools_MATCOM
0006 
0007 /* NOTE : bof, no big improvement.
0008 #include <cstring> //memcpy
0009 inline void vec_copy(double* a_to,const double* a_from,unsigned int a_number) {
0010   ::memcpy(a_to,a_from,a_number*sizeof(double));
0011 }
0012 
0013 template <class T>
0014 inline void vec_copy(T* a_to,const T* a_from,unsigned int a_number) {
0015   T* pto = (T*)a_to;
0016   T* pfm = (T*)a_from;
0017   for(unsigned int i=0;i<a_number;i++,pto++,pfm++) *pto = *pfm;
0018 }
0019 */
0020 
0021 /*NOTE : bof, no big improvement.
0022 #include <Accelerate/Accelerate.h>
0023 
0024 inline void vec_add(const float* a_1,const float* a_2,float* a_res,unsigned int a_number) {
0025   ::vDSP_vadd(a_1,1,a_2,1,a_res,1,a_number);
0026 }
0027 inline void vec_sub(const float* a_1,const float* a_2,float* a_res,unsigned int a_number) {
0028   ::vDSP_vsub(a_1,1,a_2,1,a_res,1,a_number);
0029 }
0030 */
0031 
0032 /*
0033 template <class T>
0034 inline void vec_add(const T* a_1,const T* a_2,T* a_res,unsigned int a_number) {
0035   T* p1 = (T*)a_1;
0036   T* p2 = (T*)a_2;
0037   T* pr = (T*)a_res;
0038   for(unsigned int i=0;i<a_number;i++,p1++,p2++,pr++) *pr = *p1+*p2;
0039 }
0040 
0041 template <class T>
0042 inline void vec_sub(const T* a_1,const T* a_2,T* a_res,unsigned int a_number) {
0043   T* p1 = (T*)a_1;
0044   T* p2 = (T*)a_2;
0045   T* pr = (T*)a_res;
0046   for(unsigned int i=0;i<a_number;i++,p1++,p2++,pr++) *pr = *p1-*p2;
0047 }
0048 */
0049 
0050 #include "../eqT"
0051 
0052 #include <cstddef> //size_t
0053 
0054 // common code to class mat and nmat.
0055 
0056 #define TOOLS_MATCOM \
0057 protected:\
0058   static T zero() {return T();}\
0059   static T one() {return T(1);}\
0060   static T minus_one() {return T(-1);}\
0061   static T two() {return T(2);}\
0062 public:\
0063   typedef T elem_t;\
0064   typedef unsigned int size_type;\
0065 public:\
0066   unsigned int rows() const {return dimension();}\
0067   unsigned int cols() const {return dimension();}\
0068 \
0069   void set_value(unsigned int aR,unsigned int aC,const T& a_value) { \
0070     m_vec[aR + aC * dimension()] = a_value;\
0071   }\
0072 \
0073   const T& value(unsigned int aR,unsigned int aC) const { \
0074     return m_vec[aR + aC * dimension()];\
0075   }\
0076 \
0077   T value(unsigned int aR,unsigned int aC) { \
0078     return m_vec[aR + aC * dimension()];\
0079   }\
0080 \
0081   void set_matrix(const TOOLS_MAT_CLASS& a_m){ /*optimization.*/\
0082     _copy(a_m.m_vec);\
0083   }\
0084 \
0085   void set_constant(const T& a_v){\
0086     for(unsigned int i=0;i<dim2();i++) m_vec[i] = a_v;\
0087   }\
0088   void set_zero(){\
0089     set_constant(zero());\
0090   }\
0091   void set_identity() {\
0092     set_zero();\
0093     for(unsigned int i=0;i<dimension();i++) m_vec[i+i*dimension()] = one();\
0094   }\
0095   void set_diagonal(const T& a_s) {\
0096     set_zero();\
0097     for(unsigned int i=0;i<dimension();i++) m_vec[i+i*dimension()] = a_s;\
0098   }\
0099   typedef T (*func)(const T&);\
0100   void apply_func(func a_func) {\
0101     T* pos = m_vec;\
0102     for(unsigned int i=0;i<dim2();i++,pos++) *pos = a_func(*pos);\
0103   }\
0104   template <class RANDOM>\
0105   void set_random(RANDOM& a_random) {\
0106     for(unsigned int i=0;i<dim2();i++) m_vec[i] = a_random.shoot();\
0107   }\
0108   template <class RANDOM>\
0109   void set_symmetric_random(RANDOM& a_random) {\
0110     unsigned int _D = dimension();\
0111    {for(unsigned int r=0;r<_D;r++) set_value(r,r,a_random.shoot());}\
0112     T rd;\
0113    {for(unsigned int r=0;r<_D;r++) {\
0114       for(unsigned int c=(r+1);c<_D;c++) {\
0115         rd = a_random.shoot();\
0116         set_value(r,c,rd);\
0117         set_value(c,r,rd);\
0118       }\
0119     }}\
0120   }\
0121   template <class RANDOM>\
0122   void set_antisymmetric_random(RANDOM& a_random) {\
0123     unsigned int _D = dimension();\
0124    {for(unsigned int r=0;r<_D;r++) set_value(r,r,zero());}\
0125     T rd;\
0126    {for(unsigned int r=0;r<_D;r++) {\
0127       for(unsigned int c=(r+1);c<_D;c++) {\
0128         rd = a_random.shoot();\
0129         set_value(r,c,rd);\
0130         set_value(c,r,minus_one()*rd);\
0131       }\
0132     }}\
0133   }\
0134 public:\
0135   template <class ARRAY>\
0136   bool mul_array(ARRAY& a_array,T a_tmp[]) const {\
0137     /* a_array = this *= a_array */\
0138     unsigned int _dim = dimension();\
0139     T* pos = a_tmp;\
0140     for(unsigned int r=0;r<_dim;r++,pos++) {\
0141       *pos = T();\
0142       for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_array[c];\
0143     }\
0144    {for(unsigned int i=0;i<_dim;i++) a_array[i] = a_tmp[i];}\
0145     return true;\
0146   }\
0147   template <class VEC>\
0148   bool mul_vec(VEC& a_vec,T a_tmp[]) const {\
0149     /* a_vec = this *= a_vec */\
0150     unsigned int _dim = dimension();\
0151     if(a_vec.dimension()!=_dim) return false;\
0152     T* pos = a_tmp;\
0153     for(unsigned int r=0;r<_dim;r++,pos++) {\
0154       *pos = T();\
0155       for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_vec[c];\
0156     }\
0157    {for(unsigned int i=0;i<_dim;i++) a_vec[i] = a_tmp[i];}\
0158     return true;\
0159   }\
0160   template <class VEC>\
0161   bool mul_vec(VEC& a_vec) const {\
0162     T* _tmp = new T[dimension()];\
0163     bool status = mul_vec(a_vec,_tmp);\
0164     delete [] _tmp;\
0165     return status;\
0166   }\
0167 \
0168   bool mul_array(T a_vec[],T a_tmp[]) const {\
0169     /* a_vec = this *= a_vec */\
0170     unsigned int _dim = dimension();\
0171     T* pos = a_tmp;\
0172     for(unsigned int r=0;r<_dim;r++,pos++) {\
0173       *pos = T();\
0174       for(unsigned int c=0;c<_dim;c++) *pos += m_vec[r+c*_dim]*a_vec[c];\
0175     }\
0176    {for(unsigned int i=0;i<_dim;i++) a_vec[i] = a_tmp[i];}\
0177     return true;\
0178   }\
0179   bool mul_array(T a_vec[]) const {\
0180     T* _tmp = new T[dimension()];\
0181     bool status = mul_array(a_vec,_tmp);\
0182     delete [] _tmp;\
0183     return status;\
0184   }\
0185 \
0186   void mul_mtx(const TOOLS_MAT_CLASS& a_m) {\
0187     _mul_mtx(a_m.m_vec);\
0188   }\
0189   void mul_mtx(const TOOLS_MAT_CLASS& a_m,T a_tmp[]) {\
0190     _mul_mtx(a_m.m_vec,a_tmp);\
0191   }\
0192   void left_mul_mtx(const TOOLS_MAT_CLASS& a_m) {    \
0193     /* this = a_m * this :*/\
0194     _left_mul_mtx(a_m.m_vec);\
0195   }\
0196   bool equal(const TOOLS_MAT_CLASS& a_m) const {\
0197     if(&a_m==this) return true;\
0198     for(unsigned int i=0;i<dim2();i++) {\
0199       if(m_vec[i]!=a_m.m_vec[i]) return false;\
0200     }\
0201     return true;\
0202   }\
0203 \
0204   bool equal(const TOOLS_MAT_CLASS& a_m,const T& a_prec) const {\
0205     if(&a_m==this) return true;\
0206     T* tp = (T*)m_vec;\
0207     T* mp = (T*)a_m.m_vec;\
0208     for(unsigned int i=0;i<dim2();i++,tp++,mp++) {\
0209       T diff = (*tp) - (*mp);\
0210       if(diff<zero()) diff *= minus_one();\
0211       if(diff>=a_prec) return false;\
0212     }\
0213     return true;\
0214   }\
0215 \
0216   template <class PREC>\
0217   bool equal_prec(const TOOLS_MAT_CLASS& a_m,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0218     if(&a_m==this) return true;\
0219     T* tp = (T*)m_vec;\
0220     T* mp = (T*)a_m.m_vec;\
0221     for(unsigned int i=0;i<dim2();i++,tp++,mp++) {\
0222       T diff = (*tp) - (*mp);\
0223       if(a_fabs(diff)>=a_prec) return false;\
0224     }\
0225     return true;\
0226   }\
0227 \
0228   void mx_diff(const TOOLS_MAT_CLASS& a_m,T& a_mx_diff) const {\
0229     T* tp = (T*)m_vec;\
0230     T* mp = (T*)a_m.m_vec;\
0231     a_mx_diff = (*tp) - (*mp);\
0232     if(a_mx_diff<zero()) a_mx_diff *= minus_one();\
0233     for(unsigned int i=0;i<dim2();i++,tp++,mp++) {\
0234       T diff = (*tp) - (*mp);\
0235       if(diff<zero()) diff *= minus_one();\
0236       a_mx_diff = (diff>a_mx_diff?diff:a_mx_diff);\
0237     }\
0238   }\
0239 \
0240   bool to_rm_is_proportional(const TOOLS_MAT_CLASS& a_m,const T& a_prec,T& a_factor) const {\
0241     if(&a_m==this) {a_factor=one();return true;}\
0242     /* If true, then : a_m = a_factor * this.*/\
0243     a_factor = zero();\
0244     T* tp = (T*)m_vec;\
0245     T* mp = (T*)a_m.m_vec;\
0246     bool first = true;\
0247     for(unsigned int i=0;i<dim2();i++,tp++,mp++) {\
0248              if( ((*tp)==zero()) && ((*mp)==zero())) {\
0249         continue;\
0250       /*} else if( ((*tp)!=zero()) && ((*mp)==zero())) {\
0251         return false;*/\
0252       } else if( ((*tp)==zero()) && ((*mp)!=zero())) {\
0253         return false;\
0254       } else {\
0255         if(first) {\
0256           a_factor = (*mp)/(*tp);\
0257           first = false;\
0258         } else {\
0259           T diff = (*tp)*a_factor - (*mp);\
0260           if(diff<zero()) diff *= minus_one();\
0261           if(diff>=a_prec) return false;\
0262         }\
0263       }\
0264     }\
0265     return true;\
0266   }\
0267 \
0268 public:\
0269   bool is_proportional(const TOOLS_MAT_CLASS& a_right,T& a_factor) const {\
0270     /* If true, then : a_right = a_factor * this. a_factor could be zero.*/\
0271     if(this==&a_right) {a_factor=T(1);return true;}\
0272     a_factor = zero();\
0273     if(dimension()!=a_right.dimension()) return false;\
0274     T* lp = (T*)m_vec;\
0275     T* rp = (T*)a_right.m_vec;\
0276     bool first = true;\
0277     size_t _data_size = data_size();\
0278     for(size_t i=0;i<_data_size;i++,lp++,rp++) {\
0279       if(*lp==zero()) {\
0280         if(*rp==zero()) continue;\
0281         return false;\
0282       }\
0283       if(first) {\
0284         a_factor = (*rp)/(*lp);\
0285         first = false;\
0286         continue;\
0287       }\
0288       if((*lp)*a_factor!=(*rp)) return false;\
0289     }\
0290     return true;\
0291   }\
0292 \
0293   template <class PREC>\
0294   bool is_proportional_prec(const TOOLS_MAT_CLASS& a_right,const PREC& a_prec,PREC(*a_fabs)(const T&),T& a_factor) const {\
0295     /* If true, then : a_right = a_factor * this. a_factor could be zero.*/\
0296     if(this==&a_right) {a_factor=T(1);return true;}\
0297     a_factor = zero();\
0298     if(dimension()!=a_right.dimension()) return false;\
0299     T* lp = (T*)m_vec;\
0300     T* rp = (T*)a_right.m_vec;\
0301     bool first = true;\
0302     size_t _data_size = data_size();\
0303     for(size_t i=0;i<_data_size;i++,lp++,rp++) {\
0304       if(is_zero(*lp,a_prec,a_fabs)) {\
0305         if(is_zero(*rp,a_prec,a_fabs)) continue;\
0306         return false;\
0307       }\
0308       if(first) {\
0309         a_factor = (*rp)/(*lp);\
0310         first = false;\
0311         continue;\
0312       }\
0313       if(!numbers_are_equal((*lp)*a_factor,*rp,a_prec,a_fabs)) return false;\
0314     }\
0315     return true;\
0316   }\
0317 \
0318   bool is_diagonal() const {\
0319     unsigned int _D = dimension();\
0320     for(unsigned int r=0;r<_D;r++) {\
0321       for(unsigned int c=0;c<_D;c++) {\
0322         if(c!=r) {if(value(r,c)!=zero()) return false;}\
0323       }\
0324     }\
0325     return true;\
0326   }\
0327 \
0328   template <class PREC>\
0329   bool is_diagonal_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0330     unsigned int _D = dimension();\
0331     for(unsigned int r=0;r<_D;r++) {\
0332       for(unsigned int c=0;c<_D;c++) {\
0333         if(c!=r) {if(!is_zero(value(r,c),a_prec,a_fabs)) return false;}\
0334       }\
0335     }\
0336     return true;\
0337   }\
0338 \
0339   bool is_identity() const {\
0340     unsigned int _D = dimension();\
0341    {for(unsigned int r=0;r<_D;r++) {\
0342       if(value(r,r)!=one()) return false;\
0343     }}\
0344    {for(unsigned int r=0;r<_D;r++) {\
0345       for(unsigned int c=0;c<_D;c++) {\
0346         if(c!=r) {if(value(r,c)!=zero()) return false;}\
0347       }\
0348     }}\
0349     return true;\
0350   }\
0351 \
0352   template <class PREC>\
0353   bool is_identity_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0354     unsigned int _D = dimension();\
0355    {for(unsigned int r=0;r<_D;r++) {\
0356       if(!numbers_are_equal(value(r,r),one(),a_prec,a_fabs)) return false;\
0357     }}\
0358    {for(unsigned int r=0;r<_D;r++) {\
0359       for(unsigned int c=0;c<_D;c++) {\
0360         if(c!=r) {if(!is_zero(value(r,c),a_prec,a_fabs)) return false;}\
0361       }\
0362     }}\
0363     return true;\
0364   }\
0365 \
0366   const T* data() const {return m_vec;}\
0367   unsigned int size() const {return dim2();}\
0368   unsigned int data_size() const {return dim2();} /*for mathz*/\
0369 \
0370   T trace() const {\
0371     T _value = zero();\
0372     unsigned int _D = dimension();\
0373     for(unsigned int c=0;c<_D;c++) _value += m_vec[c+c*_D];\
0374     return _value;\
0375   }\
0376 \
0377   void transpose() {\
0378     unsigned int _D = dimension();\
0379     for(unsigned int r=0;r<_D;r++) {\
0380       for(unsigned int c=(r+1);c<_D;c++) {\
0381         T vrc = value(r,c);\
0382         T vcr = value(c,r);\
0383         set_value(r,c,vcr);\
0384         set_value(c,r,vrc);\
0385       }\
0386     }\
0387   }\
0388 \
0389   void multiply(const T& a_T) {\
0390     for(unsigned int i=0;i<dim2();i++) m_vec[i] *= a_T;\
0391   }\
0392 \
0393   bool is_symmetric() const {\
0394     unsigned int _D = dimension();\
0395     for(unsigned int r=0;r<_D;r++) {\
0396       for(unsigned int c=(r+1);c<_D;c++) {\
0397         if(value(r,c)!=value(c,r)) return false;\
0398       }\
0399     }\
0400     return true;\
0401   }\
0402 \
0403   template <class PREC>\
0404   bool is_symmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0405     unsigned int _D = dimension();\
0406     for(unsigned int r=0;r<_D;r++) {\
0407       for(unsigned int c=(r+1);c<_D;c++) {\
0408         T diff = value(r,c)-value(c,r);\
0409         if(a_fabs(diff)>=a_prec) return false;\
0410       }\
0411     }\
0412     return true;\
0413   }\
0414 \
0415   bool is_antisymmetric() const {\
0416     unsigned int _D = dimension();\
0417    {for(unsigned int r=0;r<_D;r++) {\
0418       if(value(r,r)!=zero()) return false;\
0419     }}\
0420     for(unsigned int r=0;r<_D;r++) {\
0421       for(unsigned int c=(r+1);c<_D;c++) {\
0422         if(value(r,c)!=minus_one()*value(c,r)) return false;\
0423       }\
0424     }\
0425     return true;\
0426   }\
0427 \
0428   template <class PREC>\
0429   bool is_antisymmetric_prec(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0430     unsigned int _D = dimension();\
0431    {for(unsigned int r=0;r<_D;r++) {\
0432       if(a_fabs(value(r,r))>=a_prec) return false;\
0433     }}\
0434     for(unsigned int r=0;r<_D;r++) {\
0435       for(unsigned int c=(r+1);c<_D;c++) {\
0436         T diff = value(r,c)-minus_one()*value(c,r);\
0437         if(a_fabs(diff)>=a_prec) return false;\
0438       }\
0439     }\
0440     return true;\
0441   }\
0442 \
0443   void symmetric_part(TOOLS_MAT_CLASS& a_res) const {\
0444     a_res = *this;\
0445     a_res.transpose();\
0446     a_res += *this;\
0447     a_res.multiply(one()/two());\
0448   }\
0449 \
0450   void antisymmetric_part(TOOLS_MAT_CLASS& a_res) const {\
0451     a_res = *this;\
0452     a_res.transpose();\
0453     a_res.multiply(minus_one());\
0454     a_res += *this;\
0455     a_res.multiply(one()/two());\
0456   }\
0457 \
0458   template <class PREC>\
0459   bool is_block_UL_DR(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0460     /* Look if even dim matrix is of the form :  |X 0|\
0461                                                  |0 Y|*/\
0462     unsigned int _D = dimension();\
0463     unsigned int _D_2 = _D/2;\
0464     if(2*_D_2!=_D) return false;\
0465     for(unsigned int r=0;r<_D_2;r++) {\
0466       for(unsigned int c=_D_2;c<_D;c++) {\
0467         if(a_fabs(value(r,c))>=a_prec) return false;\
0468       }\
0469     }\
0470     for(unsigned int r=_D_2;r<_D;r++) {\
0471       for(unsigned int c=0;c<_D_2;c++) {\
0472         if(a_fabs(value(r,c))>=a_prec) return false;\
0473       }\
0474     }\
0475     return true;\
0476   }\
0477 \
0478   template <class PREC>\
0479   bool is_block_UR_DL(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0480     /* Look if even dim matrix is of the form :  |0 X|\
0481                                                  |Y 0|*/\
0482     unsigned int _D = dimension();\
0483     unsigned int _D_2 = _D/2;\
0484     if(2*_D_2!=_D) return false;\
0485     for(unsigned int r=0;r<_D_2;r++) {\
0486       for(unsigned int c=0;c<_D_2;c++) {\
0487         if(a_fabs(value(r,c))>=a_prec) return false;\
0488       }\
0489     }\
0490     for(unsigned int r=_D_2;r<_D;r++) {\
0491       for(unsigned int c=_D_2;c<_D;c++) {\
0492         if(a_fabs(value(r,c))>=a_prec) return false;\
0493       }\
0494     }\
0495     return true;\
0496   }\
0497 \
0498   template <class PREC>\
0499   bool is_decomplex(const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0500     /* Look if even dim matrix is of the form :  | X Y|\
0501                                                  |-Y X|*/\
0502     unsigned int _D = dimension();\
0503     unsigned int _D_2 = _D/2;\
0504     if(2*_D_2!=_D) return false;\
0505     for(unsigned int r=0;r<_D_2;r++) {\
0506       for(unsigned int c=0;c<_D_2;c++) {\
0507         if(a_fabs(value(r,c)-value(r+_D_2,c+_D_2))>=a_prec) return false;\
0508       }\
0509     }\
0510     for(unsigned int r=0;r<_D_2;r++) {\
0511       for(unsigned int c=_D_2;c<_D;c++) {\
0512         if(a_fabs(value(r,c)+value(r+_D_2,c-_D_2))>=a_prec) return false;\
0513       }\
0514     }\
0515     return true;\
0516   }\
0517 \
0518   template <class PREC>\
0519   T determinant_prec(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[],  /*[rord=dim-1]*/\
0520                      const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0521     unsigned int ord = dimension();\
0522     if(ord==0) {\
0523       return zero();\
0524     } else if(ord==1) {\
0525       return *m_vec;\
0526     } else if(ord==2) {\
0527       T v00 = *m_vec;\
0528       T v10 = *(m_vec+1);\
0529       T v01 = *(m_vec+2);\
0530       T v11 = *(m_vec+3);\
0531       return (v00 * v11 - v10 * v01);\
0532     } else if(ord==3) {\
0533       /*   00 01 02 \
0534            10 11 12 \
0535            20 21 22 \
0536       */\
0537       T v00 = *m_vec;\
0538       T v10 = *(m_vec+1);\
0539       T v20 = *(m_vec+2);\
0540       T v01 = *(m_vec+3);\
0541       T v11 = *(m_vec+4);\
0542       T v21 = *(m_vec+5);\
0543       T v02 = *(m_vec+6);\
0544       T v12 = *(m_vec+7);\
0545       T v22 = *(m_vec+8);\
0546       T cof_00 = v11 * v22 - v21 * v12;\
0547       T cof_10 = v01 * v22 - v21 * v02;\
0548       T cof_20 = v01 * v12 - v11 * v02;\
0549       return (v00*cof_00-v10*cof_10+v20*cof_20);\
0550     }\
0551 \
0552     unsigned int rord = ord-1;\
0553 \
0554     T v_rc;\
0555 \
0556     T det = zero();\
0557    {for(unsigned int i=0;i<rord;i++) {a_tmp_cs[i] = i+1;}}\
0558     unsigned int c = 0;\
0559 \
0560    {for(unsigned int i=0;i<rord;i++) {a_tmp_rs[i] = i+1;}}\
0561     bool sg = true; /*c=0+r=0*/\
0562     for(unsigned int r=0;r<ord;r++) {\
0563       if(r>=1) a_tmp_rs[r-1] = r-1;\
0564       v_rc = value(r,c);\
0565       if(!is_zero(v_rc,a_prec,a_fabs)) {\
0566         T subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
0567         if(sg) \
0568           det += v_rc * subdet;\
0569         else\
0570           det -= v_rc * subdet;\
0571       }\
0572       sg = sg?false:true;\
0573     }\
0574 \
0575     return det;\
0576   }\
0577 \
0578   T determinant(unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \
0579     return determinant_prec<double>(a_tmp_rs,a_tmp_cs,0,zero_fabs);\
0580   }\
0581 \
0582   T determinant() const {\
0583     unsigned int ord = dimension();\
0584     if(ord==0) {\
0585       return zero();\
0586     } else if(ord==1) {\
0587       return *m_vec;\
0588     } else if(ord==2) {\
0589       T v00 = *m_vec;\
0590       T v10 = *(m_vec+1);\
0591       T v01 = *(m_vec+2);\
0592       T v11 = *(m_vec+3);\
0593       return (v00 * v11 - v10 * v01);\
0594     } else if(ord==3) {\
0595       /*   00 01 02 \
0596            10 11 12 \
0597            20 21 22 \
0598       */\
0599       T v00 = *m_vec;\
0600       T v10 = *(m_vec+1);\
0601       T v20 = *(m_vec+2);\
0602       T v01 = *(m_vec+3);\
0603       T v11 = *(m_vec+4);\
0604       T v21 = *(m_vec+5);\
0605       T v02 = *(m_vec+6);\
0606       T v12 = *(m_vec+7);\
0607       T v22 = *(m_vec+8);\
0608       T cof_00 = v11 * v22 - v21 * v12;\
0609       T cof_10 = v01 * v22 - v21 * v02;\
0610       T cof_20 = v01 * v12 - v11 * v02;\
0611       return (v00*cof_00-v10*cof_10+v20*cof_20);\
0612     }\
0613     unsigned int rord = ord-1;\
0614     unsigned int* rs = new unsigned int[rord];\
0615     unsigned int* cs = new unsigned int[rord];\
0616     T det = determinant(rs,cs);\
0617     delete [] rs;\
0618     delete [] cs;\
0619     return det;\
0620   }\
0621 \
0622   template <class PREC>\
0623   bool invert_prec(TOOLS_MAT_CLASS& a_res,\
0624                    unsigned int a_tmp_rs[],unsigned int a_tmp_cs[],  /*[rord=dim-1]*/\
0625                    const PREC& a_prec,PREC(*a_fabs)(const T&) /*for det=?zero*/ \
0626                    ) const { \
0627     unsigned int ord = dimension();\
0628     if(ord==0) return true;\
0629 \
0630     if(ord==1) {\
0631       T det = value(0,0);\
0632       if(is_zero(det,a_prec,a_fabs)) return false;\
0633       a_res.set_value(0,0,one()/det);\
0634       return true;\
0635     } else if(ord==2) {\
0636       T v00 = *m_vec;\
0637       T v10 = *(m_vec+1);\
0638       T v01 = *(m_vec+2);\
0639       T v11 = *(m_vec+3);\
0640       T det = (v00 * v11 - v10 * v01);\
0641       if(is_zero(det,a_prec,a_fabs)) return false;\
0642       a_res.set_value(0,0,v11/det);\
0643       a_res.set_value(1,1,v00/det);\
0644       a_res.set_value(0,1,minus_one()*v01/det);\
0645       a_res.set_value(1,0,minus_one()*v10/det);\
0646       return true;\
0647     } else if(ord==3) {\
0648       /*   00 01 02 \
0649            10 11 12 \
0650            20 21 22 \
0651       */\
0652       T v00 = *m_vec;\
0653       T v10 = *(m_vec+1);\
0654       T v20 = *(m_vec+2);\
0655       T v01 = *(m_vec+3);\
0656       T v11 = *(m_vec+4);\
0657       T v21 = *(m_vec+5);\
0658       T v02 = *(m_vec+6);\
0659       T v12 = *(m_vec+7);\
0660       T v22 = *(m_vec+8);\
0661       T cof_00 = v11 * v22 - v21 * v12;\
0662       T cof_10 = v01 * v22 - v21 * v02;\
0663       T cof_20 = v01 * v12 - v11 * v02;\
0664       T det = (v00*cof_00-v10*cof_10+v20*cof_20);\
0665       if(is_zero(det,a_prec,a_fabs)) return false;\
0666       T cof_01 = v10 * v22 - v20 * v12;\
0667       T cof_11 = v00 * v22 - v20 * v02;\
0668       T cof_21 = v00 * v12 - v10 * v02;\
0669       T cof_02 = v10 * v21 - v20 * v11;\
0670       T cof_12 = v00 * v21 - v20 * v01;\
0671       T cof_22 = v00 * v11 - v10 * v01;\
0672       a_res.set_value(0,0,cof_00/det);\
0673       a_res.set_value(1,0,minus_one()*cof_01/det);\
0674       a_res.set_value(2,0,cof_02/det);\
0675       a_res.set_value(0,1,minus_one()*cof_10/det);\
0676       a_res.set_value(1,1,cof_11/det);\
0677       a_res.set_value(2,1,minus_one()*cof_12/det);\
0678       a_res.set_value(0,2,cof_20/det);\
0679       a_res.set_value(1,2,minus_one()*cof_21/det);\
0680       a_res.set_value(2,2,cof_22/det);\
0681       return true;\
0682     }\
0683   \
0684     /*Generic invertion method.*/\
0685   \
0686     unsigned int rord = ord-1;\
0687   \
0688     /* Get det with r = 0;*/\
0689     T det = zero();\
0690     T subdet;\
0691    {\
0692    {for(unsigned int i=0;i<rord;i++) {a_tmp_rs[i] = i+1;}}\
0693     unsigned int r = 0;\
0694     /*if(r>=1) a_tmp_rs[r-1] = r-1;*/\
0695   \
0696    {for(unsigned int i=0;i<rord;i++) {a_tmp_cs[i] = i+1;}}\
0697     bool sg = true; /*r=0+c=0*/\
0698     for(unsigned int c=0;c<ord;c++) {\
0699       if(c>=1) a_tmp_cs[c-1] = c-1;\
0700       subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
0701       if(sg) {\
0702         det += value(r,c) * subdet;\
0703         a_res.set_value(c,r,subdet);\
0704         sg = false;\
0705       } else {\
0706         det += value(r,c) * subdet * minus_one();\
0707         a_res.set_value(c,r,subdet * minus_one());\
0708         sg = true;\
0709       }\
0710     }}\
0711 \
0712    if(is_zero(det,a_prec,a_fabs)) return false;\
0713 \
0714    {for(unsigned int c=0;c<ord;c++) {\
0715       a_res.set_value(c,0,a_res.value(c,0)/det);\
0716     }}\
0717   \
0718    {for(unsigned int i=0;i<rord;i++) {a_tmp_rs[i] = i+1;}}\
0719     bool sgr = false; /*r=1+c=0*/\
0720     for(unsigned int r=1;r<ord;r++) {\
0721       if(r>=1) a_tmp_rs[r-1] = r-1;\
0722      {for(unsigned int i=0;i<rord;i++) {a_tmp_cs[i] = i+1;}}\
0723       bool sg = sgr;\
0724       for(unsigned int c=0;c<ord;c++) {\
0725         if(c>=1) a_tmp_cs[c-1] = c-1;\
0726         subdet = sub_determinant_prec(rord,a_tmp_rs,a_tmp_cs,a_prec,a_fabs);\
0727         if(sg) {\
0728           a_res.set_value(c,r,subdet/det);\
0729           sg = false;\
0730         } else {\
0731           a_res.set_value(c,r,(subdet * minus_one())/det);\
0732           sg = true;\
0733         }\
0734       }\
0735       sgr = sgr?false:true;\
0736     }\
0737 \
0738     return true;\
0739   }\
0740 \
0741   template <class PREC>\
0742   bool invert_prec(TOOLS_MAT_CLASS& a_res,const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
0743     unsigned int ord = dimension();\
0744     if(ord==0) return true;\
0745 \
0746     if(ord==1) {\
0747       T det = value(0,0);\
0748       if(is_zero(det,a_prec,a_fabs)) return false;\
0749       a_res.set_value(0,0,one()/det);\
0750       return true;\
0751     } else if(ord==2) {\
0752       T v00 = *m_vec;\
0753       T v10 = *(m_vec+1);\
0754       T v01 = *(m_vec+2);\
0755       T v11 = *(m_vec+3);\
0756       T det = (v00 * v11 - v10 * v01);\
0757       if(is_zero(det,a_prec,a_fabs)) return false;\
0758       a_res.set_value(0,0,v11/det);\
0759       a_res.set_value(1,1,v00/det);\
0760       a_res.set_value(0,1,minus_one()*v01/det);\
0761       a_res.set_value(1,0,minus_one()*v10/det);\
0762       return true;\
0763     } else if(ord==3) {\
0764       /*   00 01 02 \
0765            10 11 12 \
0766            20 21 22 \
0767       */\
0768       T v00 = *m_vec;\
0769       T v10 = *(m_vec+1);\
0770       T v20 = *(m_vec+2);\
0771       T v01 = *(m_vec+3);\
0772       T v11 = *(m_vec+4);\
0773       T v21 = *(m_vec+5);\
0774       T v02 = *(m_vec+6);\
0775       T v12 = *(m_vec+7);\
0776       T v22 = *(m_vec+8);\
0777       T cof_00 = v11 * v22 - v21 * v12;\
0778       T cof_10 = v01 * v22 - v21 * v02;\
0779       T cof_20 = v01 * v12 - v11 * v02;\
0780       T det = (v00*cof_00-v10*cof_10+v20*cof_20);\
0781       if(is_zero(det,a_prec,a_fabs)) return false;\
0782       T cof_01 = v10 * v22 - v20 * v12;\
0783       T cof_11 = v00 * v22 - v20 * v02;\
0784       T cof_21 = v00 * v12 - v10 * v02;\
0785       T cof_02 = v10 * v21 - v20 * v11;\
0786       T cof_12 = v00 * v21 - v20 * v01;\
0787       T cof_22 = v00 * v11 - v10 * v01;\
0788       a_res.set_value(0,0,cof_00/det);\
0789       a_res.set_value(1,0,minus_one()*cof_01/det);\
0790       a_res.set_value(2,0,cof_02/det);\
0791       a_res.set_value(0,1,minus_one()*cof_10/det);\
0792       a_res.set_value(1,1,cof_11/det);\
0793       a_res.set_value(2,1,minus_one()*cof_12/det);\
0794       a_res.set_value(0,2,cof_20/det);\
0795       a_res.set_value(1,2,minus_one()*cof_21/det);\
0796       a_res.set_value(2,2,cof_22/det);\
0797       return true;\
0798     }\
0799 \
0800     unsigned int rord = ord-1;\
0801     unsigned int* cs = new unsigned int[rord];\
0802     unsigned int* rs = new unsigned int[rord];\
0803     bool status = invert_prec(a_res,rs,cs,a_prec,a_fabs);\
0804     delete [] cs;\
0805     delete [] rs;\
0806     return status;\
0807   }\
0808 \
0809   bool invert(TOOLS_MAT_CLASS& a_res,unsigned int a_tmp_rs[],unsigned int a_tmp_cs[]) const { /*[rord=dim-1]*/ \
0810     return invert_prec<double>(a_res,a_tmp_rs,a_tmp_cs,0,zero_fabs);\
0811   }\
0812 \
0813   bool invert(TOOLS_MAT_CLASS& a_res) const {\
0814     return invert_prec<double>(a_res,0,zero_fabs);\
0815   }\
0816 \
0817   void power(unsigned int a_n,TOOLS_MAT_CLASS& a_res) const {\
0818     a_res.set_identity();\
0819     T* _tmp = new T[dim2()];\
0820     for(unsigned int i=0;i<a_n;i++) {\
0821       a_res._mul_mtx(m_vec,_tmp);\
0822     }\
0823     delete [] _tmp;\
0824   }\
0825 \
0826   void exp(unsigned int a_le,TOOLS_MAT_CLASS& a_res,TOOLS_MAT_CLASS& a_tmp,T a_tmp_2[]) const { /*OPTIMIZATION*/\
0827     /* result = I + M + M**2/2! + M**3/3! + .... */\
0828     a_res.set_identity();\
0829     a_tmp.set_identity();\
0830     for(unsigned int i=1;i<=a_le;i++) {\
0831       a_tmp._mul_mtx(m_vec,a_tmp_2);\
0832       a_tmp.multiply(one()/T(i));\
0833       a_res += a_tmp;\
0834     }\
0835   }\
0836 \
0837   void exp(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
0838     /* result = I + M + M**2/2! + M**3/3! + .... */\
0839     TOOLS_MAT_CLASS tmp(*this);\
0840     tmp.set_identity();\
0841     T* tmp_2 = new T[dim2()];\
0842     exp(a_le,a_res,tmp,tmp_2);\
0843     delete [] tmp_2;\
0844   }\
0845 \
0846   void cosh(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
0847     /* result = I + M**2/2! + M**4/4! + .... */\
0848     a_res.set_identity();\
0849     TOOLS_MAT_CLASS M_2(*this);\
0850     M_2._mul_mtx(m_vec);\
0851     TOOLS_MAT_CLASS tmp(*this);\
0852     tmp.set_identity();\
0853     T* _tmp = new T[dim2()];\
0854     for(unsigned int i=1;i<=a_le;i+=2) {\
0855       tmp._mul_mtx(M_2.m_vec,_tmp);\
0856       tmp.multiply(one()/T(i+0)); \
0857       tmp.multiply(one()/T(i+1)); \
0858       a_res += tmp;\
0859     }\
0860     delete [] _tmp;\
0861   }\
0862 \
0863   void sinh(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
0864     /* result = M + M**3/3! + .... */\
0865     a_res._copy(m_vec);\
0866     TOOLS_MAT_CLASS M_2(*this);\
0867     M_2._mul_mtx(m_vec);\
0868     TOOLS_MAT_CLASS tmp(*this);\
0869     tmp._copy(m_vec);\
0870     T* _tmp = new T[dim2()];\
0871     for(unsigned int i=1;i<=a_le;i+=2) {\
0872       tmp._mul_mtx(M_2.m_vec,_tmp);\
0873       tmp.multiply(one()/T(i+1)); \
0874       tmp.multiply(one()/T(i+2)); \
0875       a_res += tmp;\
0876     }\
0877     delete [] _tmp;\
0878   }\
0879 \
0880   void log(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
0881     /* result = (M-I) - (M-I)**2/2 + (M-I)**3/3 +... */\
0882     /* WARNING : touchy, it may not converge ! */\
0883     a_res.set_zero();\
0884 \
0885     TOOLS_MAT_CLASS M_I;\
0886     M_I.set_identity();\
0887     M_I.multiply(minus_one());\
0888     M_I._add_mtx(m_vec);\
0889 \
0890     TOOLS_MAT_CLASS M_Ip(M_I);\
0891     T fact = minus_one();\
0892 \
0893     TOOLS_MAT_CLASS tmp;\
0894 \
0895     T* _tmp = new T[dim2()];\
0896     for(unsigned int i=0;i<=a_le;i++) {\
0897       fact *= minus_one();      \
0898       tmp = M_Ip;\
0899       tmp.multiply(fact/T(i+1)); \
0900       a_res += tmp;\
0901       M_Ip._mul_mtx(M_I.m_vec,_tmp);\
0902     }\
0903     delete [] _tmp;\
0904   }\
0905 \
0906   void omega(unsigned int a_le,TOOLS_MAT_CLASS& a_res,TOOLS_MAT_CLASS& a_tmp,T a_tmp_2[]) const { /*OPTIMIZATION*/\
0907     /* result = I + M/2! + M**2/3! + M**3/4! + .... */\
0908     a_res.set_identity();\
0909     a_tmp.set_identity();\
0910     for(unsigned int i=1;i<=a_le;i++) {\
0911       a_tmp._mul_mtx(m_vec,a_tmp_2);\
0912       a_tmp.multiply(one()/T(i+1));\
0913       a_res += a_tmp;\
0914     }\
0915   }\
0916 \
0917   void omega(unsigned int a_le,TOOLS_MAT_CLASS& a_res) const {\
0918     /* result = I + M/2! + M**2/3! + M**3/4! + .... */\
0919     TOOLS_MAT_CLASS tmp(*this);\
0920     tmp.set_identity();\
0921     T* tmp_2 = new T[dim2()];\
0922     omega(a_le,a_res,tmp,tmp_2);\
0923     delete [] tmp_2;\
0924   }\
0925 \
0926   template <class MAT>\
0927   bool copy(const MAT& a_from) {\
0928     /*for exa from a double matrix to a symbol matrix*/\
0929     unsigned int _D = dimension();\
0930     if(a_from.dimension()!=_D) return false;\
0931     for(unsigned int r=0;r<_D;r++) {\
0932       for(unsigned int c=0;c<_D;c++) {\
0933         set_value(r,c,a_from.value(r,c));\
0934       }\
0935     }\
0936     return true;\
0937   }\
0938 public: /*operators*/\
0939   T operator()(unsigned int a_r,unsigned int a_c) const {\
0940     /*WARNING : no check on a_r,a_c.*/\
0941     return m_vec[a_r + a_c * dimension()];\
0942   }\
0943 \
0944   T& operator[](size_t a_index) { /*for tools/sg/sf_vec*/\
0945     /*WARNING : no check on a_index.*/\
0946     return m_vec[a_index];\
0947   }\
0948   const T& operator[](size_t a_index) const {\
0949     /*WARNING : no check on a_index.*/\
0950     return m_vec[a_index];\
0951   }\
0952   bool operator==(const TOOLS_MAT_CLASS& a_array) const {\
0953     return equal(a_array);\
0954   }\
0955   bool operator!=(const TOOLS_MAT_CLASS& a_array) const {\
0956     return !operator==(a_array);\
0957   }\
0958   TOOLS_MAT_CLASS& operator*=(const TOOLS_MAT_CLASS& a_m) {\
0959     _mul_mtx(a_m.m_vec);\
0960     return *this;\
0961   }\
0962   TOOLS_MAT_CLASS& operator+=(const TOOLS_MAT_CLASS& a_m) {\
0963     _add_mtx(a_m.m_vec);\
0964     return *this;\
0965   }\
0966   TOOLS_MAT_CLASS& operator-=(const TOOLS_MAT_CLASS& a_m) {\
0967     _sub_mtx(a_m.m_vec);\
0968     return *this;\
0969   }\
0970   TOOLS_MAT_CLASS& operator*=(const T& a_fac) {\
0971     for(unsigned int i=0;i<dim2();i++) m_vec[i] *= a_fac;\
0972     return *this;\
0973   }\
0974 \
0975   TOOLS_MAT_CLASS operator*(const T& a_fac) {\
0976     TOOLS_MAT_CLASS res;\
0977     res.operator*=(a_fac);\
0978     return res;\
0979   }\
0980 protected:\
0981   void _copy(const T a_m[]) {\
0982     T* tp = (T*)m_vec;T* ap = (T*)a_m;\
0983     for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp = *ap;\
0984    /*{for(unsigned int i=0;i<dim2();i++) m_vec[i] = a_m[i];}*/\
0985    /* memcpy does not work with std::complex<> and mat<symbol,4> see tools/tests/symbolic.cpp */\
0986     /*vec_copy(m_vec,a_m,dim2());*/\
0987   }\
0988 \
0989   void _add_mtx(const T a_m[]) {  /* this = this + a_m, */\
0990     T* tp = (T*)m_vec;T* ap = (T*)a_m;\
0991     for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp += *ap;\
0992     /*for(unsigned int i=0;i<dim2();i++) m_vec[i] += a_m[i];*/\
0993     /*vec_add(m_vec,a_m,m_vec,dim2());*/\
0994   }\
0995   void _sub_mtx(const T a_m[]) {  /* this = this - a_m, */\
0996     T* tp = (T*)m_vec;T* ap = (T*)a_m;\
0997     for(unsigned int i=0;i<dim2();i++,tp++,ap++) *tp -= *ap;\
0998     /*for(unsigned int i=0;i<dim2();i++) m_vec[i] -= a_m[i];*/\
0999     /*vec_sub(m_vec,a_m,m_vec,dim2());*/\
1000   }\
1001 \
1002 /*\
1003   void _mul_mtx(const T a_m[],T a_tmp[]) {\
1004     unsigned int ord = dimension();\
1005     for(unsigned int r=0;r<ord;r++) {\
1006       for(unsigned int c=0;c<ord;c++) {\
1007         T _value = zero();\
1008         for(unsigned int i=0;i<ord;i++) {\
1009           _value += (*(m_vec+r+i*ord)) * (*(a_m+i+c*ord)); //optimize.\
1010         }\
1011         *(a_tmp+r+c*ord) = _value;\
1012       }\
1013     }\
1014     _copy(a_tmp);\
1015   }\
1016 */\
1017   void _mul_mtx(const T a_m[],T a_tmp[]) { /*OPTIMIZATION*/\
1018     /* this = this * a_m */\
1019     typedef T* Tp;\
1020     Tp tpos,ttpos,rpos,apos,mpos,aapos;\
1021     T _value;\
1022     unsigned int r,c,i;\
1023 \
1024     unsigned int _D = dimension();\
1025 \
1026     tpos = a_tmp;\
1027     for(r=0;r<_D;r++,tpos++) {\
1028       ttpos = tpos;\
1029       rpos = m_vec+r;\
1030       apos = (T*)a_m;\
1031       for(c=0;c<_D;c++,ttpos+=_D,apos+=_D) {\
1032         _value = zero();\
1033         mpos = rpos;\
1034         aapos = apos;\
1035         for(i=0;i<_D;i++,mpos+=_D,aapos++) _value += (*mpos) * (*aapos);\
1036         *ttpos = _value;\
1037       }\
1038     }\
1039     _copy(a_tmp);\
1040   }\
1041 \
1042   void _mul_mtx(const T a_m[]) {\
1043     T* _tmp = new T[dim2()];\
1044     _mul_mtx(a_m,_tmp);\
1045     delete [] _tmp;\
1046   }\
1047 \
1048   void _left_mul_mtx(const T a_m[]) {\
1049     /* this = a_m * this */\
1050     unsigned int _D = dimension();\
1051     T* _tmp = new T[dim2()];\
1052     for(unsigned int r=0;r<_D;r++) {\
1053       for(unsigned int c=0;c<_D;c++) {\
1054         T _value = zero();\
1055         for(unsigned int i=0;i<_D;i++) {\
1056           _value += (*(a_m+r+i*_D)) * (*(m_vec+i+c*_D)); /*optimize.*/\
1057         }\
1058         *(_tmp+r+c*_D) = _value;\
1059       }\
1060     }\
1061     _copy(_tmp);\
1062     delete [] _tmp;\
1063   }\
1064 \
1065   template <class PREC>\
1066   T sub_determinant_prec(unsigned int a_ord,unsigned int aRs[],unsigned int aCs[],\
1067                          const PREC& a_prec,PREC(*a_fabs)(const T&)) const {\
1068     /*WARNING : to optimize, we do not check the content of aRs, aCs.*/\
1069     unsigned int ord = a_ord;\
1070     if(ord==0) return zero();\
1071     else if(ord==1) return value(aRs[0],aCs[0]);\
1072     else if(ord==2) {\
1073       /*return (value(aRs[0],aCs[0]) * value(aRs[1],aCs[1]) -\
1074                value(aRs[1],aCs[0]) * value(aRs[0],aCs[1])); \
1075       Optimize the upper :*/\
1076 \
1077       unsigned int _ord = dimension();\
1078 \
1079       return ( (*(m_vec+aRs[0]+aCs[0]*_ord)) * (*(m_vec+aRs[1]+aCs[1]*_ord)) -\
1080                (*(m_vec+aRs[1]+aCs[0]*_ord)) * (*(m_vec+aRs[0]+aCs[1]*_ord)) );\
1081 \
1082     } else if(ord==3) {\
1083       /*   00 01 02 \
1084            10 11 12 \
1085            20 21 22 \
1086       */\
1087       unsigned int _ord = dimension();\
1088 \
1089       T v00 = *(m_vec+aRs[0]+aCs[0]*_ord);\
1090       T v10 = *(m_vec+aRs[1]+aCs[0]*_ord);\
1091       T v20 = *(m_vec+aRs[2]+aCs[0]*_ord);\
1092       T v01 = *(m_vec+aRs[0]+aCs[1]*_ord);\
1093       T v11 = *(m_vec+aRs[1]+aCs[1]*_ord);\
1094       T v21 = *(m_vec+aRs[2]+aCs[1]*_ord);\
1095       T v02 = *(m_vec+aRs[0]+aCs[2]*_ord);\
1096       T v12 = *(m_vec+aRs[1]+aCs[2]*_ord);\
1097       T v22 = *(m_vec+aRs[2]+aCs[2]*_ord);\
1098       T cof_00 = v11 * v22 - v21 * v12;\
1099       T cof_10 = v01 * v22 - v21 * v02;\
1100       T cof_20 = v01 * v12 - v11 * v02;\
1101       return (v00*cof_00-v10*cof_10+v20*cof_20);\
1102     }\
1103 \
1104     unsigned int rord = ord-1;\
1105     unsigned int* cs = new unsigned int[rord];\
1106     unsigned int* rs = new unsigned int[rord];\
1107 \
1108     T v_rc;\
1109 \
1110     T det = zero();\
1111    {for(unsigned int i=0;i<rord;i++) {cs[i] = aCs[i+1];}}\
1112     unsigned int c = 0;\
1113     /*if(c>=1) cs[c-1] = c-1;*/\
1114 \
1115    {for(unsigned int i=0;i<rord;i++) {rs[i] = aRs[i+1];}}\
1116     bool sg = true; /*c=0+r=0*/\
1117     for(unsigned int r=0;r<ord;r++) {\
1118       if(r>=1) rs[r-1] = aRs[r-1];\
1119       v_rc = value(aRs[r],aCs[c]);\
1120       if(!is_zero(v_rc,a_prec,a_fabs)) {\
1121         T subdet = sub_determinant_prec(rord,rs,cs,a_prec,a_fabs);\
1122         if(sg)\
1123           det += v_rc * subdet;\
1124         else\
1125           det -= v_rc * subdet;\
1126       }\
1127       sg = sg?false:true;\
1128     }\
1129 \
1130     delete [] cs;\
1131     delete [] rs;\
1132 \
1133     return det;\
1134   }\
1135 \
1136   static double zero_fabs(const T& a_number) {return a_number==zero()?0:1000000;}
1137 
1138 #endif