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