00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, 2009, 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 For a more general discussion of vectors and matrices in \o2, 00030 see the \ref vecmat_section 00031 of the User's Guide. 00032 00033 This file contains classes and functions for operating with 00034 C-style 1- or 2-dimensional arrays and pointers to double. For an 00035 example of the usage of the array allocation classes, see the \ref 00036 ex_mroot_sect . For more generic operations on generic vector 00037 objects (including in some cases C-style arrays), see also the 00038 file \ref vector.h . 00039 00040 This file contains the allocation classes 00041 - array_alloc 00042 - array_2d_alloc 00043 - pointer_alloc 00044 - pointer_2d_alloc 00045 00046 the classes for the manipulation of arrays in smart_interp 00047 - array_reverse 00048 - array_subvector 00049 - array_subvector_reverse 00050 - array_const_reverse 00051 - array_const_subvector 00052 - array_const_subvector_reverse 00053 00054 the array equivalent of omatrix_row and omatrix_col (see 00055 usage in <tt>src/ode/ode_it_solve_ts.cpp</tt>) 00056 - array_2d_row 00057 - array_2d_col 00058 00059 \note The classes 00060 - array_reverse 00061 - array_subvector 00062 - array_subvector_reverse 00063 - array_const_reverse 00064 - array_const_subvector 00065 - array_const_subvector_reverse 00066 00067 can be used with pointers or arrays, but array_alloc and 00068 pointer_alloc are \e not interchangable. 00069 00070 */ 00071 #include <iostream> 00072 #include <cmath> 00073 #include <string> 00074 #include <fstream> 00075 #include <sstream> 00076 #include <new> 00077 #include <o2scl/err_hnd.h> 00078 #include <gsl/gsl_ieee_utils.h> 00079 #include <gsl/gsl_sort.h> 00080 00081 #ifndef DOXYGENP 00082 namespace o2scl 00083 { 00084 #endif 00085 00086 /** 00087 \brief A simple class to provide an \c allocate() function 00088 for arrays 00089 00090 The functions here are blank, as fixed-length arrays are 00091 automatically allocated and destroyed by the compiler. This 00092 class is present to provide an analog to \ref pointer_alloc and 00093 \ref ovector_alloc . This class is used, for example, for \ref 00094 sma_interp_vec . 00095 00096 \future Might it be possible to rework this so that 00097 it does range checking and ensures that the user 00098 doesn't try to allocate more or less space? I.e. 00099 array_alloc<double[2]> complains if you try an allocate(x,3)? 00100 */ 00101 template<class vec_t> class array_alloc { 00102 public: 00103 /// Allocate \c v for \c i elements 00104 void allocate(vec_t &v, size_t i) {} 00105 /// Free memory 00106 void free(vec_t &v) {} 00107 }; 00108 00109 /** 00110 \brief A simple class to provide an \c allocate() function 00111 for 2-dimensional arrays 00112 00113 The functions here are blank, as fixed-length arrays are 00114 automatically allocated and destroyed by the compiler. This 00115 class is present to provide an analog to \ref pointer_2d_alloc 00116 and \ref omatrix_alloc . This class is used in 00117 <tt>gsl_mroot_hybrids_ts.cpp</tt> . 00118 */ 00119 template<class mat_t> class array_2d_alloc { 00120 public: 00121 /// Allocate \c v for \c i elements 00122 void allocate(mat_t &v, size_t i, size_t j) {} 00123 /// Free memory 00124 void free(mat_t &v, size_t i) {} 00125 }; 00126 00127 /** 00128 \brief A simple class to provide an \c allocate() function 00129 for pointers 00130 00131 This class is used in \ref tensor_grid . 00132 00133 This class uses \c new and \c delete. 00134 00135 \todo Call error handler appropriately here 00136 */ 00137 template<class base_t> class pointer_alloc { 00138 public: 00139 /// Allocate \c v for \c i elements 00140 void allocate(base_t *&v, size_t i) { v=new base_t[i]; } 00141 /// Free memory 00142 void free(base_t *&v) { delete[] v; } 00143 }; 00144 00145 /** 00146 \brief A simple class to provide an \c allocate() function 00147 for pointers 00148 00149 Uses \c new and \c delete. 00150 */ 00151 template<class base_t> class pointer_2d_alloc { 00152 public: 00153 /// Allocate \c v for \c i elements 00154 void allocate(base_t **&v, size_t i, size_t j) { 00155 v=new base_t *[i]; 00156 for(size_t m=0;m<i;m++) v[m]=new base_t[j]; 00157 } 00158 /// Free memory 00159 void free(base_t **&v, size_t i) { 00160 for(size_t m=0;m<i;m++) delete[] v[m]; 00161 delete[] v; 00162 } 00163 }; 00164 00165 /** 00166 \brief A simple class which reverses the order of an array 00167 00168 See an example of usage in <tt>interp_ts.cpp</tt> and 00169 <tt>smart_interp_ts.cpp</tt>. 00170 */ 00171 template<size_t sz> class array_reverse { 00172 00173 #ifndef DOXYGEN_INTERNAL 00174 00175 protected: 00176 00177 /// The array pointer 00178 double *a; 00179 00180 #endif 00181 00182 public: 00183 00184 /// Create a reversed array from \c arr of size \c sz 00185 array_reverse(double *arr) { 00186 a=arr; 00187 } 00188 00189 /** 00190 \brief Array-like indexing 00191 */ 00192 double &operator[](size_t i) { 00193 return a[sz-1-i]; 00194 } 00195 00196 /** 00197 \brief Array-like indexing 00198 */ 00199 const double &operator[](size_t i) const { 00200 return a[sz-1-i]; 00201 } 00202 00203 }; 00204 00205 /** 00206 \brief A simple class which reverses the order of an array 00207 00208 See an example of usage in <tt>interp_ts.cpp</tt> and 00209 <tt>smart_interp_ts.cpp</tt>. 00210 */ 00211 template<size_t sz> class array_const_reverse { 00212 00213 #ifndef DOXYGEN_INTERNAL 00214 00215 protected: 00216 00217 /// The array pointer 00218 double *a; 00219 00220 #endif 00221 00222 public: 00223 00224 /// Create a reversed array from \c arr of size \c sz 00225 array_const_reverse(const double *arr) { 00226 a=(double *)arr; 00227 } 00228 00229 /** 00230 \brief Array-like indexing 00231 */ 00232 const double &operator[](size_t i) const { 00233 return a[sz-1-i]; 00234 } 00235 00236 }; 00237 00238 /** 00239 \brief A simple subvector class for an array (without error checking) 00240 */ 00241 class array_subvector { 00242 00243 #ifndef DOXYGEN_INTERNAL 00244 00245 protected: 00246 00247 /// The array pointer 00248 double *a; 00249 00250 /// The offset 00251 size_t off; 00252 00253 /// The subvector length 00254 size_t len; 00255 00256 #endif 00257 00258 public: 00259 00260 /// Create a reversed array from \c arr of size \c sz 00261 array_subvector(double *arr, size_t offset, size_t n) { 00262 a=arr+offset; 00263 off=offset; 00264 len=n; 00265 } 00266 00267 /** 00268 \brief Array-like indexing 00269 */ 00270 double &operator[](size_t i) { 00271 return a[i]; 00272 } 00273 00274 /** 00275 \brief Array-like indexing 00276 */ 00277 const double &operator[](size_t i) const { 00278 return a[i]; 00279 } 00280 00281 }; 00282 00283 /** 00284 \brief Column of a 2d array 00285 00286 This works because two-dimensional arrays are always 00287 continguous (as indicated in appendix C of Soustroup's book). 00288 */ 00289 template<size_t R, size_t C, class data_t=double> class array_2d_col 00290 { 00291 00292 #ifndef DOXYGEN_INTERNAL 00293 00294 protected: 00295 00296 /// The array pointer 00297 data_t *a; 00298 00299 #endif 00300 00301 public: 00302 00303 /// Create an object as the <tt>i</tt>th column of \c mat 00304 array_2d_col(data_t mat[R][C], size_t i) { 00305 a=&(mat[0][i]); 00306 } 00307 00308 /** 00309 \brief Array-like indexing 00310 */ 00311 data_t &operator[](size_t i) { 00312 return a[R*i]; 00313 } 00314 00315 /** 00316 \brief Array-like indexing 00317 */ 00318 const data_t &operator[](size_t i) const { 00319 return a[R*i]; 00320 } 00321 00322 }; 00323 00324 /** 00325 \brief Row of a 2d array 00326 */ 00327 template<class array_2d_t, class data_t=double> class array_2d_row { 00328 00329 #ifndef DOXYGEN_INTERNAL 00330 00331 protected: 00332 00333 /// The array pointer 00334 data_t *a; 00335 00336 #endif 00337 00338 public: 00339 00340 /// Create an object as the <tt>i</tt>th row of \c mat 00341 array_2d_row(array_2d_t &mat, size_t i) { 00342 a=&(mat[i][0]); 00343 } 00344 00345 /** 00346 \brief Array-like indexing, returns the element in the <tt>i</tt>th 00347 column of the chosen row 00348 */ 00349 data_t &operator[](size_t i) { 00350 return a[i]; 00351 } 00352 00353 /** 00354 \brief Array-like indexing, returns the element in the <tt>i</tt>th 00355 column of the chosen row 00356 */ 00357 const data_t &operator[](size_t i) const { 00358 return a[i]; 00359 } 00360 00361 }; 00362 00363 /** \brief A simple subvector class for a const array 00364 (without error checking) 00365 00366 \future Make the member data truly const and remove 00367 the extra typecast. 00368 */ 00369 class array_const_subvector { 00370 00371 #ifndef DOXYGEN_INTERNAL 00372 00373 protected: 00374 00375 /// The array pointer 00376 double *a; 00377 00378 /// The offset 00379 size_t off; 00380 00381 /// The subvector length 00382 size_t len; 00383 00384 #endif 00385 00386 public: 00387 00388 /// Create a reversed array from \c arr of size \c sz 00389 array_const_subvector(const double *arr, size_t offset, size_t n) { 00390 a=(double *)arr+offset; 00391 off=offset; 00392 len=n; 00393 } 00394 00395 /** 00396 \brief Array-like indexing 00397 */ 00398 const double &operator[](size_t i) const { 00399 return a[i]; 00400 } 00401 00402 }; 00403 00404 /** 00405 \brief Reverse a subvector of an array 00406 */ 00407 class array_subvector_reverse { 00408 00409 #ifndef DOXYGEN_INTERNAL 00410 00411 protected: 00412 00413 /// The array pointer 00414 double *a; 00415 00416 /// The offset 00417 size_t off; 00418 00419 /// The subvector length 00420 size_t len; 00421 00422 #endif 00423 00424 public: 00425 00426 /// Create a reversed array from \c arr of size \c sz 00427 array_subvector_reverse(double *arr, size_t offset, size_t n) { 00428 a=arr+offset; 00429 off=offset; 00430 len=n; 00431 } 00432 00433 /** 00434 \brief Array-like indexing 00435 */ 00436 double &operator[](size_t i) { 00437 return a[len-1-i]; 00438 } 00439 00440 /** 00441 \brief Array-like indexing 00442 */ 00443 const double &operator[](size_t i) const { 00444 return a[len-1-i]; 00445 } 00446 00447 }; 00448 00449 /** 00450 \brief Reverse a subvector of a const array 00451 */ 00452 class array_const_subvector_reverse { 00453 00454 #ifndef DOXYGEN_INTERNAL 00455 00456 protected: 00457 00458 /// The array pointer 00459 double *a; 00460 00461 /// The offset 00462 size_t off; 00463 00464 /// The subvector length 00465 size_t len; 00466 00467 #endif 00468 00469 public: 00470 00471 /// Create a reversed array from \c arr of size \c sz 00472 array_const_subvector_reverse(const double *arr, size_t offset, size_t n) { 00473 a=(double *)arr+offset; 00474 off=offset; 00475 len=n; 00476 } 00477 00478 /** 00479 \brief Array-like indexing 00480 */ 00481 const double &operator[](size_t i) const { 00482 return a[len-1-i]; 00483 } 00484 00485 }; 00486 00487 /** 00488 \brief Create a new C-style 1-dimensional array 00489 00490 This function is convenient because it automatically calls the 00491 \o2 error handler in case the allocation fails. 00492 */ 00493 template<class type> type *new_array(size_t n) { 00494 if (n==0) { 00495 O2SCL_ERR2("Tried to allocate array of size zero ", 00496 "in new_array().",gsl_einval); 00497 return 0; 00498 } 00499 type *t=new(std::nothrow) type[n]; 00500 if (t==0) O2SCL_ERR("Allocation failed in new_array().",gsl_enomem); 00501 return t; 00502 } 00503 00504 /** 00505 \brief Free the memory for a C-style 1-dimensional array 00506 00507 This function never calls the error handler, but may create 00508 a segmentation fault if improperly called multiple times. 00509 */ 00510 template<class type> void delete_array(type *t) { 00511 delete[] t; 00512 return; 00513 } 00514 00515 /** 00516 \brief Create a new C-style 2-dimensional array 00517 00518 This function is convenient because it automatically calls the 00519 \o2 error handler in case the allocation fails, and will free 00520 the portions of the memory which were successfully allocated. 00521 */ 00522 template<class type> type **new_2d_array(size_t nr, size_t nc) { 00523 if (nr==0 || nc==0) { 00524 O2SCL_ERR2("Tried to allocate 2-d array of size zero ", 00525 "in new_2d_array().",gsl_einval); 00526 return 0; 00527 } 00528 type **t; 00529 t=new(std::nothrow) type *[nr]; 00530 if (t==0) O2SCL_ERR("Allocation failed in new_2d_array().",gsl_enomem); 00531 for(size_t i=0;i<nr;i++) { 00532 t[i]=new(std::nothrow) type[nc]; 00533 if (t[i]==0) { 00534 for(size_t j=0;j<i;j++) delete[] t[j]; 00535 delete[] t; 00536 O2SCL_ERR("Allocation failed in new_2d_array().",gsl_enomem); 00537 return 0; 00538 } 00539 } 00540 return t; 00541 } 00542 00543 /** 00544 \brief Free the memory for a C-style 2-dimensional array 00545 00546 This function never calls the error handler, but may create 00547 a segmentation fault if improperly called multiple times. 00548 */ 00549 template<class type> void delete_2d_array(type **t, size_t nr) { 00550 for(size_t i=0;i<nr;i++) delete[] t[i]; 00551 delete[] t; 00552 return; 00553 } 00554 00555 #ifndef DOXYGENP 00556 } 00557 #endif 00558 00559 #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