00001 00002 /* 00003 ------------------------------------------------------------------- 00004 00005 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00006 00007 This file is part of O2scl. 00008 00009 O2scl is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 O2scl is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00021 00022 ------------------------------------------------------------------- 00023 */ 00024 #ifndef O2SCL_PERMUTATION_H 00025 #define O2SCL_PERMUTATION_H 00026 00027 /** \file permutation.h 00028 \brief File for definitions of vectors 00029 */ 00030 00031 #include <iostream> 00032 #include <cstdlib> 00033 #include <string> 00034 #include <fstream> 00035 #include <sstream> 00036 #include <vector> 00037 #include <gsl/gsl_vector.h> 00038 #include <gsl/gsl_permutation.h> 00039 #include <o2scl/err_hnd.h> 00040 #include <o2scl/string_conv.h> 00041 #include <o2scl/uvector_tlate.h> 00042 #include <o2scl/array.h> 00043 00044 #ifndef DOXYGENP 00045 namespace o2scl { 00046 #endif 00047 00048 /** 00049 \brief A permutation 00050 */ 00051 class permutation : public gsl_permutation_struct { 00052 00053 public: 00054 00055 permutation(size_t dim=0) { 00056 gsl_permutation_struct::size=dim; 00057 if (dim>0) { 00058 data=(size_t *)malloc(dim*sizeof(size_t)); 00059 } 00060 } 00061 00062 /// \name Copy constructors 00063 //@{ 00064 permutation(const permutation &v) { 00065 gsl_permutation_struct::size=v.size(); 00066 data=new size_t[gsl_permutation_struct::size]; 00067 for(size_t i=0;i<gsl_permutation_struct::size;i++) { 00068 data[i]=v.data[i]; 00069 } 00070 } 00071 00072 permutation& operator=(const permutation &v) { 00073 gsl_permutation_struct::size=v.size(); 00074 data=new size_t[gsl_permutation_struct::size]; 00075 for(size_t i=0;i<gsl_permutation_struct::size;i++) { 00076 data[i]=v.data[i]; 00077 } 00078 return *this; 00079 } 00080 //@} 00081 00082 ~permutation() { 00083 if (gsl_permutation_struct::size>0) { 00084 std::free(data); 00085 gsl_permutation_struct::size=0; 00086 } 00087 }; 00088 00089 /** \brief Get (with optional range-checking) */ 00090 size_t get(size_t i) const { 00091 #if O2SCL_NO_RANGE_CHECK 00092 #else 00093 if (i>=gsl_permutation_struct::size) { 00094 set_err((((std::string)"Permutation index ")+itos(i)+" out of bounds" 00095 +" in permutation::get(). Size: "+ 00096 itos(gsl_permutation_struct::size)+ 00097 " (index should be less than size).").c_str(),gsl_index); 00098 return 0; 00099 } 00100 #endif 00101 return data[i]; 00102 } 00103 00104 /** \brief Set (with optional range-checking) */ 00105 int set(size_t i, size_t val) { 00106 #if O2SCL_NO_RANGE_CHECK 00107 #else 00108 if (i>=gsl_permutation_struct::size) { 00109 set_err_ret((((std::string)"Permutation index ")+itos(i)+ 00110 " out of bounds"+" in permutation::set(). Size: "+ 00111 itos(gsl_permutation_struct::size)+ 00112 " (index should be less than size).").c_str(),gsl_index); 00113 } 00114 #endif 00115 data[i]=val; 00116 return 0; 00117 } 00118 00119 /// Initialize permutation to the identity 00120 int init() { 00121 for(size_t i=0;i<gsl_permutation_struct::size;i++) data[i]=i; 00122 return 0; 00123 } 00124 00125 /** 00126 \brief Return permutation size 00127 00128 If no memory has been allocated, this will quietly 00129 return zero. 00130 */ 00131 size_t size() const { 00132 return gsl_permutation_struct::size; 00133 } 00134 00135 /** \brief Allocate memory for a permutation of size \c dim 00136 */ 00137 int allocate(size_t dim) { 00138 if (gsl_permutation_struct::size!=dim && 00139 gsl_permutation_struct::size>0) free(); 00140 gsl_permutation_struct::size=dim; 00141 if (dim>0) { 00142 data=(size_t *)malloc(dim*sizeof(size_t)); 00143 } 00144 return 0; 00145 } 00146 00147 /** 00148 \brief Free the memory 00149 00150 This function will safely do nothing if used without first 00151 allocating memory or if called multiple times in succession. 00152 */ 00153 int free() { 00154 if (gsl_permutation_struct::size>0) { 00155 std::free(data); 00156 gsl_permutation_struct::size=0; 00157 } 00158 return 0; 00159 } 00160 //@} 00161 00162 /// Swap two elements of a permutation 00163 int swap(const size_t i, const size_t j) { 00164 size_t tmp=data[i]; 00165 data[i]=data[j]; 00166 data[j]=tmp; 00167 return 0; 00168 } 00169 00170 /// Check to see that a permutation is valid 00171 bool valid() { 00172 for(size_t i=0;i<gsl_permutation_struct::size;i++) { 00173 if (data[i]>gsl_permutation_struct::size) return false; 00174 for(size_t j=0;j<i;j++) { 00175 if (data[i]==data[j]) return false; 00176 } 00177 } 00178 return true; 00179 } 00180 00181 /// Reverse the permutation 00182 int reverse() { 00183 size_t i; 00184 for (i = 0; i < (gsl_permutation_struct::size / 2); i++){ 00185 size_t j = gsl_permutation_struct::size - i - 1; 00186 00187 size_t tmp = this->data[i] ; 00188 this->data[i] = this->data[j] ; 00189 this->data[j] = tmp ; 00190 } 00191 return 0; 00192 } 00193 00194 /// Compute the inverse of a permutation 00195 permutation inverse() { 00196 permutation p(gsl_permutation_struct::size); 00197 for(size_t i=0;i<gsl_permutation_struct::size;i++) { 00198 p.data[data[i]]=i; 00199 } 00200 return p; 00201 } 00202 00203 /// Apply the permutation to a vector 00204 template<class vec_t> int apply(vec_t &v) { 00205 size_t i, k, pk; 00206 for(i=0;i<gsl_permutation_struct::size;i++) { 00207 k=data[i]; 00208 while (k>i) k=data[k]; 00209 if (k<i) continue; 00210 /// Now have k==i, i.e. the least in its cycle 00211 pk=data[k]; 00212 if (pk==i) continue; 00213 // Shuffle the elements of the cycle 00214 { 00215 double t=v[i]; 00216 while (pk!=i) { 00217 double r1=v[pk]; 00218 v[k]=r1; 00219 k=pk; 00220 pk=data[k]; 00221 } 00222 v[k]=t; 00223 } 00224 } 00225 return 0; 00226 } 00227 00228 /// Apply the permutation to a vector 00229 template<class vec_t> int apply_inverse(vec_t &v) { 00230 size_t i, k, pk; 00231 for(i=0;i<gsl_permutation_struct::size;i++) { 00232 k=data[i]; 00233 while (k>i) k=data[k]; 00234 if (k<i) continue; 00235 /// Now have k==i, i.e. the least in its cycle 00236 pk=data[k]; 00237 if (pk==i) continue; 00238 // Shuffle the elements of the cycle 00239 { 00240 double t=v[k]; 00241 while (pk!=i) { 00242 double r1=v[pk]; 00243 v[pk]=t; 00244 t=r1; 00245 k=pk; 00246 pk=data[k]; 00247 } 00248 v[pk]=t; 00249 } 00250 } 00251 return 0; 00252 } 00253 00254 }; 00255 00256 #ifndef DOXYGENP 00257 } 00258 #endif 00259 00260 #endif 00261
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