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_VECTOR_H 00024 #define O2SCL_VECTOR_H 00025 00026 /** \file vector.h 00027 \brief File for generic vector functions 00028 00029 This file contains a set of template functions which can be 00030 applied to almost any vector or matrix type which allow element 00031 access through <tt>operator[]</tt>. Detailed requirements 00032 on the template parameters are given in the functions below. 00033 00034 For a general discussion of vectors and matrices in \o2, see the 00035 \ref vecmat_section of the User's Guide. 00036 00037 For overloaded arithmetic operators involving vectors and 00038 matrices, see \ref vec_arith.h . For statistics operations not 00039 included here, see \ref vec_stats.h in the directory \c src/other 00040 . For assorted functions and classes which are specific to C-style 00041 arrays, see \ref array.h . Also related are the matrix output 00042 functions, \ref matrix_out(), \ref matrix_cx_out_paren(), and \ref 00043 matrix_out_paren() which are defined in \ref columnify.h because 00044 they utilize the class \ref columnify to format the output. 00045 00046 For functions which search for a value in an ordered (either 00047 increasing or decreasing) vector, see the class \ref search_vec . 00048 00049 \future Create a matrix transpose copy function? 00050 */ 00051 #include <iostream> 00052 #include <cmath> 00053 #include <string> 00054 #include <fstream> 00055 #include <sstream> 00056 #include <o2scl/err_hnd.h> 00057 #include <gsl/gsl_ieee_utils.h> 00058 #include <gsl/gsl_sort.h> 00059 00060 #ifndef DOXYGENP 00061 namespace o2scl 00062 { 00063 #endif 00064 00065 /// \name Copying functions 00066 //@{ 00067 /** 00068 \brief Naive vector copy 00069 00070 \note This ordering is reversed from the GSL function 00071 <tt>gsl_vector_memcpy()</tt>. This is to be used with 00072 \code 00073 vector_copy(N,source,destination); 00074 \endcode 00075 instead of 00076 \code 00077 gsl_vector_memcpy(destination,source); 00078 \endcode 00079 00080 It is assumed that the memory allocation for \c dest 00081 has already been performed. 00082 00083 This function will work for any class <tt>vec2_t</tt> which has 00084 an operator[] which returns a reference to the corresponding 00085 element and class <tt>vec_t</tt> with an operator[] which 00086 returns either a reference or the value of the corresponding 00087 element. 00088 */ 00089 template<class vec_t, class vec2_t> 00090 void vector_copy(size_t N, vec_t &src, vec2_t &dest) { 00091 for(size_t i=0;i<N;i++) dest[i]=src[i]; 00092 } 00093 00094 /** 00095 \brief Naive matrix copy 00096 00097 \note This ordering is reversed from the GSL function 00098 <tt>gsl_matrix_memcpy()</tt>. This is to be used with 00099 \code 00100 matrix_copy(N,source,destination); 00101 \endcode 00102 instead of 00103 \code 00104 gsl_matrix_memcpy(destination,source); 00105 \endcode 00106 00107 It is assumed that the memory allocation for \c dest 00108 has already been performed. 00109 00110 This function will work for any class <tt>vec2_t</tt> which has 00111 an operator[][] which returns a reference to the corresponding 00112 element and class <tt>vec_t</tt> with an operator[][] which 00113 returns either a reference or the value of the corresponding 00114 element. 00115 */ 00116 template<class mat_t, class mat2_t> 00117 void matrix_copy(size_t M, size_t N, mat_t &src, mat2_t &dest) { 00118 for(size_t i=0;i<M;i++) { 00119 for(size_t j=0;j<N;j++) { 00120 dest[i][j]=src[i][j]; 00121 } 00122 } 00123 } 00124 00125 /** 00126 \brief GSL complex vector copy 00127 00128 \future At present this works only with complex types based 00129 directly on the GSL complex format. This could be improved. 00130 */ 00131 template<class vec_t, class vec2_t> 00132 void vector_cx_copy_gsl(size_t N, vec_t &src, vec2_t &dest) { 00133 for(size_t i=0;i<N;i++) { 00134 dest[i].dat[0]=src[i].dat[0]; 00135 dest[i].dat[1]=src[i].dat[1]; 00136 } 00137 } 00138 00139 /** 00140 \brief GSL complex matrix copy 00141 00142 \future At present this works only with complex types based 00143 directly on the GSL complex format. This could be improved. 00144 */ 00145 template<class mat_t, class mat2_t> 00146 void matrix_cx_copy_gsl(size_t M, size_t N, mat_t &src, mat2_t &dest) { 00147 for(size_t i=0;i<M;i++) { 00148 for(size_t j=0;j<N;j++) { 00149 dest[i][j].dat[0]=src[i][j].dat[0]; 00150 dest[i][j].dat[1]=src[i][j].dat[1]; 00151 } 00152 } 00153 } 00154 //@} 00155 00156 /// \name Sorting functions 00157 //@{ 00158 /** 00159 \brief Provide a downheap() function for vector_sort() 00160 */ 00161 template<class vec_t, class data_t> 00162 void sort_downheap(vec_t &data, size_t n, size_t k) { 00163 00164 data_t v=data[k]; 00165 00166 while (k<=n/2) { 00167 size_t j=2*k; 00168 00169 if (j<n && data[j] < data[j+1]) j++; 00170 if (!(v < data[j])) break; 00171 data[k]=data[j]; 00172 k=j; 00173 } 00174 00175 data[k]=v; 00176 } 00177 00178 /** 00179 \brief Sort a vector (in increasing order) 00180 00181 This is a generic sorting template function using a heapsort 00182 algorithm. It will work for any types \c data_t and \c vec_t for 00183 which 00184 - \c data_t has a non-const version of <tt>operator=</tt> 00185 - \c data_t has a less than operator to compare elements 00186 - <tt>vec_t::operator[]</tt> returns a non-const reference 00187 to an object of type \c data_t 00188 00189 In particular, it will work with \ref ovector, \ref uvector, 00190 \ref ovector_int, \ref uvector_int (and other related \o2 00191 vector classes), the STL template class <tt>std::vector</tt>, 00192 and arrays and pointers of numeric, character, and string 00193 objects. 00194 00195 For example, 00196 \code 00197 std::string list[3]={"dog","cat","fox"}; 00198 vector_sort<std::string[3],std::string>(3,list); 00199 \endcode 00200 00201 \note With this function template alone, the user cannot avoid 00202 explicitly specifying the template types for this function 00203 because there is no parameter of type \c data_t, and function 00204 templates cannot handle default template types. For this 00205 reason, the function template \ref vector_sort_double() was 00206 also created which provides the convenience of not requiring 00207 the user to specify the vector template type. 00208 00209 \note This sorting routine is not stable, i.e. equal elements 00210 have arbtrary final ordering 00211 00212 This works similarly to the GSL function <tt>gsl_sort_vector()</tt>. 00213 */ 00214 template<class vec_t, class data_t> 00215 int vector_sort(size_t n, vec_t &data) { 00216 00217 size_t N; 00218 size_t k; 00219 00220 if (n==0) return 0; 00221 00222 N=n-1; 00223 k=N/2; 00224 k++; 00225 do { 00226 k--; 00227 sort_downheap<vec_t,data_t>(data,N,k); 00228 } while (k > 0); 00229 00230 while (N > 0) { 00231 data_t tmp=data[0]; 00232 data[0]=data[N]; 00233 data[N]=tmp; 00234 N--; 00235 sort_downheap<vec_t,data_t>(data,N,0); 00236 } 00237 00238 return 0; 00239 } 00240 00241 /** \brief Provide a downheap() function for vector_sort_index() 00242 */ 00243 template<class vec_t, class vec_size_t> 00244 int sort_index_downheap(size_t N, const vec_t &data, vec_size_t &order, 00245 size_t k) { 00246 00247 const size_t pki = order[k]; 00248 00249 while (k <= N / 2) { 00250 size_t j = 2 * k; 00251 00252 if (j < N && data[order[j]] < data[order[j + 1]]) { 00253 j++; 00254 } 00255 00256 // avoid infinite loop if nan 00257 if (!(data[pki] < data[order[j]])) { 00258 break; 00259 } 00260 00261 order[k] = order[j]; 00262 00263 k = j; 00264 } 00265 00266 order[k] = pki; 00267 00268 return 0; 00269 } 00270 00271 /** 00272 \brief Create a permutation which sorts a vector (in increasing order) 00273 00274 This function takes a vector \c data and arranges a list of 00275 indices in \c order, which give a sorted version of the vector. 00276 The value <tt>order[i]</tt> gives the index of entry in in \c 00277 data which corresponds to the <tt>i</tt>th value in the sorted 00278 vector. The vector \c data is unchanged by this function, and 00279 the initial values in \c order are ignored. Before calling this 00280 function, \c order must already be allocated as a vector of size 00281 \c n. 00282 00283 For example, after calling this function, a sorted version the 00284 vector can be output with 00285 \code 00286 size_t n=5; 00287 double data[5]={3.1,4.1,5.9,2.6,3.5}; 00288 permutation order(n); 00289 vector_sort_index(n,data,order); 00290 for(size_t i=0;i<n;i++) { 00291 cout << data[order[i]] << endl; 00292 } 00293 \endcode 00294 00295 To create a permutation which stores as its <tt>i</tt>th element, 00296 the index of <tt>data[i]</tt> in the sorted vector, you can 00297 invert the permutation created by this function. 00298 00299 This is a generic sorting template function. It will work for 00300 any types \c vec_t and \c vec_size_t for which 00301 - \c vec_t has an <tt>operator[]</tt>, and 00302 - \c vec_size_t has an <tt>operator[]</tt> which returns 00303 a \c size_t . 00304 One possible type for \c vec_size_t is \ref permutation. 00305 00306 This works similarly to the GSL function <tt>gsl_sort_index()</tt>. 00307 */ 00308 template<class vec_t, class vec_size_t> 00309 int vector_sort_index(size_t n, const vec_t &data, vec_size_t &order) { 00310 size_t N; 00311 size_t i, k; 00312 00313 if (n == 0) return 0; 00314 00315 // set permutation to identity 00316 00317 for (i = 0 ; i < n ; i++) { 00318 order[i] = i ; 00319 } 00320 00321 /* We have n_data elements, last element is at 'n_data-1', first 00322 at '0' Set N to the last element number. 00323 */ 00324 N = n - 1; 00325 00326 k = N / 2; 00327 // Compensate the first use of 'k--' 00328 k++; 00329 do { 00330 k--; 00331 sort_index_downheap<vec_t,vec_size_t>(N,data,order,k); 00332 } while (k > 0); 00333 00334 00335 while (N > 0) { 00336 00337 // first swap the elements 00338 size_t tmp = order[0]; 00339 order[0] = order[N]; 00340 order[N] = tmp; 00341 00342 // then process the heap 00343 N--; 00344 00345 sort_index_downheap<vec_t,vec_size_t>(N,data,order,0); 00346 } 00347 00348 return 0; 00349 } 00350 00351 /** 00352 \brief Sort a vector of doubles (in increasing order) 00353 00354 This function is just a wrapper for 00355 \code 00356 vector_sort<vec_t,double>(n,data); 00357 \endcode 00358 See the documentation of \ref vector_sort() for more 00359 details. 00360 */ 00361 template<class vec_t> 00362 int vector_sort_double(size_t n, vec_t &data) { 00363 return vector_sort<vec_t,double>(n,data); 00364 } 00365 //@} 00366 00367 /// \name Smallest and largest functions 00368 //@{ 00369 /** \brief Find the k smallest entries of a vector 00370 00371 Given a vector \c data of size \c n this sets the first \c k 00372 entries of the vector \c smallest to the k smallest entries from 00373 vector \c data in ascending order. The vector \c smallest must 00374 be allocated beforehand to hold at least \c k elements. 00375 00376 This works similarly to the GSL function <tt>gsl_sort_smallest()</tt>. 00377 00378 \note This \f$ {\cal O}(k N) \f$ algorithm is useful only when 00379 \f$ k << N \f$. 00380 00381 If \c k is zero, then this function does nothing and 00382 returns \ref gsl_success . 00383 */ 00384 template<class vec_t, class data_t> 00385 int vector_smallest(size_t n, vec_t &data, size_t k, vec_t &smallest) { 00386 if (k>n) { 00387 O2SCL_ERR2_RET("Subset length greater than size in ", 00388 "function vector_smallest().",gsl_einval); 00389 } 00390 if (k==0 || n==0) return gsl_success; 00391 00392 // Take the first element 00393 size_t j=1; 00394 data_t xbound=data[0]; 00395 smallest[0]=xbound; 00396 00397 // Examine the remaining elements 00398 for(size_t i=1;i<n;i++) { 00399 data_t xi=data[i]; 00400 if (j<k) { 00401 j++; 00402 } else if (xi>=xbound) { 00403 continue; 00404 } 00405 size_t i1; 00406 for(i1=j-1;i1>0;i1--) { 00407 if (xi>smallest[i1-1]) break; 00408 smallest[i1]=smallest[i1-1]; 00409 } 00410 smallest[i1]=xi; 00411 xbound=smallest[j-1]; 00412 } 00413 return 0; 00414 } 00415 00416 /** \brief Find the k largest entries of a vector 00417 00418 Given a vector \c data of size \c n this sets the first \c k 00419 entries of the vector \c largest to the k largest entries from 00420 vector \c data in descending order. The vector \c largest must 00421 be allocated beforehand to hold at least \c k elements. 00422 00423 This works similarly to the GSL function <tt>gsl_sort_largest()</tt>. 00424 00425 \note This \f$ {\cal O}(k N) \f$ algorithm is useful only when 00426 \f$ k << N \f$. 00427 00428 If \c k is zero, then this function does nothing and 00429 returns \ref gsl_success . 00430 */ 00431 template<class vec_t, class data_t> 00432 int vector_largest(size_t n, vec_t &data, size_t k, vec_t &largest) { 00433 if (k>n) { 00434 O2SCL_ERR2_RET("Subset length greater than size in ", 00435 "function vector_largest().",gsl_einval); 00436 } 00437 if (k==0 || n==0) return gsl_success; 00438 00439 // Take the first element 00440 size_t j=1; 00441 data_t xbound=data[0]; 00442 largest[0]=xbound; 00443 00444 // Examine the remaining elements 00445 for(size_t i=1;i<n;i++) { 00446 data_t xi=data[i]; 00447 if (j<k) { 00448 j++; 00449 } else if (xi<=xbound) { 00450 continue; 00451 } 00452 size_t i1; 00453 for(i1=j-1;i1>0;i1--) { 00454 if (xi<largest[i1-1]) break; 00455 largest[i1]=largest[i1-1]; 00456 } 00457 largest[i1]=xi; 00458 xbound=largest[j-1]; 00459 } 00460 return 0; 00461 } 00462 //@} 00463 00464 /// \name Vector minimum and maximum functions 00465 //@{ 00466 /** \brief Compute the maximum of the first \c n elements of a vector 00467 */ 00468 template<class vec_t, class data_t> 00469 data_t vector_max(size_t n, const vec_t &data) { 00470 00471 if (n==0) { 00472 O2SCL_ERR_RET("Sent size=0 to vector_max().",gsl_efailed); 00473 } 00474 data_t max=data[0]; 00475 for(size_t i=1;i<n;i++) { 00476 if (data[i]>max) { 00477 max=data[i]; 00478 } 00479 } 00480 return max; 00481 } 00482 00483 /** \brief Compute the minimum of the first \c n elements of a vector 00484 */ 00485 template<class vec_t, class data_t> 00486 data_t vector_min(size_t n, const vec_t &data) { 00487 00488 if (n==0) { 00489 O2SCL_ERR_RET("Sent size=0 to vector_min().",gsl_efailed); 00490 } 00491 data_t min=data[0]; 00492 for(size_t i=1;i<n;i++) { 00493 if (data[i]<min) { 00494 min=data[i]; 00495 } 00496 } 00497 return min; 00498 } 00499 00500 /** \brief Compute the minimum and maximum of the first 00501 \c n elements of a vector 00502 */ 00503 template<class vec_t, class data_t> 00504 int vector_minmax(size_t n, vec_t &data, data_t &min, data_t &max) { 00505 00506 if (n==0) { 00507 O2SCL_ERR_RET("Sent size=0 to vector_min().",gsl_efailed); 00508 } 00509 min=data[0]; 00510 max=min; 00511 for(size_t i=1;i<n;i++) { 00512 if (data[i]<min) { 00513 min=data[i]; 00514 } 00515 if (data[i]>max) { 00516 max=data[i]; 00517 } 00518 } 00519 return 0; 00520 } 00521 //@} 00522 00523 /// \name Matrix minimum and maximum functions 00524 //@{ 00525 /** \brief Compute the maximum of a matrix 00526 */ 00527 template<class mat_t, class data_t> 00528 data_t matrix_max(size_t n, const size_t m, const mat_t &data) { 00529 00530 if (n==0 || m==0) { 00531 O2SCL_ERR_RET("Sent size=0 to matrix_max().",gsl_efailed); 00532 } 00533 data_t max=data[0][0]; 00534 for(size_t i=0;i<n;i++) { 00535 for(size_t j=0;j<m;j++) { 00536 if (data[i][j]>max) { 00537 max=data[i][j]; 00538 } 00539 } 00540 } 00541 return max; 00542 } 00543 00544 /** \brief Compute the minimum of a matrix 00545 */ 00546 template<class mat_t, class data_t> 00547 data_t matrix_min(size_t n, const size_t m, const mat_t &data) { 00548 00549 if (n==0 || m==0) { 00550 O2SCL_ERR_RET("Sent size=0 to matrix_min().",gsl_efailed); 00551 } 00552 data_t min=data[0][0]; 00553 for(size_t i=0;i<n;i++) { 00554 for(size_t j=0;j<m;j++) { 00555 if (data[i][j]<min) { 00556 min=data[i][j]; 00557 } 00558 } 00559 } 00560 return min; 00561 } 00562 00563 /** \brief Compute the minimum and maximum of a matrix 00564 */ 00565 template<class mat_t, class data_t> 00566 int matrix_minmax(size_t n, const size_t m, const mat_t &data, 00567 data_t &min, data_t &max) { 00568 00569 if (n==0 || m==0) { 00570 O2SCL_ERR_RET("Sent size=0 to matrix_min().",gsl_efailed); 00571 } 00572 min=data[0][0]; 00573 max=data[0][0]; 00574 for(size_t i=0;i<n;i++) { 00575 for(size_t j=0;j<m;j++) { 00576 if (data[i][j]<min) { 00577 min=data[i][j]; 00578 } else if (data[i][j]>max) { 00579 max=data[i][j]; 00580 } 00581 } 00582 } 00583 return 0; 00584 } 00585 //@} 00586 00587 /// \name Vector minimum and maximum functions returning an index 00588 //@{ 00589 /** \brief Compute the maximum of the first \c n elements of a vector 00590 */ 00591 template<class vec_t, class data_t> 00592 size_t vector_max_index(size_t n, vec_t &data, data_t &max) { 00593 00594 if (n==0) { 00595 O2SCL_ERR_RET("Sent size=0 to vector_max().",gsl_efailed); 00596 } 00597 size_t ix=0; 00598 max=data[0]; 00599 for(size_t i=1;i<n;i++) { 00600 if (data[i]>max) { 00601 max=data[i]; 00602 ix=i; 00603 } 00604 } 00605 return ix; 00606 } 00607 00608 /** \brief Compute the minimum of the first \c n elements of a vector 00609 */ 00610 template<class vec_t, class data_t> 00611 int vector_min_index(size_t n, vec_t &data, data_t &min) { 00612 00613 if (n==0) { 00614 O2SCL_ERR_RET("Sent size=0 to vector_min().",gsl_efailed); 00615 } 00616 size_t ix=0; 00617 min=data[0]; 00618 for(size_t i=1;i<n;i++) { 00619 if (data[i]<min) { 00620 min=data[i]; 00621 ix=i; 00622 } 00623 } 00624 return ix; 00625 } 00626 00627 /** \brief Compute the minimum and maximum of the first 00628 \c n elements of a vector 00629 */ 00630 template<class vec_t, class data_t> 00631 int vector_minmax_index(size_t n, vec_t &data, data_t &min, 00632 size_t &ix, data_t &max, size_t &ix2) { 00633 00634 if (n==0) { 00635 O2SCL_ERR_RET("Sent size=0 to vector_min().",gsl_efailed); 00636 } 00637 ix=0; 00638 ix2=0; 00639 min=data[0]; 00640 max=min; 00641 for(size_t i=1;i<n;i++) { 00642 if (data[i]<min) { 00643 min=data[i]; 00644 ix=i; 00645 } 00646 if (data[i]>max) { 00647 max=data[i]; 00648 ix2=i; 00649 } 00650 } 00651 return 0; 00652 } 00653 //@} 00654 00655 /** \brief Create a vector-like class from a row of a matrix 00656 00657 \comment 00658 This class isn't used in o2scl at present, but we 00659 keep it here for posterity for now. 00660 \endcomment 00661 00662 \future Generalize to operator(,) 00663 */ 00664 template <class mat_t> class matrix_row { 00665 00666 #ifndef DOXYGEN_INTERNAL 00667 00668 protected: 00669 00670 /// The row index 00671 size_t r2; 00672 00673 /// The pointer to the matrix 00674 mat_t *m2; 00675 00676 #endif 00677 00678 public: 00679 00680 /// Create an object which represents row \c r of matrix \c m 00681 matrix_row(mat_t &m, size_t r) { 00682 r2=r; 00683 m2=&m; 00684 } 00685 00686 /// Access element of column \c c from the specified row 00687 double &operator[](size_t c) { 00688 return (*m2)[r2][c]; 00689 } 00690 00691 /// Access element of column \c c from the specified row 00692 const double &operator[](size_t c) const { 00693 return (*m2)[r2][c]; 00694 } 00695 00696 }; 00697 00698 /// \name Searching functions 00699 //@{ 00700 /** \brief Lookup element \c x0 in vector \c x of length \c n 00701 00702 This function finds the element in vector \c x which is closest 00703 to \c x0. It ignores all elements in \c x which are not 00704 finite. If the vector is empty, or if all of the elements in \c 00705 x are not finite, then the error handler will be called. 00706 00707 This function works for all classes \c vec_t where an operator[] 00708 is defined which returns a double (either as a value or a 00709 reference). 00710 */ 00711 template<class vec_t> 00712 size_t vector_lookup(size_t n, const vec_t &x, double x0) { 00713 if (n==0) { 00714 O2SCL_ERR("Empty vector in vector_lookup().", 00715 gsl_einval); 00716 return 0; 00717 } 00718 size_t row=0, i=0; 00719 while(!finite(x[i]) && i<n-1) i++; 00720 if (i==n-1) { 00721 O2SCL_ERR2("Entire vector not finite in ", 00722 "vector_lookup()",gsl_einval); 00723 return 0; 00724 } 00725 double best=x[i], bdiff=fabs(x[i]-x0); 00726 for(;i<n;i++) { 00727 if (finite(x[i]) && fabs(x[i]-x0)<bdiff) { 00728 row=i; 00729 best=x[i]; 00730 bdiff=fabs(x[i]-x0); 00731 } 00732 } 00733 return row; 00734 } 00735 00736 /** 00737 \brief Binary search a part of an increasing vector for 00738 <tt>x0</tt>. 00739 00740 This function performs a binary search of between 00741 <tt>x[lo]</tt> and <tt>x[hi]</tt>. It returns 00742 - \c lo if \c x0 < <tt>x[lo]</tt> 00743 - \c i if <tt>x[i]</tt> <= \c x0 < <tt>x[i+1]</tt> 00744 for \c lo <= \c i < \c hi 00745 - \c hi-1 if \c x0 >= \c <tt>x[hi-1]</tt> 00746 00747 The element at <tt>x[hi]</tt> is never referenced by this 00748 function. The parameter \c hi can be either the last element in 00749 the vector, or one element past the last element of the vector, 00750 depending on whether or not the user wants the function to 00751 return the index of the last element. 00752 00753 This function operates in the same way as 00754 <tt>gsl_interp_bsearch()</tt>. 00755 00756 The operation of this function is undefined if the data is 00757 not strictly monotonic, i.e. if some of the data elements are 00758 equal. 00759 00760 This function will call the error handler if \c lo is 00761 greater than \c hi. 00762 */ 00763 template<class vec_t, class data_t> 00764 size_t vector_bsearch_inc(const data_t x0, const vec_t &x, 00765 size_t lo, size_t hi) { 00766 if (lo>hi) { 00767 O2SCL_ERR2("Low and high indexes backwards in ", 00768 "vector_bsearch_inc().",gsl_einval); 00769 } 00770 while (hi>lo+1) { 00771 size_t i=(hi+lo)/2; 00772 if (x[i]>x0) { 00773 hi=i; 00774 } else { 00775 lo=i; 00776 } 00777 } 00778 00779 return lo; 00780 } 00781 00782 /** 00783 \brief Binary search a part of an decreasing vector for 00784 <tt>x0</tt>. 00785 00786 This function performs a binary search of between 00787 <tt>x[lo]</tt> and <tt>x[hi]</tt> (inclusive). It returns 00788 - \c lo if \c x0 > <tt>x[lo]</tt> 00789 - \c i if <tt>x[i]</tt> >= \c x0 > <tt>x[i+1]</tt> 00790 for \c lo <= \c i < \c hi 00791 - \c hi-1 if \c x0 <= \c <tt>x[hi-1]</tt> 00792 00793 The element at <tt>x[hi]</tt> is never referenced by this 00794 function. The parameter \c hi can be either the last 00795 element in the vector, or one element past the last element of 00796 the vector, depending on whether or not the user wants 00797 the function to return the index of the last element. 00798 00799 The operation of this function is undefined if the data is 00800 not strictly monotonic, i.e. if some of the data elements are 00801 equal. 00802 00803 This function will call the error handler if \c lo is 00804 greater than \c hi. 00805 */ 00806 template<class vec_t, class data_t> 00807 size_t vector_bsearch_dec(const data_t x0, const vec_t &x, 00808 size_t lo, size_t hi) { 00809 if (lo>hi) { 00810 O2SCL_ERR2("Low and high indexes backwards in ", 00811 "vector_bsearch_dec().",gsl_einval); 00812 } 00813 while (hi>lo+1) { 00814 size_t i=(hi+lo)/2; 00815 if (x[i]<x0) { 00816 hi=i; 00817 } else { 00818 lo=i; 00819 } 00820 } 00821 00822 return lo; 00823 } 00824 //@} 00825 00826 /// \name Miscellaneous mathematical functions 00827 //@{ 00828 /** 00829 \brief Compute the sum of the first \c n elements of a vector 00830 00831 If \c n is zero, this will set \c sum to zero and return 00832 \ref gsl_success. 00833 */ 00834 template<class vec_t, class data_t> 00835 data_t vector_sum(size_t n, vec_t &data) { 00836 00837 data_t sum=0.0; 00838 for(size_t i=0;i<n;i++) { 00839 sum+=data[i]; 00840 } 00841 return sum; 00842 } 00843 00844 /** \brief Compute the norm of a vector of floating-point 00845 (single or double precision) numbers 00846 00847 This function is a more generic version of 00848 \ref o2scl_cblas::dnrm2 . 00849 */ 00850 template<class vec_t, class data_t> 00851 data_t vector_norm(size_t n, const vec_t &x) { 00852 00853 data_t scale = 0.0; 00854 data_t ssq = 1.0; 00855 00856 if (n <= 0) { 00857 return 0.0; 00858 } else if (n == 1) { 00859 return fabs(x[0]); 00860 } 00861 00862 for (size_t i = 0; i < n; i++) { 00863 const data_t xx = x[i]; 00864 00865 if (xx != 0.0) { 00866 const data_t ax = fabs(xx); 00867 00868 if (scale < ax) { 00869 ssq = 1.0 + ssq * (scale / ax) * (scale / ax); 00870 scale = ax; 00871 } else { 00872 ssq += (ax / scale) * (ax / scale); 00873 } 00874 } 00875 00876 } 00877 00878 return scale * sqrt(ssq); 00879 } 00880 //@} 00881 00882 /// \name Other functions 00883 //@{ 00884 /** 00885 \brief "Rotate" a vector so that the kth element is now the beginning 00886 00887 This is a generic template function which will work for 00888 any types \c data_t and \c vec_t for which 00889 - \c data_t has an <tt>operator=</tt> 00890 - <tt>vec_t::operator[]</tt> returns a reference 00891 to an object of type \c data_t 00892 00893 This function is used, for example, in \ref pinside. 00894 */ 00895 template<class vec_t, class data_t> 00896 int vector_rotate(size_t n, vec_t &data, size_t k) { 00897 00898 data_t *tmp=new data_t[n]; 00899 for(size_t i=0;i<n;i++) { 00900 tmp[i]=data[(i+k)%n]; 00901 } 00902 for(size_t i=0;i<n;i++) { 00903 data[i]=tmp[i]; 00904 } 00905 delete[] tmp; 00906 00907 return 0; 00908 } 00909 00910 /** \brief Reverse a vector 00911 00912 If \c n is zero, this function will silenly do nothing. 00913 */ 00914 template<class vec_t, class data_t> 00915 int vector_reverse(size_t n, vec_t &data) { 00916 data_t tmp; 00917 00918 for(size_t i=0;i<n/2;i++) { 00919 tmp=data[n-1-i]; 00920 data[n-1-i]=data[i]; 00921 data[i]=tmp; 00922 } 00923 return 0; 00924 } 00925 00926 /** 00927 \brief Output a vector to a stream 00928 00929 No trailing space is output after the last element, and an 00930 endline is output only if \c endline is set to \c true. If the 00931 parameter \c n is zero, this function silently does nothing. 00932 00933 Note that the \o2 vector classes also have their own 00934 \c operator<<() defined for them. 00935 00936 This works with any class <tt>vec_t</tt> which has an operator[] 00937 which returns either the value of or a reference to the ith 00938 element and the element type has its own output operator which 00939 has been defined. 00940 */ 00941 template<class vec_t> 00942 int vector_out(std::ostream &os, size_t n, vec_t &v, 00943 bool endline=false) { 00944 00945 // This next line is important since n-1 is not well-defined if n=0 00946 if (n==0) return 0; 00947 00948 for(size_t i=0;i<n-1;i++) os << v[i] << " "; 00949 os << v[n-1]; 00950 if (endline) os << std::endl; 00951 return 0; 00952 } 00953 //@} 00954 00955 #ifndef DOXYGENP 00956 } 00957 #endif 00958 00959 #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