00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00021 #ifndef __Num2DArray_h
00022 #define __Num2DArray_h
00023
00024 #ifdef __GNUC__
00025 #pragma interface
00026 #endif
00027
00028 #ifndef ANSI_HDRS
00029 #include <math.h>
00030 #else
00031 #include <cmath>
00032 #endif
00033
00034 #include "_math.h"
00035 #include "NumArray.h"
00036 #include "Simple2DArray.h"
00037
00038 template <class T>
00039 class UTILIB_API Num2DArray;
00040
00041
00042 template <class T>
00043 Num2DArray<T> operator% (const Num2DArray<T> & m1, const Num2DArray<T> & m2)
00044 {
00045 static Num2DArray<T> temp_mat(m1.nrows(), m2.ncols());
00046 matmult(temp_mat, m1, m2);
00047 return temp_mat;
00048 }
00049
00050
00051 template <class T>
00052 NumArray<T> operator% (const Num2DArray<T> & m, const NumArray<T> & v)
00053 {
00054 static NumArray<T> temp_vec(m.nrows());
00055 matmult(temp_vec, m, v);
00056 return temp_vec;
00057 }
00058
00059
00060 template <class T>
00061 NumArray<T> operator% (const NumArray<T> & v, const Num2DArray<T> & m)
00062 {
00063 static NumArray<T> temp_vec(m.ncols());
00064 matmult(temp_vec,v,m);
00065 return temp_vec;
00066 }
00067
00068
00069 template <class T>
00070 void matmult(Num2DArray<T>& res, const Num2DArray<T> & m1,
00071 const Num2DArray<T> & m2)
00072 {
00073 if (m1.ncols() != m2.nrows())
00074 ErrAbort(errmsg("matmult: ncols(M1) != nrows(M2) %d %d",m1.ncols(),
00075 m2.nrows()) );
00076 if ((res.nrows() != m1.nrows()) || (res.ncols() != m2.ncols()))
00077 ErrAbort("matmult: bad dimensions for result.");
00078
00079 T temp;
00080 size_type M1Ncols = m1.ncols();
00081 size_type M1Nrows = m1.nrows();
00082 size_type M2Ncols = m2.ncols();
00083 for (size_type i=0; i<M1Nrows; i++){
00084 for (size_type j=0; j<M2Ncols; j++){
00085 temp = m1[i][0] * m2[0][j];
00086 for (size_type k=1; k<M1Ncols; k++){
00087 temp += m1[i][k] * m2[k][j];
00088 }
00089 res[i][j] = temp;
00090 }
00091 }
00092 }
00093
00094
00095 template <class T>
00096 void matmult(NumArray<T>& res, const Num2DArray<T>& m, const NumArray<T>& v)
00097 {
00098 if (m.ncols() != v.size())
00099 ErrAbort( "matmult: ncols(M) != size(V)" );
00100 if (res.size() != m.nrows())
00101 ErrAbort( "matmult: size(RES) != nrows(M)" );
00102
00103 T temp;
00104 size_type NRows = m.nrows();
00105 size_type NCols = v.size();
00106 for (size_type i=0; i<NRows; i++) {
00107 temp = m[i][0] * v[0];
00108 for (size_type j=1; j<NCols; j++)
00109 temp += m[i][j] * v[j];
00110 res[i] = temp;
00111 }
00112 }
00113
00114
00115 template <class T>
00116 void matmult(NumArray<T>& res, const NumArray<T> & v, const Num2DArray<T> & m)
00117 {
00118 if (m.nrows() != v.size())
00119 ErrAbort( "matmult: size(V) != nrows(M)" );
00120 if (res.size() != m.ncols())
00121 ErrAbort( "matmult: size(RES) != ncols(M)" );
00122
00123 T temp;
00124 size_type NRows = v.size();
00125 size_type NCols = m.ncols();
00126 for (size_type i=0; i<NCols; i++) {
00127 temp = m[0][i] * v[0];
00128 for (size_type j=1; j<NRows; j++)
00129 temp += m[j][i] * v[j];
00130 res[i] = temp;
00131 }
00132 }
00133
00134
00135
00136 #ifdef SWIG
00137 template <class T>
00138 class Num2DArray: public Simple2DArray<T>
00139 #else
00140 template <class T>
00141 class UTILIB_API Num2DArray: public Simple2DArray<T>
00142 #endif
00143 {
00144 public:
00145
00147 Num2DArray() : Simple2DArray<T>() {}
00153 Num2DArray(const BasicArray<T>& array, const int nrows=1,
00154 const EnumDataOwned own=DataNotOwned)
00155 : Simple2DArray<T>(array,nrows,own) {}
00161 Num2DArray(const int nrows, const int ncols, T *d=((T*)0),
00162 const EnumDataOwned own=DataNotOwned)
00163 : Simple2DArray<T>(nrows,ncols,d,own) {}
00169 Num2DArray(const int nrows, const int ncols, const BasicArray<T>& array,
00170 const EnumDataOwned own=DataNotOwned)
00171 : Simple2DArray<T>(nrows,ncols,array,own) {}
00173 Num2DArray(const Num2DArray& array)
00174 : Simple2DArray<T>(array) {}
00175
00177 Num2DArray<T>& operator=(const Num2DArray<T>& array)
00178 {Simple2DArray<T>::operator=(array); return *this;}
00180 Num2DArray<T>& operator=(const T& array)
00181 {Simple2DArray<T>::operator=(array); return *this;}
00182
00183
00185 void plus (const Num2DArray<T>& x, const Num2DArray<T>& y);
00187 void minus (const Num2DArray<T>& x, const Num2DArray<T>& y);
00189 void times (const Num2DArray<T>& x, const Num2DArray<T>& y);
00191 void divide(const Num2DArray<T>& x, const Num2DArray<T>& y);
00192
00194 void plus (const Num2DArray<T>& x, const NumArray<T>& y);
00196 void minus (const Num2DArray<T>& x, const NumArray<T>& y);
00198 void times (const Num2DArray<T>& x, const NumArray<T>& y);
00200 void divide(const Num2DArray<T>& x, const NumArray<T>& y);
00201
00203 void plus (const Num2DArray<T>& x, const T& z);
00205 void minus (const Num2DArray<T>& x, const T& z);
00207 void times (const Num2DArray<T>& x, const T& z);
00209 void divide(const Num2DArray<T>& x, const T& z);
00210
00212 Num2DArray<T> operator- ();
00213
00215 Num2DArray<T>& operator+= (const Num2DArray<T>& x);
00217 Num2DArray<T>& operator-= (const Num2DArray<T>& x);
00219 Num2DArray<T>& operator*= (const Num2DArray<T>& x);
00221 Num2DArray<T>& operator/= (const Num2DArray<T>& x);
00222
00224 Num2DArray<T>& operator+= (const NumArray<T>& y);
00226 Num2DArray<T>& operator-= (const NumArray<T>& y);
00228 Num2DArray<T>& operator*= (const NumArray<T>& y);
00230 Num2DArray<T>& operator/= (const NumArray<T>& y);
00231
00233 Num2DArray<T>& operator+= (const T& z);
00235 Num2DArray<T>& operator-= (const T& z);
00237 Num2DArray<T>& operator*= (const T& z);
00239 Num2DArray<T>& operator/= (const T& z);
00240
00241 friend void matmult<>(Num2DArray<T>& res, const Num2DArray<T>&,
00242 const Num2DArray<T>&);
00243 friend void matmult<>(NumArray<T>& res, const Num2DArray<T>&,
00244 const NumArray<T>&);
00245 friend void matmult<>(NumArray<T>& res, const NumArray<T>&,
00246 const Num2DArray<T>&);
00247 friend Num2DArray<T> operator%<>(const Num2DArray<T> &, const Num2DArray<T> &);
00248 friend NumArray<T> operator%<>(const Num2DArray<T> &, const NumArray<T> &);
00249 friend NumArray<T> operator%<>(const NumArray<T> &, const Num2DArray<T> &);
00250
00251 };
00252
00253
00254
00255
00256 #define BINARYOP(opname,pseudonym)\
00257 template <class T>\
00258 inline UTILIB_API Num2DArray<T> opname (const Num2DArray<T>& a1, const Num2DArray<T>& a2)\
00259 {\
00260 Num2DArray<T> res;\
00261 res.pseudonym(a1,a2);\
00262 return res;\
00263 }\
00264 \
00265 template <class T>\
00266 inline UTILIB_API Num2DArray<T> opname (const Num2DArray<T>& a1, const NumArray<T>& val)\
00267 {\
00268 Num2DArray<T> res;\
00269 res.pseudonym(a1,val);\
00270 return res;\
00271 }\
00272 \
00273 template <class T>\
00274 inline UTILIB_API Num2DArray<T> opname (const NumArray<T>& val, const Num2DArray<T>& a1)\
00275 {\
00276 Num2DArray<T> res;\
00277 res.pseudonym(a1,val);\
00278 return res;\
00279 }\
00280 \
00281 template <class T>\
00282 inline UTILIB_API Num2DArray<T> opname (const Num2DArray<T>& a1, const T& val)\
00283 {\
00284 Num2DArray<T> res;\
00285 res.pseudonym(a1,val);\
00286 return res;\
00287 }\
00288 \
00289 template <class T>\
00290 inline UTILIB_API Num2DArray<T> opname (const T& val, const Num2DArray<T>& a1)\
00291 {\
00292 Num2DArray<T> res;\
00293 res.pseudonym(a1,val);\
00294 return res;\
00295 }
00296
00297 BINARYOP( operator+ , plus )
00298 BINARYOP( operator- , minus )
00299 BINARYOP( operator* , times )
00300 BINARYOP( operator/ , divide )
00301
00302 #undef BINARYOP
00303
00304
00305 #define BINARYOP(opname,op1,pseudonym, op)\
00306 template <class T>\
00307 void Num2DArray<T>::pseudonym(const Num2DArray<T>& a1, const Num2DArray<T>& a2)\
00308 {\
00309 if ((a1.nrows() != a2.nrows()) || (a1.ncols() != a2.ncols()))\
00310 ErrAbort(errmsg("Num2DArray<T>::pseudonym : Unequal 2D array sizes %dx%d and %dx%d",a1.nrows(),a1.ncols(),a2.nrows(),a2.ncols()));\
00311 resize(a1.nrows(),a2.ncols());\
00312 for (size_type i=0; i<a->Nrows; i++)\
00313 for (size_type j=0; j<a->Ncols; j++)\
00314 a->Data[i][j] = a1[i][j] op a2[i][j];\
00315 }\
00316 \
00317 template <class T>\
00318 void Num2DArray<T>::pseudonym(const Num2DArray<T>& a1, const NumArray<T>& array)\
00319 {\
00320 if (a1.ncols() != array.size())\
00321 ErrAbort(errmsg("Num2DArray<T>::pseudonym : Number of columns %d does not equal array length %d", a1.ncols(), array.size()));\
00322 resize(a1.nrows(),a1.ncols());\
00323 for (size_type i=0; i<a->Nrows; i++)\
00324 for (size_type j=0; j<a->Ncols; j++)\
00325 a->Data[i][j] = a1[i][j] op array[j];\
00326 }\
00327 \
00328 template <class T>\
00329 void Num2DArray<T>::pseudonym(const Num2DArray<T>& a1, const T& val)\
00330 {\
00331 resize(a1.nrows(),a1.ncols());\
00332 for (size_type i=0; i<a->Nrows; i++)\
00333 for (size_type j=0; j<a->Ncols; j++)\
00334 a->Data[i][j] = a1[i][j] op val;\
00335 }\
00336 template <class T>\
00337 Num2DArray<T>& Num2DArray<T>::opname(const Num2DArray<T>& a1)\
00338 {\
00339 if ((nrows() != a1.nrows()) || (ncols() != a1.ncols()))\
00340 ErrAbort(errmsg("Num2DArray<T>::opname : Unequal 2D array sizes %dx%d and %dx%d",nrows(),ncols(),a1.nrows(),a1.ncols()));\
00341 for (size_type i=0; i<nrows(); i++)\
00342 for (size_type j=0; j<ncols(); j++)\
00343 a->Data[i][j] op1 a1.a->Data[i][j];\
00344 return *this;\
00345 }\
00346 \
00347 template <class T>\
00348 Num2DArray<T>& Num2DArray<T>::opname(const NumArray<T>& a1)\
00349 {\
00350 if (ncols() != a1.size())\
00351 ErrAbort(errmsg("Num2DArray<T>::opname : Number of columns %d does not equal array length %d", ncols(), a1.size()));\
00352 for (size_type i=0; i<nrows(); i++)\
00353 for (size_type j=0; j<ncols(); j++)\
00354 a->Data[i][j] op1 a1.data()[j];\
00355 return *this;\
00356 }\
00357 \
00358 template <class T>\
00359 Num2DArray<T>& Num2DArray<T>::opname(const T& val)\
00360 {\
00361 for (size_type i=0; i<nrows(); i++)\
00362 for (size_type j=0; j<ncols(); j++)\
00363 a->Data[i][j] op1 val;\
00364 return *this;\
00365 }
00366
00367 BINARYOP(operator+=,+=,plus, + )
00368 BINARYOP(operator-=,-=,minus, - )
00369 BINARYOP(operator*=,*=,times, * )
00370 BINARYOP(operator/=,/=,divide, / )
00371
00372 #undef BINARYOP
00373
00374
00375 template <class T>
00376 Num2DArray<T> Num2DArray<T>::operator- ()
00377 {
00378 Num2DArray<T> res;
00379 for (size_type i=0; i<a->Nrows; i++)
00380 for (size_type j=0; j<a->Ncols; j++)
00381 res.a->Data[i][j] = - a->Data[i][j];
00382 return res;
00383 }
00384
00385
00386 #endif