00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_ARRAY_H 00024 #define O2SCL_ARRAY_H 00025 00026 /** \file array.h 00027 \brief Various array classes 00028 00029 This file contains classes and functions for operating with 00030 C-style 1- or 2-dimensional arrays and pointers to double. For 00031 more generic operations on generic vector objects (including in 00032 some cases C-style arrays), see also the file \ref vector.h . This 00033 file contains the allocation classes 00034 - array_alloc 00035 - array_2d_alloc 00036 - pointer_alloc 00037 - pointer_2d_alloc 00038 the classes for the manipulation of arrays in smart_interp 00039 - array_reverse 00040 - array_subvector 00041 - array_subvector_reverse 00042 - array_const_reverse 00043 - array_const_subvector 00044 - array_const_subvector_reverse 00045 the array equivalent of omatrix_row or umatrix_row (see 00046 usage proposed in src/ode/ode_it_solve_ts.cpp) 00047 - array_row 00048 00049 For an example of the usage of the array allocation classes, 00050 see the \ref ex_mroot_sect . 00051 00052 \note The classes 00053 - array_reverse 00054 - array_subvector 00055 - array_subvector_reverse 00056 - array_const_reverse 00057 - array_const_subvector 00058 - array_const_subvector_reverse 00059 can be used with pointers or arrays, but array_alloc and 00060 pointer_alloc are \e not interchangable. 00061 00062 \todo Ensure that array_row works, either here or in 00063 src/ode/ode_it_solve_ts.cpp 00064 00065 */ 00066 #include <iostream> 00067 #include <cmath> 00068 #include <string> 00069 #include <fstream> 00070 #include <sstream> 00071 #include <o2scl/err_hnd.h> 00072 #include <gsl/gsl_ieee_utils.h> 00073 #include <gsl/gsl_sort.h> 00074 00075 #ifndef DOXYGENP 00076 namespace o2scl 00077 { 00078 #endif 00079 00080 /** 00081 \brief A simple class to provide an \c allocate() function 00082 for arrays 00083 00084 The functions here are blank, as fixed-length arrays are 00085 automatically allocated and destroyed by the compiler. This 00086 class is present to provide an analog to \ref pointer_alloc and 00087 \ref ovector_alloc. 00088 */ 00089 template<class vec_t> class array_alloc { 00090 public: 00091 /// Allocate \c v for \c i elements 00092 void allocate(vec_t &v, size_t i) {} 00093 /// Free memory 00094 void free(vec_t &v) {} 00095 }; 00096 00097 /** 00098 \brief A simple class to provide an \c allocate() function 00099 for 2-dimensional arrays 00100 00101 The functions here are blank, as fixed-length arrays are 00102 automatically allocated and destroyed by the compiler. This 00103 class is present to provide an analog to \ref pointer_2d_alloc 00104 and \ref omatrix_alloc 00105 */ 00106 template<class mat_t> class array_2d_alloc { 00107 public: 00108 /// Allocate \c v for \c i elements 00109 void allocate(mat_t &v, size_t i, size_t j) {} 00110 /// Free memory 00111 void free(mat_t &v, size_t i) {} 00112 }; 00113 00114 /** 00115 \brief A simple class to provide an \c allocate() function 00116 for pointers 00117 00118 Uses \c new and \c delete. 00119 */ 00120 template<class base_t> class pointer_alloc { 00121 public: 00122 /// Allocate \c v for \c i elements 00123 void allocate(base_t *&v, size_t i) { v=new base_t[i]; } 00124 /// Free memory 00125 void free(base_t *&v) { delete[] v; } 00126 }; 00127 00128 /** 00129 \brief A simple class to provide an \c allocate() function 00130 for pointers 00131 00132 Uses \c new and \c delete. 00133 */ 00134 template<class base_t> class pointer_2d_alloc { 00135 public: 00136 /// Allocate \c v for \c i elements 00137 void allocate(base_t **&v, size_t i, size_t j) { 00138 v=new base_t *[i]; 00139 for(size_t m=0;m<i;m++) v[m]=new base_t[j]; 00140 } 00141 /// Free memory 00142 void free(base_t **&v, size_t i) { 00143 for(size_t m=0;m<i;m++) delete[] v[m]; 00144 delete[] v; 00145 } 00146 }; 00147 00148 /** 00149 \brief A simple class which reverses the order of an array 00150 */ 00151 template<size_t sz> class array_reverse { 00152 00153 #ifndef DOXYGEN_INTERNAL 00154 00155 protected: 00156 00157 /// The array pointer 00158 double *a; 00159 00160 #endif 00161 00162 public: 00163 00164 /// Create a reversed array from \c arr of size \c sz 00165 array_reverse(double *arr) { 00166 a=arr; 00167 } 00168 00169 /** 00170 \brief Array-like indexing 00171 */ 00172 double &operator[](size_t i) { 00173 return a[sz-1-i]; 00174 } 00175 00176 /** 00177 \brief Array-like indexing 00178 */ 00179 const double &operator[](size_t i) const { 00180 return a[sz-1-i]; 00181 } 00182 00183 }; 00184 00185 /** 00186 \brief A simple class which reverses the order of an array 00187 */ 00188 template<size_t sz> class array_const_reverse { 00189 00190 #ifndef DOXYGEN_INTERNAL 00191 00192 protected: 00193 00194 /// The array pointer 00195 double *a; 00196 00197 #endif 00198 00199 public: 00200 00201 /// Create a reversed array from \c arr of size \c sz 00202 array_const_reverse(const double *arr) { 00203 a=(double *)arr; 00204 } 00205 00206 /** 00207 \brief Array-like indexing 00208 */ 00209 const double &operator[](size_t i) const { 00210 return a[sz-1-i]; 00211 } 00212 00213 }; 00214 00215 /** 00216 \brief A simple subvector class for an array (without error checking) 00217 */ 00218 class array_subvector { 00219 00220 #ifndef DOXYGEN_INTERNAL 00221 00222 protected: 00223 00224 /// The array pointer 00225 double *a; 00226 00227 /// The offset 00228 size_t off; 00229 00230 /// The subvector length 00231 size_t len; 00232 00233 #endif 00234 00235 public: 00236 00237 /// Create a reversed array from \c arr of size \c sz 00238 array_subvector(double *arr, size_t offset, size_t n) { 00239 a=arr+offset; 00240 off=offset; 00241 len=n; 00242 } 00243 00244 /** 00245 \brief Array-like indexing 00246 */ 00247 double &operator[](size_t i) { 00248 return a[i]; 00249 } 00250 00251 /** 00252 \brief Array-like indexing 00253 */ 00254 const double &operator[](size_t i) const { 00255 return a[i]; 00256 } 00257 00258 }; 00259 00260 /** 00261 \brief Column of a 2d array 00262 00263 This works because two-dimensional arrays are always 00264 continguous (as indicated in appendix C of Soustroup's book) 00265 */ 00266 template<size_t R, size_t C> class array_2d_column { 00267 00268 #ifndef DOXYGEN_INTERNAL 00269 00270 protected: 00271 00272 /// The array pointer 00273 double *a; 00274 00275 #endif 00276 00277 public: 00278 00279 /// Create an object as the <tt>i</tt>th column of \c mat 00280 array_2d_column(double mat[R][C], size_t i) { 00281 a=&(mat[0][i]); 00282 } 00283 00284 /** 00285 \brief Array-like indexing 00286 */ 00287 double &operator[](size_t i) { 00288 return a[R*i]; 00289 } 00290 00291 /** 00292 \brief Array-like indexing 00293 */ 00294 const double &operator[](size_t i) const { 00295 return a[R*i]; 00296 } 00297 00298 }; 00299 00300 /** 00301 \brief Row of a 2d array 00302 */ 00303 template<class array_2d_t> class array_2d_row { 00304 00305 #ifndef DOXYGEN_INTERNAL 00306 00307 protected: 00308 00309 /// The array pointer 00310 double *a; 00311 00312 #endif 00313 00314 public: 00315 00316 /// Create an object as the <tt>i</tt>th row of \c mat 00317 array_2d_row(array_2d_t &mat, size_t i) { 00318 a=&(mat[i][0]); 00319 } 00320 00321 /** 00322 \brief Array-like indexing 00323 */ 00324 double &operator[](size_t i) { 00325 return a[i]; 00326 } 00327 00328 /** 00329 \brief Array-like indexing 00330 */ 00331 const double &operator[](size_t i) const { 00332 return a[i]; 00333 } 00334 00335 }; 00336 00337 /** \brief A simple subvector class for a const array 00338 (without error checking) 00339 */ 00340 class array_const_subvector { 00341 00342 #ifndef DOXYGEN_INTERNAL 00343 00344 protected: 00345 00346 /// The array pointer 00347 double *a; 00348 00349 /// The offset 00350 size_t off; 00351 00352 /// The subvector length 00353 size_t len; 00354 00355 #endif 00356 00357 public: 00358 00359 /// Create a reversed array from \c arr of size \c sz 00360 array_const_subvector(const double *arr, size_t offset, size_t n) { 00361 a=(double *)arr+offset; 00362 off=offset; 00363 len=n; 00364 } 00365 00366 /** 00367 \brief Array-like indexing 00368 */ 00369 const double &operator[](size_t i) const { 00370 return a[i]; 00371 } 00372 00373 }; 00374 00375 /** 00376 \brief Reverse a subvector of an array 00377 */ 00378 class array_subvector_reverse { 00379 00380 #ifndef DOXYGEN_INTERNAL 00381 00382 protected: 00383 00384 /// The array pointer 00385 double *a; 00386 00387 /// The offset 00388 size_t off; 00389 00390 /// The subvector length 00391 size_t len; 00392 00393 #endif 00394 00395 public: 00396 00397 /// Create a reversed array from \c arr of size \c sz 00398 array_subvector_reverse(double *arr, size_t offset, size_t n) { 00399 a=arr+offset; 00400 off=offset; 00401 len=n; 00402 } 00403 00404 /** 00405 \brief Array-like indexing 00406 */ 00407 double &operator[](size_t i) { 00408 return a[len-1-i]; 00409 } 00410 00411 /** 00412 \brief Array-like indexing 00413 */ 00414 const double &operator[](size_t i) const { 00415 return a[len-1-i]; 00416 } 00417 00418 }; 00419 00420 /** 00421 \brief Reverse a subvector of a const array 00422 */ 00423 class array_const_subvector_reverse { 00424 00425 #ifndef DOXYGEN_INTERNAL 00426 00427 protected: 00428 00429 /// The array pointer 00430 double *a; 00431 00432 /// The offset 00433 size_t off; 00434 00435 /// The subvector length 00436 size_t len; 00437 00438 #endif 00439 00440 public: 00441 00442 /// Create a reversed array from \c arr of size \c sz 00443 array_const_subvector_reverse(const double *arr, size_t offset, size_t n) { 00444 a=(double *)arr+offset; 00445 off=offset; 00446 len=n; 00447 } 00448 00449 /** 00450 \brief Array-like indexing 00451 */ 00452 const double &operator[](size_t i) const { 00453 return a[len-1-i]; 00454 } 00455 00456 }; 00457 00458 /// Extract a row of a C-style 2d-array 00459 template <class data_t, class array_2d_t> class array_row { 00460 protected: 00461 /// The pointer 00462 data_t *p; 00463 public: 00464 /// View the <tt>i</tt>th row of the 2-d array \c a. 00465 array_row(array_2d_t &a, size_t i) { 00466 p=&(a[i][0]); 00467 } 00468 /// The element in the <tt>i</tt>th column of the chosen row 00469 data_t &operator[](size_t i) { 00470 return p[i]; 00471 } 00472 }; 00473 00474 /// Create a new C-style 2-dimensional array 00475 template<class type> type **new_2d_array(size_t nr, size_t nc) { 00476 type **t; 00477 t=new type *[nr]; 00478 for(size_t i=0;i<nr;i++) t[i]=new type[nc]; 00479 return t; 00480 } 00481 00482 /// Create a new C-style 2-dimensional array 00483 template<class type> int delete_2d_array(type **t, size_t nr) { 00484 for(size_t i=0;i<nr;i++) delete[] t[i]; 00485 delete[] t; 00486 return 0; 00487 } 00488 00489 #ifndef DOXYGENP 00490 } 00491 #endif 00492 00493 #endif
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page