NumArray.h

00001 /*  _________________________________________________________________________
00002  *
00003  *  UTILIB: A utility library for developing portable C++ codes.
00004  *  Copyright (c) 2001, Sandia National Laboratories.
00005  *  This software is distributed under the GNU Lesser General Public License.
00006  *  For more information, see the README file in the top UTILIB directory.
00007  *  _________________________________________________________________________
00008  */
00009 
00010 //
00011 // NumArray.h
00012 //
00020 #ifndef __NumArray_h
00021 #define __NumArray_h
00022 
00023 #if !defined (ANSI_HDRS) || defined(SGI)
00024 #include <math.h>
00025 #else
00026 #include <cmath>
00027 #endif
00028 
00029 #include "SimpleArray.h"
00030 
00031 #ifndef SWIG
00032 template <class T>
00033 class UTILIB_API NumArray;
00034 
00035 template <class T>
00036 class UTILIB_API Num2DArray;
00037 #endif // SWIG
00038 
00039 
00040 #ifdef SWIG
00041 template <class T>
00042 class NumArray: public SimpleArray<T> {
00043 #else
00044 template <class T>
00045 class UTILIB_API NumArray: public SimpleArray<T> {
00046 #endif
00047 
00048   friend Num2DArray<T>;
00049 
00050 public:
00051 
00053   NumArray() : SimpleArray<T>() {}
00065 #ifndef NON_ANSI
00066   explicit 
00067 #endif
00068   NumArray(const size_type len, T *d=((T*)0), const EnumDataOwned o=DataNotOwned)
00069                 : SimpleArray<T>(len,d,o)
00070                 {if (d == NULL) initialize(Data,0,len);}
00072   NumArray(const NumArray& array)
00073                 : SimpleArray<T>(array) {}
00075   ~NumArray() {}
00076 
00078   NumArray<T>& operator=(const NumArray<T>& array)
00079                 {SimpleArray<T>::operator=(array); return *this;}
00081   NumArray<T>& operator=(const T& array)
00082                 {SimpleArray<T>::operator=(array); return *this;}
00083 
00085   void plus  (const NumArray<T>& x, const NumArray<T>& y);
00087   void minus (const NumArray<T>& x, const NumArray<T>& y);
00089   void times (const NumArray<T>& x, const NumArray<T>& y);
00091   void divide(const NumArray<T>& x, const NumArray<T>& y);
00092 
00094   void plus  (const NumArray<T>& x, const T& z);
00096   void minus (const NumArray<T>& x, const T& z);
00098   void times (const NumArray<T>& x, const T& z);
00100   void divide(const NumArray<T>& x, const T& z);
00101 
00103   NumArray<T> operator-    ();
00104  
00106   NumArray<T>& operator+= (const NumArray<T>& x);
00108   NumArray<T>& operator-= (const NumArray<T>& x);
00110   NumArray<T>& operator*= (const NumArray<T>& x);
00112   NumArray<T>& operator/= (const NumArray<T>& x);
00113  
00115   NumArray<T>& operator+=  (const T& z);
00117   NumArray<T>& operator-=  (const T& z);
00119   NumArray<T>& operator*=  (const T& z);
00121   NumArray<T>& operator/=  (const T& z);
00122 
00123 protected:
00124 
00126   void initialize(T* data, const size_type start, const size_type stop);
00127 };
00128  
00129 
00130 
00131 #ifndef SWIG
00132 #define BINARYOP(opname,pseudonym)\
00133 template <class T>\
00134 inline UTILIB_API NumArray<T> opname (const NumArray<T>& a1, const NumArray<T>& a2)\
00135 {\
00136 NumArray<T> res;\
00137 res.pseudonym(a1,a2);\
00138 return res;\
00139 }\
00140 \
00141 template <class T>\
00142 inline UTILIB_API NumArray<T> opname (const NumArray<T>& a1, const T& val)\
00143 {\
00144 NumArray<T> res;\
00145 res.pseudonym(a1,val);\
00146 return res;\
00147 }\
00148 \
00149 template <class T>\
00150 inline UTILIB_API NumArray<T> opname (const T& val, const NumArray<T>& a1)\
00151 {\
00152 NumArray<T> res;\
00153 res.pseudonym(a1,val);\
00154 return res;\
00155 }
00156 
00157 BINARYOP( operator+ , plus )
00158 BINARYOP( operator- , minus )
00159 BINARYOP( operator* , times )
00160 BINARYOP( operator/ , divide )
00161 
00162 #undef BINARYOP
00163 #endif // SWIG
00164 
00165 
00166 /*
00167 template <class T>
00168 T NumArray<T>::operator%(const NumArray<T>& a1, const NumArray<T>& a2)
00169 {
00170 T cum;
00171 T *ptr1, *ptr2;
00172 ptr1 = a1.a->Data;
00173 ptr2 = a2.a->Data;
00174 cum = *ptr1 * *ptr2;
00175 ptr1++; ptr2++;
00176 for (size_type i=1; i<a1.a->len; i++, ptr1++, ptr2++)
00177   cum += *ptr1 * *ptr2;
00178 return cum;
00179 }
00180 */
00181 
00182 
00183 #define BINARYOP(opname,op1,pseudonym, op)\
00184 template <class T>\
00185 void NumArray<T>::pseudonym(const NumArray<T>& a1, const NumArray<T>& a2)\
00186 {\
00187 if (a1.size() != a2.size())\
00188    ErrAbort(errmsg("NumArray<T>::pseudonym : Unequal array lengths %d and %d", a1.size(),a2.size()));\
00189 resize(a1.size());\
00190 T* tmp = Data;\
00191 size_type mylen = size();\
00192 for (size_type i=0; i<mylen; i++)\
00193   tmp[i] = a1[i] op a2[i];\
00194 }\
00195 \
00196 template <class T>\
00197 void NumArray<T>::pseudonym(const NumArray<T>& a1, const T& val)\
00198 {\
00199 resize(a1.size());\
00200 T* tmp = Data;\
00201 size_type mylen = size();\
00202 for (size_type i=0; i<mylen; i++)\
00203   tmp[i] = a1[i] op val;\
00204 }\
00205 \
00206 template <class T>\
00207 NumArray<T>& NumArray<T>::opname(const T& val)\
00208 {\
00209 T* tmp = Data;\
00210 size_type mylen = size();\
00211 for (size_type i=0; i<mylen; i++) \
00212   tmp[i] op1 val;\
00213 return(*this); \
00214 }\
00215 \
00216 template <class T>\
00217 NumArray<T>& NumArray<T>::opname(const NumArray<T>& array)\
00218 {\
00219 T* tmp = Data;\
00220 T* arraytmp = array.Data;\
00221 size_type mylen = size();\
00222 for (size_type i=0; i<mylen; i++) \
00223   tmp[i] op1 arraytmp[i]; \
00224 return(*this); \
00225 }
00226 
00227 
00228 BINARYOP(operator+=,+=,plus, + )
00229 BINARYOP(operator-=,-=,minus, - )
00230 BINARYOP(operator*=,*=,times, * )
00231 BINARYOP(operator/=,/=,divide, / )
00232 
00233 #undef BINARYOP
00234 
00235 
00236 template <class T>
00237 NumArray<T> NumArray<T>::operator-    ()
00238 {
00239 size_type mylen = size();
00240 NumArray<T> res(mylen);
00241 T* tmp = Data;
00242 T* restmp = res.Data;
00243 for (size_type i=0; i<mylen; i++)
00244   restmp[i] = - tmp[i];
00245 return res;
00246 }
00247 
00248 
00249 template <class T>
00250 void NumArray<T>::initialize(T* data, const size_type start, 
00251                                                         const size_type stop)
00252 {
00253 for (size_type i=start; i < stop; i++)
00254   data[i] = ( T ) 0;
00255 }
00256 #endif