Array.inl

Go to the documentation of this file.
00001 //Copyright (c) 2004-2005, Baris Sumengen
00002 //All rights reserved.
00003 //
00004 // CIMPL Matrix Performance Library
00005 //
00006 //Redistribution and use in source and binary
00007 //forms, with or without modification, are
00008 //permitted provided that the following
00009 //conditions are met:
00010 //
00011 //    * No commercial use is allowed. 
00012 //    This software can only be used
00013 //    for non-commercial purposes. This 
00014 //    distribution is mainly intended for
00015 //    academic research and teaching.
00016 //    * Redistributions of source code must
00017 //    retain the above copyright notice, this
00018 //    list of conditions and the following
00019 //    disclaimer.
00020 //    * Redistributions of binary form must
00021 //    mention the above copyright notice, this
00022 //    list of conditions and the following
00023 //    disclaimer in a clearly visible part 
00024 //    in associated product manual, 
00025 //    readme, and web site of the redistributed 
00026 //    software.
00027 //    * Redistributions in binary form must
00028 //    reproduce the above copyright notice,
00029 //    this list of conditions and the
00030 //    following disclaimer in the
00031 //    documentation and/or other materials
00032 //    provided with the distribution.
00033 //    * The name of Baris Sumengen may not be
00034 //    used to endorse or promote products
00035 //    derived from this software without
00036 //    specific prior written permission.
00037 //
00038 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
00039 //HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00040 //EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
00041 //NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00042 //MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00043 //PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00044 //CONTRIBUTORS BE LIABLE FOR ANY
00045 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00046 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00047 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00048 //OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00049 //DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00050 //HOWEVER CAUSED AND ON ANY THEORY OF
00051 //LIABILITY, WHETHER IN CONTRACT, STRICT
00052 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00053 //OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00054 //OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00055 //POSSIBILITY OF SUCH DAMAGE.
00056 
00057 
00058 
00059 
00060 namespace CIMPL
00061 {
00062 
00063 
00064 // Template Implementation
00065 
00066 
00067 template< class T >
00068 Array<T>::Array() 
00069         : ndims(0), length(0)
00070 {
00071         dims = 0;
00072         data = 0;
00073         clean = 0;
00074 
00075 }
00076 
00077 
00078 template< class T >
00079 Array<T>::Array(const int xdim)
00080 {
00081         if(xdim < 1)
00082         {
00083                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00084                 Utility::RunTimeError("All array dimensions should be larger than 0!");
00085         }
00086 
00087         ndims = 1;
00088         length = xdim;
00089         dims = new (std::nothrow) int[1];
00090         Utility::CheckPointer(dims);
00091         dims[0] = xdim;
00092         data = new (std::nothrow) T[length];
00093         Utility::CheckPointer(data);
00094 
00095         clean = new (std::nothrow) Cleaner<T>(data);
00096         Utility::CheckPointer(clean);
00097 }
00098 
00099 
00100 template< class T >
00101 Array<T>::Array(const int xdim, const int ydim)
00102 {
00103         if(xdim < 1 || ydim < 1)
00104         {
00105                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00106                 Utility::RunTimeError("All array dimensions should be larger than 0!");
00107         }
00108 
00109         ndims = 2;
00110         length = xdim*ydim;
00111         dims = new (std::nothrow) int[2];
00112         Utility::CheckPointer(dims);
00113         dims[0] = xdim;
00114         dims[1] = ydim;
00115         data = new (std::nothrow) T[length];
00116         Utility::CheckPointer(data);
00117 
00118         clean = new (std::nothrow) Cleaner<T>(data);
00119         Utility::CheckPointer(clean);
00120         
00121 }
00122 
00123 
00124 template< class T >
00125 Array<T>::Array(const int xdim, const int ydim, const int zdim)
00126 {
00127         if(xdim < 1 || ydim < 1 || zdim < 1)
00128         {
00129                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00130                 Utility::RunTimeError("All array dimensions should be larger than 0!");
00131         }
00132         ndims = 3;
00133         length = xdim*ydim*zdim;
00134         dims = new (std::nothrow) int[3];
00135         Utility::CheckPointer(dims);
00136         dims[0] = xdim;
00137         dims[1] = ydim;
00138         dims[2] = zdim;
00139         data = new (std::nothrow) T[length];
00140         Utility::CheckPointer(data);
00141 
00142         clean = new (std::nothrow) Cleaner<T>(data);
00143         Utility::CheckPointer(clean);
00144 
00145 }
00146 
00147 
00148 template< class T >
00149 Array<T>::Array(const int xdim, const int ydim, const int zdim, const int extradim, ...)
00150 {
00151         int *temp = new (std::nothrow) int[10];
00152         Utility::CheckPointer(temp);
00153         
00154         temp[0] = xdim;
00155         temp[1] = ydim;
00156         temp[2] = zdim;
00157         temp[3] = extradim;
00158 
00159         va_list argptr;
00160         va_start(argptr, extradim);
00161         int i = 4;
00162         int a;
00163         while((a = va_arg(argptr, int)) > 0 && i<10)
00164         {
00165                 temp[i] = a;
00166                 i++;
00167         }
00168         va_end(argptr);
00169 
00170         if(a>=0)
00171         {
00172                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00173                 Utility::RunTimeError("To create multidimensional arrays of dimension 4 or higher, an extra dimension should be entered as -1 at the end. Dimensionality of arrays cannot exceed 10 !");
00174         }
00175 
00176         ndims = i;
00177         length = 1;
00178         dims = new (std::nothrow) int[ndims];
00179         Utility::CheckPointer(dims);
00180 
00181         for(int j=0;j<ndims;j++)
00182         {
00183                 if(temp[j] < 1)
00184                 {
00185                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00186                         Utility::RunTimeError("All array dimensions should be larger than 1!");
00187                 }
00188 
00189                 length *= temp[j];
00190                 dims[j] = temp[j];
00191         }
00192         data = new (std::nothrow) T[length];
00193         Utility::CheckPointer(data);
00194 
00195         clean = new (std::nothrow) Cleaner<T>(data);
00196         Utility::CheckPointer(clean);
00197         
00198 }
00199 
00200 
00201 template< class T >
00202 Array<T>::Array(const int _ndims, const int* _dims) 
00203         : ndims(_ndims)
00204 {
00205         dims = new (std::nothrow) int[ndims];
00206         Utility::CheckPointer(dims);
00207         
00208         length = 1;
00209         for(int j=0;j<ndims;j++)
00210         {
00211                 dims[j] = _dims[j];
00212                 length *= _dims[j];
00213         }
00214         data = new (std::nothrow) T[length];
00215         Utility::CheckPointer(data);
00216 
00217         clean = new (std::nothrow) Cleaner<T>(data);
00218         Utility::CheckPointer(clean);
00219 
00220 }
00221 
00222 
00223 // copies only the data pointer.
00224 template< class T >
00225 Array<T>::Array(Array<T> &m) 
00226         : ndims(m.ndims), length(m.length)
00227 {
00228         dims = new (std::nothrow) int[ndims];
00229         Utility::CheckPointer(dims);
00230         
00231         for(int j=0;j<ndims;j++)
00232         {
00233                 dims[j] = m.dims[j];
00234         }
00235 
00236         data = m.data;
00237 
00238         clean = new (std::nothrow) Cleaner<T>(data);
00239         Utility::CheckPointer(clean);
00240 
00241 }
00242 
00243 
00244 template< class T >
00245 Array<T>::~Array()
00246 {
00247 //      cout << "Array destroyed" << endl;
00248         delete [] dims;
00249         
00250         // Collect garbage
00251         delete clean;
00252 }
00253 
00254 
00255 // Useful for passing data to third party libraries.
00256 template< class T >
00257 inline const T* Array<T>::DataPtr()
00258 {
00259         return data;
00260 }
00261 
00262 template< class T >
00263 inline T* Array<T>::Data()
00264 {
00265         return data;
00266 }
00267 
00268 
00269 
00270 template< class T >
00271 Array<T> Array<T>::Clone() const
00272 {
00273         Array<T> temp(this->ndims, this->dims);
00274 
00275         // memcopy here...
00276         for(int j=0;j<temp.length;j++)
00277         {
00278                 temp.data[j] = this->data[j];
00279         }
00280 
00281 
00282         return temp;
00283 }
00284 
00285 
00286 
00287 
00288 
00289 
00290 template< class T >
00291 inline const int Array<T>::XDim() const
00292 {
00293         return dims[0];
00294 }
00295 
00296 template< class T >
00297 inline const int Array<T>::YDim() const
00298 {
00299         if(ndims < 2)
00300         {
00301                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00302                 Utility::RunTimeError("YDim(): Number of dimensions is less than 2!");
00303         }
00304         return dims[1];
00305 }
00306 
00307 template< class T >
00308 inline const int Array<T>::ZDim() const
00309 {
00310         if(ndims < 3)
00311         {
00312                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00313                 Utility::RunTimeError("ZDim(): Number of dimensions is less than 3!");
00314         }
00315         return dims[2];
00316 }
00317 
00318 template< class T >
00319 inline const int* Array<T>::Dims() const
00320 {
00321         return dims;
00322 }
00323 
00324 template< class T >
00325 inline const int* Array<T>::Size() const
00326 {
00327         return dims;
00328 }
00329 
00330 template< class T >
00331 inline int Array<T>::Length() const
00332 {
00333         return length;
00334 }
00335 
00336 template< class T >
00337 inline int Array<T>::NDims() const
00338 {
00339         return ndims;
00340 }
00341 
00342 template< class T >
00343 inline void Array<T>::Init(const T init)
00344 {
00345         for(int i=0;i<length;i++)
00346         {
00347                 data[i] = init;
00348         }
00349 }
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 template< class T >
00364 bool Array<T>::IsCompatible(Array<T>& m1, Array<T>& m2)
00365 {
00366         bool temp = true;
00367         if(m1.ndims != m2.ndims)
00368         {
00369                 temp = false;
00370         }
00371         else
00372         {
00373                 for(int i=0; i<m1.ndims; i++)
00374                 {
00375                         if(m1.dims[i] != m2.dims[i])
00376                         {
00377                                 temp = false;
00378                                 break;
00379                         }
00380                 }
00381         }
00382 
00383         return temp;
00384 }
00385 
00386 
00387 
00388 
00389 
00390 // Boolean Operations...
00391 template< class T >
00392 Array<int> Array<T>::And(Array<T>& m1, Array<T>& m2)
00393 {
00394         if(!Array<T>::IsCompatible(m1, m2))
00395         {
00396                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00397                 Utility::RunTimeError("Array sizes are not compatible!");
00398         }
00399 
00400         Array<int> temp(m1.ndims, m1.dims);
00401         for(int i=0;i<temp.Length();i++)
00402         {
00403                 temp[i] = (m1.data[i] != 0 && m2.data[i] != 0) ? 1 : 0;
00404         }
00405         
00406         return temp;
00407 }
00408 
00409 
00410 template< class T >
00411 Array<int> Array<T>::Or(Array<T>& m1, Array<T>& m2)
00412 {
00413         if(!Array<T>::IsCompatible(m1, m2))
00414         {
00415                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00416                 Utility::RunTimeError("Array sizes are not compatible!");
00417         }
00418 
00419         Array<int> temp(m1.ndims, m1.dims);
00420         for(int i=0;i<temp.Length();i++)
00421         {
00422                 temp[i] = (m1.data[i] == 0 && m2.data[i] == 0) ? 0 : 1;
00423         }
00424         
00425         return temp;
00426 }
00427 
00428 
00429 template< class T >
00430 Array<int> Array<T>::Lt(Array<T>& m1, Array<T>& m2)
00431 {
00432         if(!Array<T>::IsCompatible(m1, m2))
00433         {
00434                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00435                 Utility::RunTimeError("Array sizes are not compatible!");
00436         }
00437 
00438         Array<int> temp(m1.ndims, m1.dims);
00439         for(int i=0;i<temp.Length();i++)
00440         {
00441                 temp[i] = (m1.data[i] < m2.data[i]) ? 1 : 0;
00442         }
00443         
00444         return temp;
00445 }
00446 
00447 
00448 template< class T >
00449 Array<int> Array<T>::Gt(Array<T>& m1, Array<T>& m2)
00450 {
00451         if(!Array<T>::IsCompatible(m1, m2))
00452         {
00453                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00454                 Utility::RunTimeError("Array sizes are not compatible!");
00455         }
00456 
00457         Array<int> temp(m1.ndims, m1.dims);
00458         for(int i=0;i<temp.Length();i++)
00459         {
00460                 temp[i] = (m1.data[i] > m2.data[i]) ? 1 : 0;
00461         }
00462         
00463         return temp;
00464 }
00465 
00466 
00467 template< class T >
00468 Array<int> Array<T>::Le(Array<T>& m1, Array<T>& m2)
00469 {
00470         if(!Array<T>::IsCompatible(m1, m2))
00471         {
00472                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00473                 Utility::RunTimeError("Array sizes are not compatible!");
00474         }
00475 
00476         Array<int> temp(m1.ndims, m1.dims);
00477         for(int i=0;i<temp.Length();i++)
00478         {
00479                 temp[i] = (m1.data[i] <= m2.data[i]) ? 1 : 0;
00480         }
00481         
00482         return temp;
00483 }
00484 
00485 
00486 template< class T >
00487 Array<int> Array<T>::Ge(Array<T>& m1, Array<T>& m2)
00488 {
00489         if(!Array<T>::IsCompatible(m1, m2))
00490         {
00491                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00492                 Utility::RunTimeError("Array sizes are not compatible!");
00493         }
00494 
00495         Array<int> temp(m1.ndims, m1.dims);
00496         for(int i=0;i<temp.Length();i++)
00497         {
00498                 temp[i] = (m1.data[i] >= m2.data[i]) ? 1 : 0;
00499         }
00500         
00501         return temp;
00502 }
00503 
00504 
00505 template< class T >
00506 Array<int> Array<T>::Eq(Array<T>& m1, Array<T>& m2)
00507 {
00508         if(!Array<T>::IsCompatible(m1, m2))
00509         {
00510                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00511                 Utility::RunTimeError("Array sizes are not compatible!");
00512         }
00513 
00514         Array<int> temp(m1.ndims, m1.dims);
00515         for(int i=0;i<temp.Length();i++)
00516         {
00517                 temp[i] = (m1.data[i] == m2.data[i]) ? 1 : 0;
00518         }
00519         
00520         return temp;
00521 }
00522 
00523 
00524 template< class T >
00525 Array<int> Array<T>::Ne(Array<T>& m1, Array<T>& m2)
00526 {
00527         if(!Array<T>::IsCompatible(m1, m2))
00528         {
00529                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00530                 Utility::RunTimeError("Array sizes are not compatible!");
00531         }
00532 
00533         Array<int> temp(m1.ndims, m1.dims);
00534         for(int i=0;i<temp.Length();i++)
00535         {
00536                 temp[i] = (m1.data[i] != m2.data[i]) ? 1 : 0;
00537         }
00538         
00539         return temp;
00540 }
00541 
00542 
00543 
00544 
00545 
00546 
00547 
00548 
00549 // Boolean Operations with value types...
00550 template< class T >
00551 Array<int> Array<T>::And(Array<T>& m1, T v)
00552 {
00553         Array<int> temp(m1.ndims, m1.dims);
00554         for(int i=0;i<temp.Length();i++)
00555         {
00556                 temp[i] = (m1.data[i] != 0 && v != 0) ? 1 : 0;
00557         }
00558         
00559         return temp;
00560 }
00561 
00562 
00563 template< class T >
00564 Array<int> Array<T>::Or(Array<T>& m1, T v)
00565 {
00566         Array<int> temp(m1.ndims, m1.dims);
00567         for(int i=0;i<temp.Length();i++)
00568         {
00569                 temp[i] = (m1.data[i] == 0 && v == 0) ? 0 : 1;
00570         }
00571         
00572         return temp;
00573 }
00574 
00575 
00576 template< class T >
00577 Array<int> Array<T>::Lt(Array<T>& m1, T v)
00578 {
00579         Array<int> temp(m1.ndims, m1.dims);
00580         for(int i=0;i<temp.Length();i++)
00581         {
00582                 temp[i] = (m1.data[i] < v) ? 1 : 0;
00583         }
00584         
00585         return temp;
00586 }
00587 
00588 
00589 template< class T >
00590 Array<int> Array<T>::Gt(Array<T>& m1, T v)
00591 {
00592         Array<int> temp(m1.ndims, m1.dims);
00593         for(int i=0;i<temp.Length();i++)
00594         {
00595                 temp[i] = (m1.data[i] > v) ? 1 : 0;
00596         }
00597         
00598         return temp;
00599 }
00600 
00601 
00602 template< class T >
00603 Array<int> Array<T>::Le(Array<T>& m1, T v)
00604 {
00605         Array<int> temp(m1.ndims, m1.dims);
00606         for(int i=0;i<temp.Length();i++)
00607         {
00608                 temp[i] = (m1.data[i] <= v) ? 1 : 0;
00609         }
00610         
00611         return temp;
00612 }
00613 
00614 
00615 template< class T >
00616 Array<int> Array<T>::Ge(Array<T>& m1, T v)
00617 {
00618         Array<int> temp(m1.ndims, m1.dims);
00619         for(int i=0;i<temp.Length();i++)
00620         {
00621                 temp[i] = (m1.data[i] >= v) ? 1 : 0;
00622         }
00623         
00624         return temp;
00625 }
00626 
00627 
00628 template< class T >
00629 Array<int> Array<T>::Eq(Array<T>& m1, T v)
00630 {
00631         Array<int> temp(m1.ndims, m1.dims);
00632         for(int i=0;i<temp.Length();i++)
00633         {
00634                 temp[i] = (m1.data[i] == v) ? 1 : 0;
00635         }
00636         
00637         return temp;
00638 }
00639 
00640 
00641 template< class T >
00642 Array<int> Array<T>::Ne(Array<T>& m1, T v)
00643 {
00644         Array<int> temp(m1.ndims, m1.dims);
00645         for(int i=0;i<temp.Length();i++)
00646         {
00647                 temp[i] = (m1.data[i] != v) ? 1 : 0;
00648         }
00649         
00650         return temp;
00651 }
00652 
00653 
00654 
00655 
00656 
00657 
00658 
00659 
00660 
00661 
00662 // Add matrix to another matrix
00663 template< class T >
00664 Array<T> Array<T>::Add(Array<T>& m1, Array<T>& m2)
00665 {
00666         if(!Array<T>::IsCompatible(m1, m2))
00667         {
00668                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00669                 Utility::RunTimeError("Array sizes are not compatible!");
00670         }
00671 
00672         Array<T> temp(m1.ndims, m1.dims);
00673         for(int i=0;i<temp.length;i++)
00674         {
00675                 temp.data[i] = m1.data[i] + m2.data[i];
00676         }
00677         
00678         return temp;
00679 }
00680 
00681 
00682 template< class T >
00683 Array<T> Array<T>::Subtract(Array<T>& m1, Array<T>& m2)
00684 {
00685         if(!Array<T>::IsCompatible(m1, m2))
00686         {
00687                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00688                 Utility::RunTimeError("Array sizes are not compatible!");
00689         }
00690 
00691         Array<T> temp(m1.ndims, m1.dims);
00692         for(int i=0;i<temp.length;i++)
00693         {
00694                 temp.data[i] = m1.data[i] - m2.data[i];
00695         }
00696         
00697         return temp;
00698 }
00699 
00700 
00701 template< class T >
00702 Array<T> Array<T>::Multiply(Array<T>& m1, Array<T>& m2)
00703 {
00704         if(!Array<T>::IsCompatible(m1, m2))
00705         {
00706                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00707                 Utility::RunTimeError("Array sizes are not compatible!");
00708         }
00709 
00710         Array<T> temp(m1.ndims, m1.dims);
00711         for(int i=0;i<temp.length;i++)
00712         {
00713                 temp.data[i] = m1.data[i] * m2.data[i];
00714         }
00715         
00716         return temp;
00717 }
00718 
00719 
00720 template< class T >
00721 Array<T> Array<T>::Divide(Array<T>& m1, Array<T>& m2)
00722 {
00723         if(!Array<T>::IsCompatible(m1, m2))
00724         {
00725                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00726                 Utility::RunTimeError("Array sizes are not compatible!");
00727         }
00728 
00729         Array<T> temp(m1.ndims, m1.dims);
00730         for(int i=0;i<temp.length;i++)
00731         {
00732                 //catch division exception instead... Future work
00733                 if(m2.data[i] != 0)
00734                 {
00735                         temp.data[i] = m1.data[i] / m2.data[i];
00736                 }
00737                 else
00738                 {
00739                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00740                         Utility::RunTimeError("Divide by zero in matrix division!");
00741                 }
00742         }
00743         
00744         return temp;
00745 }
00746 
00747 
00748 // Add value to another matrix
00749 template< class T >
00750 Array<T> Array<T>::Add(Array<T>& m1, T v2)
00751 {
00752         Array<T> temp(m1.ndims, m1.dims);
00753         for(int i=0;i<temp.length;i++)
00754         {
00755                 temp.data[i] = m1.data[i] + v2;
00756         }
00757         return temp;
00758 }
00759 
00760 
00761 template< class T >
00762 Array<T> Array<T>::Subtract(Array<T>& m1, T v2)
00763 {
00764         Array<T> temp(m1.ndims, m1.dims);
00765         for(int i=0;i<temp.length;i++)
00766         {
00767                 temp.data[i] = m1.data[i] - v2;
00768         }
00769         return temp;
00770 }
00771 
00772 
00773 template< class T >
00774 Array<T> Array<T>::Subtract(T v2, Array<T>& m1)
00775 {
00776         Array<T> temp(m1.ndims, m1.dims);
00777         for(int i=0;i<temp.length;i++)
00778         {
00779                 temp.data[i] = v2 - m1.data[i];
00780         }
00781         return temp;
00782 }
00783 
00784 
00785 template< class T >
00786 Array<T> Array<T>::Multiply(Array<T>& m1, T v2)
00787 {
00788         Array<T> temp(m1.ndims, m1.dims);
00789         for(int i=0;i<temp.length;i++)
00790         {
00791                 temp.data[i] = m1.data[i] * v2;
00792         }
00793         return temp;
00794 }
00795 
00796 
00797 template< class T >
00798 Array<T> Array<T>::Divide(Array<T>& m1, T v2)
00799 {
00800         if(v2 == 0)
00801         {
00802                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00803                 Utility::RunTimeError("Divide by zero in matrix by value division!");
00804         }
00805 
00806         Array<T> temp(m1.ndims, m1.dims);
00807         for(int i=0;i<temp.length;i++)
00808         {
00809                 temp.data[i] = m1.data[i] / v2;
00810         }
00811         return temp;
00812 }
00813 
00814 
00815 template< class T >
00816 Array<T> Array<T>::Divide(T v2, Array<T>& m1)
00817 {
00818         Array<T> temp(m1.ndims, m1.dims);
00819         for(int i=0;i<temp.length;i++)
00820         {
00821                 if(m1.data[i] != 0)
00822                 {
00823                         temp.data[i] = v2 / m1.data[i];
00824                 }
00825                 else
00826                 {
00827                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00828                         Utility::RunTimeError("Divide by zero in value by matrix division!");
00829                 }
00830         }
00831         return temp;
00832 }
00833 
00834 
00835 
00836 // Add matrix to "this" matrix
00837 template< class T >
00838 Array<T>& Array<T>::Add(Array<T>& m)
00839 {
00840         if(!Array<T>::IsCompatible(*this, m))
00841         {
00842                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00843                 Utility::RunTimeError("Array sizes are not compatible!");
00844         }
00845 
00846         for(int i=0;i<this->length;i++)
00847         {
00848                 this->data[i] += m.data[i];
00849         }
00850         
00851         return *this;
00852 }
00853 
00854 
00855 template< class T >
00856 Array<T>& Array<T>::Subtract(Array<T>& m)
00857 {
00858         if(!Array<T>::IsCompatible(*this, m))
00859         {
00860                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00861                 Utility::RunTimeError("Array sizes are not compatible!");
00862         }
00863 
00864         for(int i=0;i<this->length;i++)
00865         {
00866                 this->data[i] -= m.data[i];
00867         }
00868         
00869         return *this;
00870 }
00871 
00872 
00873 template< class T >
00874 Array<T>& Array<T>::Multiply(Array<T>& m)
00875 {
00876         if(!Array<T>::IsCompatible(*this, m))
00877         {
00878                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00879                 Utility::RunTimeError("Array sizes are not compatible!");
00880         }
00881 
00882         for(int i=0;i<this->length;i++)
00883         {
00884                 this->data[i] *= m.data[i];
00885         }
00886         
00887         return *this;
00888 }
00889 
00890 
00891 template< class T >
00892 Array<T>& Array<T>::Divide(Array<T>& m)
00893 {
00894         if(!Array<T>::IsCompatible(*this, m))
00895         {
00896                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00897                 Utility::RunTimeError("Array sizes are not compatible!");
00898         }
00899 
00900         for(int i=0;i<this->length;i++)
00901         {
00902                 if(m.data[i] != 0)
00903                 {
00904                         this->data[i] /= m.data[i];
00905                 }
00906                 else
00907                 {
00908                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00909                         Utility::RunTimeError("Divide by zero in matrix division!");
00910                 }
00911         }
00912         
00913         return *this;
00914 }
00915 
00916 
00917 // Add value to "this" matrix
00918 template< class T >
00919 Array<T>& Array<T>::Add(T v)
00920 {
00921         for(int i=0;i<this->length;i++)
00922         {
00923                 this->data[i] += v;
00924         }
00925         return *this;
00926 }
00927 
00928 
00929 template< class T >
00930 Array<T>& Array<T>::Subtract(T v)
00931 {
00932         for(int i=0;i<this->length;i++)
00933         {
00934                 this->data[i] -= v;
00935         }
00936         return *this;
00937 }
00938 
00939 
00940 template< class T >
00941 Array<T>& Array<T>::Multiply(T v)
00942 {
00943         for(int i=0;i<this->length;i++)
00944         {
00945                 this->data[i] *= v;
00946         }
00947         return *this;
00948 }
00949 
00950 
00951 template< class T >
00952 Array<T>& Array<T>::Divide(T v)
00953 {
00954         if(v == 0)
00955         {
00956                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00957                 Utility::RunTimeError("Divide by zero in matrix by value division!");
00958         }
00959         
00960         for(int i=0;i<this->length;i++)
00961         {
00962                 this->data[i] /= v;
00963         }
00964         return *this;
00965 }
00966 
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 // OPERATORS
00979 
00980 
00981 template< class T >
00982 Array<T>& Array<T>::operator= (Array<T>& m)
00983 {
00984         ndims = m.ndims;
00985         length = m.length;
00986         dims = new (std::nothrow) int[ndims];
00987         Utility::CheckPointer(dims);
00988 
00989         for(int j=0;j<ndims;j++)
00990         {
00991                 dims[j] = m.dims[j];
00992         }
00993         data = m.data;
00994 
00995         delete clean;
00996         clean = new (std::nothrow) Cleaner<T>(data);
00997         Utility::CheckPointer(clean);   
00998         
00999         return *this;
01000 }
01001 
01002 template< class T >
01003 Array<T>& Array<T>::operator= (Matrix<T>& m)
01004 {
01005         ndims = m.ndims;
01006         length = m.length;
01007         dims = new (std::nothrow) int[ndims];
01008         Utility::CheckPointer(dims);
01009 
01010         dims[0] = m.xDim;
01011         dims[1] = m.yDim;
01012         data = m.data;
01013         
01014         delete clean;
01015         clean = new (std::nothrow) Cleaner<T>(data);
01016         Utility::CheckPointer(clean);
01017         
01018         return *this;
01019 }
01020 
01021 
01022 
01023 
01024 
01025 // Unary +-!
01026 template< class T >
01027 inline Array<T> Array<T>::operator+ ()
01028 {
01029         return *this;
01030 }
01031 
01032 template< class T >
01033 inline Array<T> Array<T>::operator- ()
01034 {
01035         Array<T> temp(this->ndims, this->dims);
01036         for(int i=0;i<length;i++)
01037         {
01038                 temp.data[i] = - data[i];
01039         }
01040         return temp;
01041 }
01042 
01043 template< class T >
01044 inline Array<int> Array<T>::operator! ()
01045 {
01046         Array<int> temp(this->ndims, this->dims);
01047         for(int i=0;i<length;i++)
01048         {
01049                 if(data[i] == 0)
01050                 {
01051                         temp[i] = 1;
01052                 }
01053                 else
01054                 {
01055                         temp[i] = 0;
01056                 }
01057         }
01058         return temp;
01059 }
01060 
01061 
01062 
01063 
01064 
01065 
01066 // Access to the elements
01067 template< class T >
01068 inline T& Array<T>::operator() (const int i)
01069 {
01070         if(i<0 || i>=length)
01071         {
01072                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01073                 Utility::RunTimeError("Index outside bounds!");
01074         }
01075         return data[i];
01076 }
01077 
01078 
01079 
01080 
01081         // no bounds checking...
01082 template< class T >
01083 inline T& Array<T>::operator[] (const int i)
01084 {
01085         return data[i];
01086 }
01087 
01088 
01089         
01090 
01091 template< class T >
01092 inline T& Array<T>::operator() (const int i, const int j, ...)
01093 {
01094         int *temp = new (std::nothrow) int[ndims];
01095         Utility::CheckPointer(temp);
01096         temp[0] = i;
01097         temp[1] = j;
01098 
01099         va_list argptr;
01100         va_start(argptr, j);
01101         int lim = 2;
01102         int a;
01103         while(lim<ndims)
01104         {
01105                 a = va_arg(argptr, int);
01106                 if(a<0 || a>=dims[lim])
01107                 {
01108                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01109                         Utility::RunTimeError("Index outside bounds!");
01110                 }
01111 
01112                 temp[lim] = a;
01113                 lim++;
01114         }
01115         va_end(argptr);
01116 
01117         int ind = 0;
01118         for(int it=0;it<lim;it++)
01119         {
01120                 int tempDim = 1;
01121                 for(int it2=0;it2<it;it2++)
01122                 {
01123                         tempDim *= dims[it2];
01124                 }
01125 
01126                 ind += temp[it]*tempDim;
01127         }
01128 
01129         return data[ind];
01130 }
01131 
01132 
01133 
01135 template< class T >
01136 inline T& Array<T>::Elem(const int i)
01137 {
01138         if(i<0 || i>=length)
01139         {
01140                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01141                 Utility::RunTimeError("Index outside bounds!");
01142         }
01143         return data[i];
01144 }
01145 
01147 template< class T >
01148 inline T& Array<T>::ElemNC(const int i)
01149 {
01150         return data[i];
01151 }
01152 
01153 
01155 template< class T >
01156 inline T& Array<T>::Elem(const int i, const int j, ...)
01157 {
01158         int *temp = new (std::nothrow) int[ndims];
01159         Utility::CheckPointer(temp);
01160         temp[0] = i;
01161         temp[1] = j;
01162 
01163         va_list argptr;
01164         va_start(argptr, j);
01165         int lim = 2;
01166         int a;
01167         while(lim<ndims)
01168         {
01169                 a = va_arg(argptr, int);
01170                 if(a<0 || a>=dims[lim])
01171                 {
01172                         cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01173                         Utility::RunTimeError("Index outside bounds!");
01174                 }
01175 
01176                 temp[lim] = a;
01177                 lim++;
01178         }
01179         va_end(argptr);
01180 
01181         int ind = 0;
01182         for(int it=0;it<lim;it++)
01183         {
01184                 int tempDim = 1;
01185                 for(int it2=0;it2<it;it2++)
01186                 {
01187                         tempDim *= dims[it2];
01188                 }
01189 
01190                 ind += temp[it]*tempDim;
01191         }
01192 
01193         return data[ind];
01194 }
01195 
01196 
01198 template< class T >
01199 inline T& Array<T>::ElemNC(const int i, const int j, ...)
01200 {
01201         int *temp = new (std::nothrow) int[ndims];
01202         Utility::CheckPointer(temp);
01203         temp[0] = i;
01204         temp[1] = j;
01205 
01206         va_list argptr;
01207         va_start(argptr, j);
01208         int lim = 2;
01209         int a;
01210         while(lim<ndims)
01211         {
01212                 a = va_arg(argptr, int);
01213                 temp[lim] = a;
01214                 lim++;
01215         }
01216         va_end(argptr);
01217 
01218         int ind = 0;
01219         for(int it=0;it<lim;it++)
01220         {
01221                 int tempDim = 1;
01222                 for(int it2=0;it2<it;it2++)
01223                 {
01224                         tempDim *= dims[it2];
01225                 }
01226 
01227                 ind += temp[it]*tempDim;
01228         }
01229 
01230         return data[ind];
01231 }
01232 
01233 
01234 
01235 
01236 
01237 // Add inline
01238 template< class T >
01239 Array<T>& Array<T>::operator+= (Array<T>& m)
01240 {
01241         return this->Add(m);
01242 }
01243 
01244 template< class T >
01245 Array<T>& Array<T>::operator-= (Array<T>& m)
01246 {
01247         return this->Subtract(m);
01248 }
01249 
01250 template< class T >
01251 Array<T>& Array<T>::operator*= (Array<T>& m)
01252 {
01253         return this->Multiply(m);
01254 }
01255 
01256 template< class T >
01257 Array<T>& Array<T>::operator/= (Array<T>& m)
01258 {
01259         return this->Divide(m);
01260 }
01261 
01262 
01263 template< class T >
01264 Array<T>& Array<T>::operator+= (T v)
01265 {
01266         return this->Add(v);
01267 }
01268 
01269 template< class T >
01270 Array<T>& Array<T>::operator-= (T v)
01271 {
01272         return this->Subtract(v);
01273 }
01274 
01275 template< class T >
01276 Array<T>& Array<T>::operator*= (T v)
01277 {
01278         return this->Multiply(v);
01279 }
01280 
01281 template< class T >
01282 Array<T>& Array<T>::operator/= (T v)
01283 {
01284         return this->Divide(v);
01285 }
01286 
01287 
01288 
01289 template< class T >
01290 Array<T>::Array(Matrix<T> &m) 
01291 {
01292         ndims = m.ndims;
01293         length = m.length;
01294         dims = new (std::nothrow) int[ndims];
01295         Utility::CheckPointer(dims);
01296         
01297         dims[0] = m.xDim;
01298         dims[1] = m.yDim;
01299         data = m.data;
01300         
01301         clean = new (std::nothrow) Cleaner<T>(data);
01302         Utility::CheckPointer(clean);
01303         
01304 }
01305 
01306 
01307 
01308 
01309 
01310 
01311 
01312 
01313 }; //namespace
01314 
01315 
01316 

Generated on Thu Jan 20 08:43:39 2005 for CIMPL by  doxygen 1.3.9.1