00001
00002
00003 #ifndef CH_MATRIX_CLASSES__MATOP_HXX
00004 #define CH_MATRIX_CLASSES__MATOP_HXX
00005
00016 #include <limits.h>
00017 #include <float.h>
00018 #include <assert.h>
00019 #if defined(WITH_BLAS) || defined(BLAS_GENMULT)
00020 extern "C"{
00021 #include "cblas.h"
00022 }
00023 #endif
00024 #include "gb_rand.hxx"
00025 #include "CBconfig.hxx"
00026
00029 namespace CH_Matrix_Classes {
00030
00031
00032
00033
00037
00039 typedef int Integer;
00040
00042 const Integer max_Integer= INT_MAX;
00043
00045 const Integer min_Integer= INT_MIN;
00046
00047
00049 typedef double Real;
00050
00052 const Real max_Real= DBL_MAX;
00053
00055 const Real min_Real= -DBL_MAX;
00056
00058 const Real eps_Real= DBL_EPSILON;
00059
00061
00062
00063
00068
00069
00070 #ifdef WITH_BLAS
00071
00076 inline void mat_xey( Integer len, double *x, const double* y)
00077 {
00078 cblas_dcopy(len,y,1,x,1);
00079 }
00080 #endif
00081
00087 template<class Val>
00088 inline void mat_xey( Integer len, Val *x, const Val* y)
00089 {
00090 const Val* xend=x+len;
00091 for(;x!=xend;)
00092 (*x++)=(*y++);
00093 }
00094
00095 #ifdef WITH_BLAS
00096
00103 inline void mat_xey( Integer len, double *x, const Integer incx,
00104 const double* y, const Integer incy)
00105 {
00106 cblas_dcopy(len,y,incy,x,incx);
00107 }
00108 #endif
00109
00117 template<class Val>
00118 inline void mat_xey( Integer len, Val *x, const Integer incx,
00119 const Val *y, const Integer incy)
00120 {
00121 const Val* xend=x+len*incx;
00122 for(;x!=xend;x+=incx,y+=incy)
00123 (*x)=(*y);
00124 }
00125
00126 #ifdef WITH_BLAS
00127
00131 inline void mat_xemx( Integer len, double *x)
00132 {
00133 cblas_dscal(len,-1.,x,1);
00134 }
00135 #endif
00136
00141 template<class Val>
00142 inline void mat_xemx( Integer len, Val *x)
00143 {
00144 const Val* xend=x+len;
00145 for(;x!=xend;x++)
00146 (*x)=-(*x);
00147 }
00148
00149 #ifdef WITH_BLAS
00150
00155 inline void mat_xemx( Integer len, double *x, const Integer incx)
00156 {
00157 cblas_dscal(len,-1.,x,incx);
00158 }
00159 #endif
00160
00166 template<class Val>
00167 inline void mat_xemx( Integer len, Val *x, const Integer incx)
00168 {
00169 const Val* xend=x+len*incx;
00170 for(;x!=xend;x+=incx)
00171 (*x)=-(*x);
00172 }
00173
00174 #ifdef WITH_BLAS
00175
00180 inline void mat_xemy( Integer len, double *x, const double *y)
00181 {
00182 cblas_dcopy(len,y,1,x,1);
00183 cblas_dscal(len,-1.,x,1);
00184 }
00185 #endif
00186
00192 template<class Val>
00193 inline void mat_xemy( Integer len, Val *x, const Val *y)
00194 {
00195 const Val* xend=x+len;
00196 for(;x!=xend;)
00197 (*x++)=-(*y++);
00198 }
00199
00200 #ifdef WITH_BLAS
00201
00208 inline void mat_xemy( Integer len, double *x, const Integer incx,
00209 const double *y, const Integer incy)
00210 {
00211 cblas_dcopy(len,y,incy,x,incx);
00212 cblas_dscal(len,-1.,x,incx);
00213 }
00214 #endif
00215
00223 template<class Val>
00224 inline void mat_xemy( Integer len, Val *x, const Integer incx,
00225 const Val *y, const Integer incy)
00226 {
00227 const Val* xend=x+len*incx;
00228 for(;x!=xend;x+=incx,y+=incy)
00229 (*x)=-(*y);
00230 }
00231
00232 #ifdef WITH_BLAS
00233
00239 inline void mat_xeya( Integer len, double *x,
00240 const double *y, double a)
00241 {
00242 cblas_dcopy(len,y,1,x,1);
00243 cblas_dscal(len,a,x,1);
00244 }
00245 #endif
00246
00253 template<class Val>
00254 inline void mat_xeya( Integer len, Val *x,
00255 const Val *y, Val a)
00256 {
00257 const Val* xend=x+len;
00258 for(;x!=xend;)
00259 (*x++)=a*(*y++);
00260 }
00261
00262 #ifdef WITH_BLAS
00263
00271 inline void mat_xeya( Integer len, double *x, const Integer incx,
00272 const double *y, const Integer incy,double a)
00273 {
00274 cblas_dcopy(len,y,incy,x,incx);
00275 cblas_dscal(len,a,x,incx);
00276 }
00277 #endif
00278
00287 template<class Val>
00288 inline void mat_xeya( Integer len, Val *x, const Integer incx,
00289 const Val *y, const Integer incy, Val a)
00290 {
00291 const Val* xend=x+len*incx;
00292 for(;x!=xend;x+=incx,y+=incy)
00293 (*x)=a*(*y);
00294 }
00295
00296 #ifdef WITH_BLAS
00297
00302 inline void mat_xpey( Integer len, double *x,
00303 const double *y)
00304 {
00305 cblas_daxpy(len,1.,y,1,x,1);
00306 }
00307 #endif
00308
00314 template<class Val>
00315 inline void mat_xpey( Integer len, Val *x, const Val *y)
00316 {
00317 const Val* xend=x+len;
00318 for(;x!=xend;)
00319 (*x++)+=(*y++);
00320 }
00321
00322 #ifdef WITH_BLAS
00323
00330 inline void mat_xpey( Integer len, double *x, const Integer incx,
00331 const double *y, const Integer incy)
00332 {
00333 cblas_daxpy(len,1.,y,incy,x,incx);
00334 }
00335 #endif
00336
00344 template<class Val>
00345 inline void mat_xpey( Integer len, Val *x, const Integer incx,
00346 const Val *y, const Integer incy)
00347 {
00348 const Val* xend=x+len*incx;
00349 for(;x!=xend;x+=incx,y+=incy)
00350 (*x)+=(*y);
00351 }
00352
00353 #ifdef WITH_BLAS
00354
00359 inline void mat_xmey( Integer len, double *x,
00360 const double *y)
00361 {
00362 cblas_daxpy(len,-1.,y,1,x,1);
00363 }
00364 #endif
00365
00371 template<class Val>
00372 inline void mat_xmey( Integer len, Val *x, const Val *y)
00373 {
00374 const Val* xend=x+len;
00375 for(;x!=xend;)
00376 (*x++)-=(*y++);
00377 }
00378
00379 #ifdef WITH_BLAS
00380
00387 inline void mat_xmey( Integer len, double *x, const Integer incx,
00388 const double *y, const Integer incy)
00389 {
00390 cblas_daxpy(len,-1.,y,incy,x,incx);
00391 }
00392 #endif
00393
00401 template<class Val>
00402 inline void mat_xmey( Integer len, Val *x, const Integer incx,
00403 const Val *y, const Integer incy)
00404 {
00405 const Val* xend=x+len*incx;
00406 for(;x!=xend;x+=incx,y+=incy)
00407 (*x)-=(*y);
00408 }
00409
00415 template<class Val>
00416 inline void mat_xhadey( Integer len, Val *x, const Val *y)
00417 {
00418 const Val* xend=x+len;
00419 for(;x!=xend;)
00420 (*x++)*=(*y++);
00421 }
00422
00428 template<class Val>
00429 inline void mat_xinvhadey( Integer len, Val *x, const Val *y)
00430 {
00431 const Val* xend=x+len;
00432 for(;x!=xend;)
00433 (*x++)/=(*y++);
00434 }
00435
00443 template<class Val>
00444 inline void mat_xhadey( Integer len, Val *x, const Integer incx,
00445 const Val *y, const Integer incy)
00446 {
00447 const Val* xend=x+len*incx;
00448 for(;x!=xend;x+=incx,y+=incy)
00449 (*x)*=(*y);
00450 }
00451
00459 template<class Val>
00460 inline void mat_xinvhadey( Integer len, Val *x, const Integer incx,
00461 const Val *y, const Integer incy)
00462 {
00463 const Val* xend=x+len*incx;
00464 for(;x!=xend;x+=incx,y+=incy)
00465 (*x)/=(*y);
00466 }
00467
00468 #ifdef WITH_BLAS
00469
00475 inline void mat_xpeya( Integer len, Real *x,
00476 const Real *y, Real a)
00477 {
00478 cblas_daxpy(len,a,y,1,x,1);
00479 }
00480 #endif
00481
00488 template<class Val>
00489 inline void mat_xpeya( Integer len, Val *x,
00490 const Val *y, Val a)
00491 {
00492 const Val* xend=x+len;
00493 for(;x!=xend;)
00494 (*x++)+=a*(*y++);
00495 }
00496
00497 #ifdef WITH_BLAS
00498
00506 inline void mat_xpeya( Integer len, Real *x, const Integer incx,
00507 const Real *y, const Integer incy, Real a)
00508 {
00509 cblas_daxpy(len,a,y,incy,x,incx);
00510 }
00511 #endif
00512
00521 template<class Val>
00522 inline void mat_xpeya( Integer len, Val *x, const Integer incx,
00523 const Val *y, const Integer incy, Val a)
00524 {
00525 const Val* xend=x+len*incx;
00526 for(;x!=xend;x+=incx,y+=incy)
00527 (*x)+=a*(*y);
00528 }
00529
00530 #ifdef WITH_BLAS
00531
00538 inline void mat_xbpeya( Integer len, Real *x,
00539 const Real *y, Real a, Real b)
00540 {
00541 cblas_dscal(len,b,x,1);
00542 cblas_daxpy(len,a,y,1,x,1);
00543 }
00544 #endif
00545
00553 template<class Val>
00554 inline void mat_xbpeya( Integer len, Val *x,
00555 const Val *y, Val a,Val b)
00556 {
00557 const Val* xend=x+len;
00558 for(;x!=xend;x++)
00559 (*x)=b*(*x)+a*(*y++);
00560 }
00561
00562 #ifdef WITH_BLAS
00563
00572 inline void mat_xbpeya( Integer len, Real *x, const Integer incx,
00573 const Real *y, const Integer incy, Real a, Real b)
00574 {
00575 cblas_dscal(len,b,x,incx);
00576 cblas_daxpy(len,a,y,incy,x,incx);
00577 }
00578 #endif
00579
00589 template<class Val>
00590 inline void mat_xbpeya( Integer len, Val *x, const Integer incx,
00591 const Val *y, const Integer incy, Val a,Val b)
00592 {
00593 const Val* xend=x+len*incx;
00594 for(;x!=xend;x+=incx,y+=incy)
00595 (*x)+=b*(*x)+a*(*y);
00596 }
00597
00603 template<class Val>
00604 inline void mat_xea( Integer len, Val *x, Val a)
00605 {
00606 const Val* xend=x+len;
00607 for(;x!=xend;)
00608 (*x++)=a;
00609 }
00610
00617 template<class Val>
00618 inline void mat_xea( Integer len, Val *x, const Integer incx,
00619 Val a)
00620 {
00621 const Val* xend=x+len*incx;
00622 for(;x!=xend;x+=incx)
00623 (*x)=a;
00624 }
00625
00631 template<class Val>
00632 inline void mat_xpea( Integer len, Val *x, Val a)
00633 {
00634 const Val* xend=x+len;
00635 for(;x!=xend;)
00636 (*x++)+=a;
00637 }
00638
00645 template<class Val>
00646 inline void mat_xpea( Integer len, Val *x, const Integer incx,
00647 Val a)
00648 {
00649 const Val* xend=x+len*incx;
00650 for(;x!=xend;x+=incx)
00651 (*x)+=a;
00652 }
00653
00654 #ifdef WITH_BLAS
00655
00660 inline void mat_xmultea( Integer len, double *x,double a)
00661 {
00662 cblas_dscal(len,a,x,1);
00663 }
00664 #endif
00665
00671 template<class Val>
00672 inline void mat_xmultea( Integer len, Val *x, Val a)
00673 {
00674 const Val* xend=x+len;
00675 for(;x!=xend;)
00676 (*x++)*=a;
00677 }
00678
00679 #ifdef WITH_BLAS
00680
00686 inline void mat_xmultea( Integer len, double *x, const Integer incx,double a)
00687 {
00688 cblas_dscal(len,a,x,incx);
00689 }
00690 #endif
00691
00698 template<class Val>
00699 inline void mat_xmultea( Integer len, Val *x, const Integer incx,
00700 Val a)
00701 {
00702 const Val* xend=x+len*incx;
00703 for(;x!=xend;x+=incx)
00704 (*x)*=a;
00705 }
00706
00707 #ifdef WITH_BLAS
00708
00713 inline void mat_xdivea( Integer len, double *x,double a)
00714 {
00715 cblas_dscal(len,1./a,x,1);
00716 }
00717 #endif
00718
00724 template<class Val>
00725 inline void mat_xdivea( Integer len, Val *x, Val a)
00726 {
00727 const Val* xend=x+len;
00728 for(;x!=xend;)
00729 (*x++)/=a;
00730 }
00731
00732 #ifdef WITH_BLAS
00733
00739 inline void mat_xdivea( Integer len, double *x, const Integer incx,double a)
00740 {
00741 cblas_dscal(len,1./a,x,incx);
00742 }
00743 #endif
00744
00751 template<class Val>
00752 inline void mat_xdivea( Integer len, Val *x, const Integer incx,
00753 Val a)
00754 {
00755 const Val* xend=x+len*incx;
00756 for(;x!=xend;x+=incx)
00757 (*x)/=a;
00758 }
00759
00765 template<class Val>
00766 inline void mat_xmodea( Integer len, Val *x, Val a)
00767 {
00768 const Val* xend=x+len;
00769 for(;x!=xend;)
00770 (*x++)%=a;
00771 }
00772
00779 template<class Val>
00780 inline void mat_xmodea( Integer len, Val *x, const Integer incx,
00781 Val a)
00782 {
00783 const Val* xend=x+len*incx;
00784 for(;x!=xend;x+=incx)
00785 (*x)%=a;
00786 }
00787
00788 #ifdef WITH_BLAS
00789
00795 inline void mat_xeypz( Integer len, Real *x,
00796 const Real *y,
00797 const Real *z)
00798 {
00799 cblas_dcopy(len,y,1,x,1);
00800 cblas_daxpy(len,1.,z,1,x,1);
00801 }
00802 #endif
00803
00810 template<class Val>
00811 inline void mat_xeypz( Integer len, Val *x,
00812 const Val *y, const Val *z)
00813 {
00814 const Val* xend=x+len;
00815 for(;x!=xend;)
00816 (*x++)=(*y++)+(*z++);
00817 }
00818
00819 #ifdef WITH_BLAS
00820
00829 inline void mat_xeypz( Integer len, Real *x, const Integer incx,
00830 const Real *y, const Integer incy,
00831 const Real *z, const Integer incz)
00832 {
00833 cblas_dcopy(len,y,incy,x,incx);
00834 cblas_daxpy(len,1.,z,incz,x,incx);
00835 }
00836 #endif
00837
00847 template<class Val>
00848 inline void mat_xeypz( Integer len, Val *x, const Integer incx,
00849 const Val *y, const Integer incy,
00850 const Val *z, const Integer incz)
00851 {
00852 const Val* xend=x+len*incx;
00853 for(;x!=xend;x+=incx,y+=incy,z+=incz)
00854 (*x)=(*y)+(*z);
00855 }
00856
00857 #ifdef WITH_BLAS
00858
00864 inline void mat_xeymz( Integer len, Real *x,
00865 const Real *y,
00866 const Real *z)
00867 {
00868 cblas_dcopy(len,y,1,x,1);
00869 cblas_daxpy(len,-1.,z,1,x,1);
00870 }
00871 #endif
00872
00879 template<class Val>
00880 inline void mat_xeymz( Integer len, Val *x,
00881 const Val *y, const Val *z)
00882 {
00883 const Val* xend=x+len;
00884 for(;x!=xend;)
00885 (*x++)=(*y++)-(*z++);
00886 }
00887
00888 #ifdef WITH_BLAS
00889
00898 inline void mat_xeymz( Integer len, Real *x, const Integer incx,
00899 const Real *y, const Integer incy,
00900 const Real *z, const Integer incz)
00901 {
00902 cblas_dcopy(len,y,incy,x,incx);
00903 cblas_daxpy(len,-1.,z,incz,x,incx);
00904 }
00905 #endif
00906
00916 template<class Val>
00917 inline void mat_xeymz( Integer len, Val *x, const Integer incx,
00918 const Val *y, const Integer incy,
00919 const Val *z, const Integer incz)
00920 {
00921 const Val* xend=x+len*incx;
00922 for(;x!=xend;x+=incx,y+=incy,z+=incz)
00923 (*x)=(*y)-(*z);
00924 }
00925
00926 #ifdef WITH_BLAS
00927
00935 inline void mat_xeyapzb( Integer len, Real *x,
00936 const Real *y,
00937 const Real *z, Real a, Real b)
00938 {
00939 cblas_dcopy(len,y,1,x,1);
00940 cblas_dscal(len,a,x,1);
00941 cblas_daxpy(len,b,z,1,x,1);
00942 }
00943 #endif
00944
00953 template<class Val>
00954 inline void mat_xeyapzb( Integer len, Val *x,
00955 const Val *y, const Val *z,Val a,Val b)
00956 {
00957 const Val* xend=x+len;
00958 for(;x!=xend;)
00959 (*x++)=a*(*y++)+b*(*z++);
00960 }
00961
00962 #ifdef WITH_BLAS
00963
00974 inline void mat_xeyapzb( Integer len, Real *x, const Integer incx,
00975 const Real *y, const Integer incy,
00976 const Real *z, const Integer incz, Real a, Real b)
00977 {
00978 cblas_dcopy(len,y,incy,x,incx);
00979 cblas_dscal(len,a,x,incx);
00980 cblas_daxpy(len,b,z,incz,x,incx);
00981 }
00982 #endif
00983
00995 template<class Val>
00996 inline void mat_xeyapzb( Integer len, Val *x, const Integer incx,
00997 const Val *y, const Integer incy,
00998 const Val *z, const Integer incz,Val a,Val b)
00999 {
01000 const Val* xend=x+len*incx;
01001 for(;x!=xend;x+=incx,y+=incy,z+=incz)
01002 (*x)=a*(*y)+b*(*z);
01003 }
01004
01005 #ifdef WITH_BLAS
01006
01012 inline double mat_ip( Integer len, const double *x,const double *y)
01013 {
01014 return cblas_ddot(len,x,1,y,1);
01015 }
01016 #endif
01017
01024 template<class Val>
01025 inline Val mat_ip( Integer len, const Val *x, const Val *y)
01026 {
01027 Val sum=0;
01028 const Val* xend=x+len;
01029 for(;x!=xend;)
01030 sum+=(*x++)*(*y++);
01031 return sum;
01032 }
01033
01034
01035 #ifdef WITH_BLAS
01036
01044 inline double mat_ip( Integer len, const double *x, const Integer incx,
01045 const double *y, const Integer incy)
01046 {
01047 return cblas_ddot(len,x,incx,y,incy);
01048 }
01049 #endif
01050
01059 template<class Val>
01060 inline Val mat_ip( Integer len, const Val *x, const Integer incx,
01061 const Val *y, const Integer incy)
01062 {
01063 Val sum=0;
01064 const Val* xend=x+len*incx;
01065 for(;x!=xend;x+=incx,y+=incy)
01066 sum+=(*x)*(*y);
01067 return sum;
01068 }
01069
01070 #ifdef WITH_BLAS
01071
01076 inline double mat_ip( Integer len, const double *x)
01077 {
01078 return cblas_ddot(len,x,1,x,1);
01079 }
01080 #endif
01081
01087 template<class Val>
01088 inline Val mat_ip( Integer len, const Val *x)
01089 {
01090 Val sum=0;
01091 const Val* xend=x+len;
01092 for(;x!=xend;) {
01093 register Val d=(*x++);
01094 sum+=d*d;
01095 }
01096 return sum;
01097 }
01098
01099
01100 #ifdef WITH_BLAS
01101
01107 inline double mat_ip( Integer len, const double *x, const Integer incx)
01108 {
01109 return cblas_ddot(len,x,incx,x,incx);
01110 }
01111 #endif
01112
01119 template<class Val>
01120 inline Val mat_ip( Integer len, const Val *x, const Integer incx)
01121 {
01122 Val sum=0;
01123 const Val* xend=x+len*incx;
01124 for(;x!=xend;x+=incx) {
01125 register Val d=(*x);
01126 sum+=d*d;
01127 }
01128 return sum;
01129 }
01130
01136 template<class Val>
01137 inline Val mat_sum( Integer len, const Val *x)
01138 {
01139 Val sum=0;
01140 const Val* xend=x+len;
01141 for(;x!=xend;)
01142 sum+=(*x++);
01143 return sum;
01144 }
01145
01152 template<class Val>
01153 inline Val mat_sum( Integer len, const Val *x,const Integer incx)
01154 {
01155 Val sum=0;
01156 const Val* xend=x+len*incx;
01157 for(;x!=xend;x+=incx)
01158 sum+=(*x);
01159 return sum;
01160 }
01161
01162 #ifdef WITH_BLAS
01163
01168 inline void mat_swap( Integer len, double *x, double *y)
01169 {
01170 cblas_dswap(len,x,1,y,1);
01171 }
01172 #endif
01173
01179 template<class Val>
01180 inline void mat_swap( Integer len, Val *x, Val *y)
01181 {
01182 const Val* xend=x+len;
01183 for(;x!=xend;)
01184 {Val h=*x;(*x++)=*y;(*y++)=h;}
01185 }
01186
01187 #ifdef WITH_BLAS
01188
01195 inline void mat_swap( Integer len, double *x, const Integer incx, double *y, const Integer incy)
01196 {
01197 cblas_dswap(len,x,incx,y,incy);
01198 }
01199 #endif
01200
01208 template<class Val>
01209 inline void mat_swap( Integer len, Val *x, const Integer incx,
01210 Val *y, const Integer incy)
01211 {
01212 const Val* xend=x+len*incx;
01213 for(;x!=xend;x+=incx,y+=incy)
01214 {Val h=*x;(*x)=*y;(*y)=h;}
01215 }
01216
01218
01219
01222 template<class Val>
01223 struct mat_less_index {
01224 mat_less_index( const Val* values ):
01225 _values(values)
01226 {}
01227
01228 bool operator()( Integer i, Integer j) const {
01229 return _values[i] < _values[j];
01230 }
01231
01232 private:
01233 const Val* _values;
01234
01235 };
01236
01237
01238
01239
01240
01245
01246
01247
01248
01249
01250
01251
01256 extern CH_Tools::GB_rand mat_randgen;
01257
01258
01259
01260
01261
01262
01263
01266 extern std::ostream* materrout;
01267
01269
01270
01271
01272
01273
01274
01275
01287
01288
01289
01290
01291
01293 enum Mtype {
01294 MTglobalfun,
01295 MTindexmatrix,
01296 MTmatrix,
01297 MTsymmetric,
01298 MTsparse,
01299 MTsparsesym
01300 };
01301
01302
01303
01304
01305
01307 enum MEcode {
01308 ME_unspec,
01309 ME_range,
01310 ME_mem,
01311 ME_dim,
01312 ME_num,
01313 ME_warning
01314 };
01315
01317 class MatrixError
01318 {
01319 public:
01320 MEcode code;
01321 const char *message;
01322 Mtype mtype;
01323
01325 MatrixError(MEcode c=ME_unspec,const char *mes=0,Mtype mt=MTmatrix):
01326 code(c),message(mes),mtype(mt){}
01327 };
01328
01330 class MErange:public MatrixError
01331 {
01332 public:
01333 Integer nr,r;
01334 Integer nc,c;
01335 MErange(Integer inr,Integer ir,Integer inc,Integer ic,const char *mes=0,Mtype mt=MTmatrix):
01336 MatrixError(ME_range,mes,mt),nr(inr),r(ir),nc(inc),c(ic){}
01337 };
01338
01340 class MEmem:public MatrixError
01341 {
01342 public:
01343 Integer size;
01344 MEmem(Integer s,const char *mes=0,Mtype mt=MTmatrix):
01345 MatrixError(ME_mem,mes,mt),size(s){}
01346 };
01347
01349 class MEdim:public MatrixError
01350 {
01351 public:
01352 Integer nr1, nc1, nr2, nc2;
01353 MEdim(Integer r1,Integer c1,Integer r2,Integer c2,const char *mes=0,Mtype mt=MTmatrix):
01354 MatrixError(ME_dim,mes,mt),nr1(r1),nc1(c1),nr2(r2),nc2(c2){}
01355 };
01356
01358 int MEmessage(const MatrixError&);
01359
01360
01361
01362
01363
01364
01365 #if (CONICBUNDLE_DEBUG>=1)
01366
01368 template<class Mat>
01369 inline void chk_init(const Mat& A)
01370 {
01371 if (!A.get_init())
01372 MEmessage(MatrixError(ME_unspec,"Matrix not initialized",A.get_mtype()));
01373 }
01374
01376 template<class Mat1,class Mat2>
01377 inline void chk_add(const Mat1& A,const Mat2& B)
01378 {
01379 chk_init(A); chk_init(B);
01380 if ((A.dim()==Integer(0))&&(B.dim()==Integer(0))) return;
01381 if ((A.rowdim()!=B.rowdim())||(A.coldim()!=B.coldim()))
01382 MEmessage(MEdim(A.rowdim(),A.coldim(),B.rowdim(),B.coldim(),
01383 "dimensions do not match in additive expression",
01384 A.get_mtype()));
01385 }
01386
01388 template<class Mat1,class Mat2>
01389 inline void chk_mult(const Mat1& A,const Mat2& B,int atrans=0,int btrans=0)
01390 {
01391 chk_init(A); chk_init(B);
01392 if ((A.dim()==Integer(0))&&(B.dim()==Integer(0))) return;
01393 if (
01394 ((atrans==0)&&(btrans==0)&&(A.coldim()!=B.rowdim()))
01395 ||
01396 ((atrans==1)&&(btrans==0)&&(A.rowdim()!=B.rowdim()))
01397 ||
01398 ((atrans==0)&&(btrans==1)&&(A.coldim()!=B.coldim()))
01399 ||
01400 ((atrans==1)&&(btrans==1)&&(A.rowdim()!=B.coldim()))
01401 )
01402 MEmessage(MEdim(A.rowdim(),A.coldim(),B.rowdim(),B.coldim(),
01403 "dimensions do not match in multiplicative expression",
01404 A.get_mtype()));
01405 }
01406
01408 template<class Mat1,class Mat2>
01409 inline void chk_rowseq(const Mat1& A,const Mat2& B)
01410 {
01411 chk_init(A); chk_init(B);
01412 if ((A.dim()==Integer(0))&&(B.dim()==Integer(0))) return;
01413
01414 if (A.rowdim()!=B.rowdim())
01415 MEmessage(MEdim(A.rowdim(),A.coldim(),B.rowdim(),B.coldim(),
01416 "number of rows do not agree",
01417 A.get_mtype()));
01418 }
01419
01421 template<class Mat1,class Mat2>
01422 inline void chk_colseq(const Mat1& A,const Mat2& B)
01423 {
01424 chk_init(A); chk_init(B);
01425 if ((A.dim()==Integer(0))&&(B.dim()==Integer(0))) return;
01426 if (A.coldim()!=B.coldim())
01427 MEmessage(MEdim(A.rowdim(),A.coldim(),B.rowdim(),B.coldim(),
01428 "number of columns do not agree",
01429 A.get_mtype()));
01430 }
01431
01433 inline void chk_range(Integer r,Integer c,Integer ubr,Integer ubc)
01434 {
01435 if ((r<0)||(c<0)||
01436 ((ubr>=0)&&(r>=ubr))||
01437 ((ubc>=0)&&(c>=ubc)))
01438 MEmessage(MErange(r,ubr,c,ubc,"index out of range or negative dimension"));
01439 }
01440
01442 template<class Mat>
01443 inline void chk_set_init(Mat &A,bool val){A.set_init(val);}
01444
01445 #else
01446
01447
01448
01450 #define chk_init(x)
01452 #define chk_add(x,y)
01454 template<class Mat1,class Mat2>
01455 inline void chk_mult(const Mat1&,const Mat2&,int =0,int =0){}
01457 #define chk_rowseq(x,y)
01459 #define chk_colseq(x,y)
01461 #define chk_range(i,j,ubi,ubj)
01463 #define chk_set_init(x,y)
01464
01465 #endif
01466
01468
01469 }
01470
01471 #endif