TooN 2.1
|
00001 //-*- c++ -*- 00002 00003 // Copyright (C) 2005,2009 Tom Drummond (twd20@cam.ac.uk), 00004 // Ed Rosten (er258@cam.ac.uk), Gerhard Reitmayr (gr281@cam.ac.uk) 00005 // 00006 // This file is part of the TooN Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 2, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // You should have received a copy of the GNU General Public License along 00018 // with this library; see the file COPYING. If not, write to the Free 00019 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 00020 // USA. 00021 00022 // As a special exception, you may use this file as part of a free software 00023 // library without restriction. Specifically, if other files instantiate 00024 // templates or use macros or inline functions from this file, or you compile 00025 // this file and link it with other files to produce an executable, this 00026 // file does not by itself cause the resulting executable to be covered by 00027 // the GNU General Public License. This exception does not however 00028 // invalidate any other reasons why the executable file might be covered by 00029 // the GNU General Public License. 00030 00031 00032 #ifndef TOON_INCLUDE_TOON_H 00033 #define TOON_INCLUDE_TOON_H 00034 #include <iostream> 00035 #include <cstdlib> 00036 #include <limits> 00037 #include <new> 00038 #include <utility> 00039 #include <vector> 00040 #include <complex> 00041 #include <TooN/internal/config.hh> 00042 #include <TooN/internal/typeof.hh> 00043 #include <TooN/internal/deprecated.hh> 00044 00045 #if defined TOON_NDEBUG || defined NDEBUG 00046 #define TOON_NDEBUG_MISMATCH 00047 #define TOON_NDEBUG_SLICE 00048 #define TOON_NDEBUG_SIZE 00049 #define TOON_NDEBUG_FILL 00050 #endif 00051 00052 #ifdef TOON_INITIALIZE_RANDOM 00053 #include <ctime> 00054 #endif 00055 00056 #ifdef TOON_USE_LAPACK 00057 #ifndef TOON_DETERMINANT_LAPACK 00058 #define TOON_DETERMINANT_LAPACK 35 00059 #endif 00060 #endif 00061 00062 ///Everything lives inside this namespace 00063 namespace TooN { 00064 00065 #ifdef TOON_TEST_INTERNALS 00066 namespace Internal 00067 { 00068 struct BadIndex{}; 00069 struct SliceError{}; 00070 struct StaticSliceError{}; 00071 struct SizeMismatch{}; 00072 struct StaticSizeMismatch{}; 00073 struct VectorOverfill{}; 00074 struct StaticVectorOverfill{}; 00075 struct MatrixOverfill{}; 00076 struct StaticMatrixOverfill{}; 00077 struct Underfill{}; 00078 } 00079 #endif 00080 00081 using std::numeric_limits; 00082 ///Is a number a field? i.e., +, -, *, / defined. 00083 /// 00084 ///Specialize this to make TooN work properly with new types. See, for example functions/fadbad.h 00085 /// 00086 ///Specifically, is the type on the default field. Because of the conversion rules 00087 ///of C++, TooN uses a rather loose definition of field. The a type is on the 00088 ///default field if arithmetic works between it and any builtin numeric type. So, for 00089 ///instance unsigned char and float are considered to be on the default field even though 00090 ///by themselves they form very different fields. 00091 /// 00092 ///See also Field. 00093 /// 00094 ///The reason for this is so that <code> makeVector(1, 0, 0) </code> behaves as expected 00095 ///even though it will actually be a <code> Vector<3,int></code>. 00096 /// 00097 /// 00098 /// 00099 ///The primary reason for this is to allow SFINAE to work properly. 00100 ///This is required if there are the following two functions: 00101 ///@code 00102 /// Vector<> * X //Generic type X 00103 /// Vector<> * DiagonalMatrix<> 00104 ///@endcode 00105 ///If one of the functions is a substitution failure, then it will be 00106 ///ignored, allowing the functions to coexist happily. However, not all 00107 ///types of failure are substitution failures. TooN's type deduction happens 00108 ///when determining the return type of the function. This is too early, so 00109 ///the wrong kind of error in the return type deduction causes an error, rather 00110 ///than a substitution failure. The IsField mechanism makes it the right kind of 00111 ///error, thereby allowing a substitution failuer to occur. 00112 /// 00113 ///@internal 00114 ///Internal::One is on the same field of any type which is also a field. 00115 ///@ingroup gLinAlg 00116 template<class C> struct IsField 00117 { 00118 static const int value = numeric_limits<C>::is_specialized; ///<Is C a field? 00119 }; 00120 00121 template<class C> struct IsField<std::complex<C> > 00122 { 00123 static const int value = numeric_limits<C>::is_specialized; ///<Is C a field? 00124 }; 00125 00126 ///Specialized for const types 00127 ///@internal 00128 ///Internal::Field determines if two classes are in the same field. 00129 ///@ingroup gLinAlg 00130 template<class C> struct IsField<const C> 00131 { 00132 static const int value = IsField<C>::value; ///<Is C a field? 00133 }; 00134 00135 template<class C, class D> struct These_Types_Do_Not_Form_A_Field; 00136 00137 ///@internal 00138 ///@brief The namaespace holding all the internal code. 00139 namespace Internal 00140 { 00141 ///@internal 00142 ///@brief Maximum number of bytes to be allocated on the stack. 00143 ///new is used above this number. 00144 static const unsigned int max_bytes_on_stack=1000; 00145 ///@internal 00146 ///@brief A tag used to indicate that a slice is being constructed. 00147 ///@ingroup gInternal 00148 struct Slicing{}; 00149 template<int RowStride, int ColStride> struct Slice; 00150 template<int Size, typename Precision, int Stride, typename Mem> struct GenericVBase; 00151 } 00152 00153 template<int Size, class Precision, class Base> struct Vector; 00154 template<int Rows, int Cols, class Precision, class Base> struct Matrix; 00155 template<int Size, class Precision, class Base> struct DiagonalMatrix; 00156 00157 00158 #ifdef DOXYGEN_INCLUDE_ONLY_FOR_DOCS 00159 ///@internal 00160 ///@brief This is a struct used heavily in TooN internals. 00161 /// 00162 ///They have two main uses. The first use is in construction and is completely hidden. 00163 ///For an expression such as a+b, the return value of operator+ will be constructed in 00164 ///place in the return statement, to prevent excessive copying and calls to new/delete. 00165 /// 00166 ///The other use is much more visible and is for objects such as TooN::Zeros and TooN::Idendity . 00167 /// 00168 ///The features allowed (construction, addition, etc) depend on the members present. 00169 ///For simplicity, general arguments are given below. If members are non-general, then the 00170 ///operators will simply not be applicable to all vectors or matrices. 00171 /// 00172 ///Operators belong to any of a number of categories depending on the members they provide. 00173 ///The categories are: 00174 /// 00175 /// - Sized operators 00176 /// - These know their own size and provide. 00177 /// The sizes are used only in construction of dynamic vectors or 00178 /// matrices. 00179 /// - Sizeable operators 00180 /// - Sizeable operators are able to generate a sized operator of the same sort. 00181 /// - Scalable operators 00182 /// - These can be multiplied and divided by scalars. 00183 /// 00184 ///@ingroup gInternal 00185 template<typename T> struct Operator{ 00186 ///@name Members in the category ``sized operators'' 00187 ///@{ 00188 00189 ///This must be provided in order to construct dynamic vectors. 00190 int size() const; 00191 ///This along with num_cols() must be present in order to construct matrices. 00192 int num_rows() const; 00193 ///This along with num_rows() must be present in order to construct matrices. 00194 int num_cols() const; 00195 ///@} 00196 00197 ///@name Members used by Vector 00198 ///@{ 00199 00200 ///This function must be present for construction and assignment 00201 ///of vectors to work. 00202 template<int Size, class Precision, class Base> 00203 void eval(Vector<Size, Precision, Base>& v) const; 00204 00205 ///This must be present for vector += operator 00206 template <int Size, typename P1, typename B1> 00207 void plusequals(Vector<Size, P1, B1>& v) const; 00208 00209 ///This must be present for vector -= operator 00210 template <int Size, typename P1, typename B1> 00211 void minusequals(Vector<Size, P1, B1>& v) const; 00212 00213 ///This function must be present for vector + operator 00214 ///and operator + vector 00215 template <int Size, typename P1, typename B1> 00216 Operator<T> add(const Vector<Size, P1, B1>& v) const; 00217 00218 ///This function must be present for vector - operator 00219 template <int Size, typename P1, typename B1> 00220 Operator<T> rsubtract(const Vector<Size, P1, B1>& v) const; 00221 00222 ///This function must be present for operator - vector 00223 template <int Size, typename P1, typename B1> 00224 Operator<T> lsubtract(const Vector<Size, P1, B1>& v) const; 00225 00226 ///@} 00227 00228 ///@name Members used by Matrix 00229 ///@{ 00230 ///This function must be present for construction and assignment 00231 ///of matrices to work. 00232 template<int R, int C, class P, class B> 00233 void eval(Matrix<R,C,P,B>& m) const; 00234 00235 ///This function must be present for matrix + operator 00236 ///and operator + matrix 00237 template <int Rows, int Cols, typename P1, typename B1> 00238 Operator<T> add(const Matrix<Rows,Cols, P1, B1>& m) const; 00239 00240 00241 ///This function must be present for matrix - operator 00242 template <int Rows, int Cols, typename P1, typename B1> 00243 Operator<T> rsubtract(const Matrix<Rows,Cols, P1, B1>& m) const; 00244 00245 ///This function must be present for operator - matrix 00246 template <int Rows, int Cols, typename P1, typename B1> 00247 Operator<T> lsubtract(const Matrix<Rows,Cols, P1, B1>& m) const; 00248 00249 ///This must be present for matrix += operator 00250 template <int Rows, int Cols, typename P1, typename B1> 00251 void plusequals(Matrix<Rows,Cols, P1, B1>& m) const; 00252 00253 ///This must be present for matrix -= operator 00254 template <int Rows, int Cols, typename P1, typename B1> 00255 void minusequals(Matrix<Rows,Cols, P1, B1>& m) const; 00256 ///@} 00257 00258 00259 ///@name Members in the category ``sizeable oberators'' 00260 ///@{ 00261 00262 ///Create an operator that knows its size. 00263 ///Suitable for vectors and square matrices. 00264 Operator<T> operator()(int size) const; 00265 00266 ///Create an operator that knows its size, suitable for matrices. 00267 Operator<T> operator()(int num_rows, int num_cols) const; 00268 ///@} 00269 00270 ///@name Members in the category ``scalable operators'' 00271 ///@{ 00272 typedef T Precision; ///<Precision of the operator's scale. 00273 00274 ///Scale the operator by a scalar and return a new opeator. 00275 template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > scale_me(const Pmult& m) const 00276 { 00277 return Operator<Internal::Identity<Pout> >(val*m); 00278 } 00279 ///@} 00280 00281 }; 00282 #else 00283 template<typename T> struct Operator; 00284 #endif 00285 00286 ///Template size value used to indicate dynamically sized vectors and matrices. 00287 static const int Dynamic = -1; 00288 static const int Resizable = -0x7fffffff; 00289 00290 namespace Internal 00291 { 00292 template<int i, int j> struct SimpleSizer{static const int size=i;}; 00293 template<int i> struct SimpleSizer<Dynamic, i>{static const int size=i;}; 00294 template<int i> struct SimpleSizer<i, Dynamic>{static const int size=i;}; 00295 template<> struct SimpleSizer<Dynamic, Dynamic> {static const int size=-1;}; 00296 00297 template<int i> struct IsStatic 00298 { 00299 static const bool is = (i!=Dynamic && i != Resizable); 00300 }; 00301 00302 //Choose an output size, given a pair of input sizes. Be static if possible. 00303 template<int i, int j=i> struct Sizer{ 00304 static const int size=SimpleSizer<Sizer<i>::size, Sizer<j>::size>::size; 00305 }; 00306 00307 //Choose an output size, given an input size. Be static if possible. 00308 //Otherwise be dynamic. Never generate a resizable vector. 00309 template<int i> struct Sizer<i,i>{ 00310 static const int size = IsStatic<i>::is?i:Dynamic; 00311 }; 00312 } 00313 00314 ///All TooN classes default to using this precision for computations and storage. 00315 #ifndef TOON_DEFAULT_PRECISION 00316 typedef double DefaultPrecision; 00317 #else 00318 typedef TOON_DEFAULT_PRECISION DefaultPrecision; 00319 #endif 00320 00321 #if defined TOON_FORTRAN_INTEGER && defined TOON_CLAPACK 00322 #error Error: both TOON_FORTRAN_INTEGER and TOON_CLAPACK defined 00323 #elif defined TOON_CLAPACK 00324 typedef long FortranInteger; 00325 #elif defined TOON_FORTRAN_INTEGER 00326 typedef TOON_FORTRAN_INTEGER FortranInteger; 00327 #else 00328 typedef int FortranInteger; 00329 #endif 00330 00331 } 00332 00333 #include <TooN/internal/debug.hh> 00334 00335 #include <TooN/internal/introspection.hh> 00336 00337 00338 #include <TooN/internal/dchecktest.hh> 00339 #include <TooN/internal/allocator.hh> 00340 00341 #include <TooN/internal/size_mismatch.hh> 00342 #include <TooN/internal/overfill_error.hh> 00343 #include <TooN/internal/slice_error.hh> 00344 00345 #include <TooN/internal/comma.hh> 00346 00347 #include <TooN/internal/vbase.hh> 00348 #include <TooN/internal/vector.hh> 00349 00350 #include <TooN/internal/mbase.hh> 00351 #include <TooN/internal/matrix.hh> 00352 #include <TooN/internal/reference.hh> 00353 00354 #include <TooN/internal/make_vector.hh> 00355 #include <TooN/internal/operators.hh> 00356 00357 #include <TooN/internal/objects.h> 00358 00359 #include <TooN/internal/diagmatrix.h> 00360 00361 #include <TooN/internal/data.hh> 00362 #include <TooN/internal/data_functions.hh> 00363 00364 #include <TooN/helpers.h> 00365 #include <TooN/determinant.h> 00366 00367 #endif