You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							1119 lines
						
					
					
						
							45 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							1119 lines
						
					
					
						
							45 KiB
						
					
					
				| /* -*- c++ -*- (enables emacs c++ mode) */ | |
| /*=========================================================================== | |
|   | |
|  Copyright (C) 2002-2012 Yves Renard | |
|   | |
|  This file is a part of GETFEM++ | |
|   | |
|  Getfem++  is  free software;  you  can  redistribute  it  and/or modify it | |
|  under  the  terms  of the  GNU  Lesser General Public License as published | |
|  by  the  Free Software Foundation;  either version 3 of the License,  or | |
|  (at your option) any later version along with the GCC Runtime Library | |
|  Exception either version 3.1 or (at your option) any later version. | |
|  This program  is  distributed  in  the  hope  that it will be useful,  but | |
|  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
|  or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public | |
|  License and GCC Runtime Library Exception for more details. | |
|  You  should  have received a copy of the GNU Lesser General Public License | |
|  along  with  this program;  if not, write to the Free Software Foundation, | |
|  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA. | |
|   | |
|  As a special exception, you  may use  this file  as it is a part of a free | |
|  software  library  without  restriction.  Specifically,  if   other  files | |
|  instantiate  templates  or  use macros or inline functions from this file, | |
|  or  you compile this  file  and  link  it  with other files  to produce an | |
|  executable, this file  does  not  by itself cause the resulting executable | |
|  to be covered  by the GNU Lesser General Public License.  This   exception | |
|  does not  however  invalidate  any  other  reasons why the executable file | |
|  might be covered by the GNU Lesser General Public License. | |
|   | |
| ===========================================================================*/ | |
| 
 | |
| /**@file gmm_def.h | |
|    @author  Yves Renard <Yves.Renard@insa-lyon.fr> | |
|    @date October 13, 2002. | |
|    @brief Basic definitions and tools of GMM. | |
| */ | |
| #ifndef GMM_DEF_H__ | |
| #define GMM_DEF_H__ | |
|  | |
| #include "gmm_ref.h" | |
| #include <complex> | |
|  | |
| #ifndef M_PI | |
| # define	M_E		2.7182818284590452354       /* e          */ | |
| # define	M_LOG2E		1.4426950408889634074       /* 1/ln(2)    */ | |
| # define	M_LOG10E	0.43429448190325182765      /* 1/ln(10)   */ | |
| # define	M_LN2		0.69314718055994530942      /* ln(2)      */ | |
| # define	M_LN10		2.30258509299404568402      /* ln(10)     */ | |
| # define	M_PI		3.14159265358979323846      /* pi         */ | |
| # define	M_PI_2		1.57079632679489661923      /* pi/2       */ | |
| # define	M_PI_4		0.78539816339744830962      /* pi/4       */ | |
| # define	M_1_PI		0.31830988618379067154      /* 1/pi       */ | |
| # define	M_2_PI		0.63661977236758134308      /* 2/pi       */ | |
| # define	M_2_SQRTPI	1.12837916709551257390      /* 2/sqrt(pi) */ | |
| # define	M_SQRT2		1.41421356237309504880      /* sqrt(2)    */ | |
| # define	M_SQRT1_2	0.70710678118654752440      /* sqrt(2)/2  */ | |
| #endif  | |
|  | |
| #ifndef M_PIl | |
| # define M_PIl       3.1415926535897932384626433832795029L  /* pi         */ | |
| # define M_PI_2l     1.5707963267948966192313216916397514L  /* pi/2       */ | |
| # define M_PI_4l     0.7853981633974483096156608458198757L  /* pi/4       */ | |
| # define M_1_PIl     0.3183098861837906715377675267450287L  /* 1/pi       */ | |
| # define M_2_PIl     0.6366197723675813430755350534900574L  /* 2/pi       */ | |
| # define M_2_SQRTPIl 1.1283791670955125738961589031215452L  /* 2/sqrt(pi) */ | |
| #endif | |
|  | |
| namespace gmm { | |
| 
 | |
|   typedef size_t size_type; | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*		Specifier types                             		  */ | |
|   /* ******************************************************************** */ | |
|   /* not perfectly null, required by aCC 3.33                             */ | |
|   struct abstract_null_type {  | |
|     abstract_null_type(int=0) {} | |
|     template <typename A,typename B,typename C> void operator()(A,B,C) {} | |
|   }; // specify an information lake. | |
|  | |
|   struct linalg_true {}; | |
|   struct linalg_false {}; | |
| 
 | |
|   template <typename V, typename W> struct linalg_and | |
|   { typedef linalg_false bool_type; }; | |
|   template <> struct linalg_and<linalg_true, linalg_true> | |
|   { typedef linalg_true bool_type; }; | |
|   template <typename V, typename W> struct linalg_or | |
|   { typedef linalg_true bool_type; }; | |
|   template <> struct linalg_and<linalg_false, linalg_false> | |
|   { typedef linalg_false bool_type; }; | |
| 
 | |
|   struct linalg_const {};       // A reference is either linalg_const, | |
|   struct linalg_modifiable {};  //  linalg_modifiable or linalg_false. | |
|  | |
|   struct abstract_vector {};    // The object is a vector | |
|   struct abstract_matrix {};    // The object is a matrix | |
|    | |
|   struct abstract_sparse {};    // sparse matrix or vector | |
|   struct abstract_skyline {};   // 'sky-line' matrix or vector | |
|   struct abstract_dense {};     // dense matrix or vector | |
|   struct abstract_indirect {};  // matrix given by the product with a vector | |
|  | |
|   struct row_major {};          // matrix with a row access. | |
|   struct col_major {};          // matrix with a column access | |
|   struct row_and_col {};        // both accesses but row preference | |
|   struct col_and_row {};        // both accesses but column preference | |
|  | |
|   template <typename T> struct transposed_type; | |
|   template<> struct transposed_type<row_major>   {typedef col_major   t_type;}; | |
|   template<> struct transposed_type<col_major>   {typedef row_major   t_type;}; | |
|   template<> struct transposed_type<row_and_col> {typedef col_and_row t_type;}; | |
|   template<> struct transposed_type<col_and_row> {typedef row_and_col t_type;}; | |
| 
 | |
|   template <typename T> struct principal_orientation_type | |
|   { typedef abstract_null_type potype; }; | |
|   template<> struct principal_orientation_type<row_major> | |
|   { typedef row_major potype; }; | |
|   template<> struct principal_orientation_type<col_major> | |
|   { typedef col_major potype; }; | |
|   template<> struct principal_orientation_type<row_and_col> | |
|   { typedef row_major potype; }; | |
|   template<> struct principal_orientation_type<col_and_row> | |
|   { typedef col_major potype; }; | |
| 
 | |
|   //  template <typename V> struct linalg_traits; | |
|   template <typename V> struct linalg_traits {     | |
|     typedef abstract_null_type this_type; | |
|     typedef abstract_null_type linalg_type; | |
|     typedef abstract_null_type value_type; | |
|     typedef abstract_null_type is_reference; | |
|     typedef abstract_null_type& reference; | |
|     typedef abstract_null_type* iterator; | |
|     typedef const abstract_null_type* const_iterator; | |
|     typedef abstract_null_type index_sorted; | |
|     typedef abstract_null_type storage_type; | |
|     typedef abstract_null_type origin_type; | |
|     typedef abstract_null_type const_sub_row_type; | |
|     typedef abstract_null_type sub_row_type; | |
|     typedef abstract_null_type const_row_iterator; | |
|     typedef abstract_null_type row_iterator; | |
|     typedef abstract_null_type const_sub_col_type; | |
|     typedef abstract_null_type sub_col_type; | |
|     typedef abstract_null_type const_col_iterator; | |
|     typedef abstract_null_type col_iterator; | |
|     typedef abstract_null_type sub_orientation;     | |
|   }; | |
| 
 | |
|   template <typename PT, typename V> struct vect_ref_type; | |
|   template <typename P, typename V> struct vect_ref_type<P *, V> { | |
|     typedef typename linalg_traits<V>::reference access_type; | |
|     typedef typename linalg_traits<V>::iterator iterator; | |
|   }; | |
|   template <typename P, typename V> struct vect_ref_type<const P *, V> { | |
|     typedef typename linalg_traits<V>::value_type access_type; | |
|     typedef typename linalg_traits<V>::const_iterator iterator; | |
|   }; | |
|    | |
|   template <typename PT> struct const_pointer; | |
|   template <typename P> struct const_pointer<P *> | |
|   { typedef const P* pointer; }; | |
|   template <typename P> struct const_pointer<const P *> | |
|   { typedef const P* pointer; }; | |
| 
 | |
|   template <typename PT> struct modifiable_pointer; | |
|   template <typename P> struct modifiable_pointer<P *> | |
|   { typedef P* pointer; }; | |
|   template <typename P> struct modifiable_pointer<const P *> | |
|   { typedef P* pointer; }; | |
| 
 | |
|   template <typename R> struct const_reference; | |
|   template <typename R> struct const_reference<R &> | |
|   { typedef const R &reference; }; | |
|   template <typename R> struct const_reference<const R &> | |
|   { typedef const R  &reference; }; | |
| 
 | |
| 
 | |
|   inline bool is_sparse(abstract_sparse)   { return true;  } | |
|   inline bool is_sparse(abstract_dense)    { return false; } | |
|   inline bool is_sparse(abstract_skyline)  { return true;  } | |
|   inline bool is_sparse(abstract_indirect) { return false; } | |
| 
 | |
|   template <typename L> inline bool is_sparse(const L &)  | |
|   { return is_sparse(typename linalg_traits<L>::storage_type()); } | |
| 
 | |
|   inline bool is_row_matrix_(row_major)     { return true;  } | |
|   inline bool is_row_matrix_(col_major)     { return false; } | |
|   inline bool is_row_matrix_(row_and_col)   { return true;  } | |
|   inline bool is_row_matrix_(col_and_row)   { return true;  } | |
| 
 | |
|   template <typename L> inline bool is_row_matrix(const L &)  | |
|   { return is_row_matrix_(typename linalg_traits<L>::sub_orientation()); } | |
| 
 | |
|   inline bool is_col_matrix_(row_major)     { return false; } | |
|   inline bool is_col_matrix_(col_major)     { return true;  } | |
|   inline bool is_col_matrix_(row_and_col)   { return true;  } | |
|   inline bool is_col_matrix_(col_and_row)   { return true;  } | |
| 
 | |
|   template <typename L> inline bool is_col_matrix(const L &)  | |
|   { return is_col_matrix_(typename linalg_traits<L>::sub_orientation()); } | |
| 
 | |
|   inline bool is_col_matrix(row_major) { return false; } | |
|   inline bool is_col_matrix(col_major) { return true; } | |
|   inline bool is_row_matrix(row_major) { return true; } | |
|   inline bool is_row_matrix(col_major) { return false; } | |
| 
 | |
|   template <typename L> inline bool is_const_reference(L) { return false; } | |
|   inline bool is_const_reference(linalg_const) { return true; }   | |
| 
 | |
| 
 | |
|   template <typename T> struct is_gmm_interfaced_ { | |
|     typedef linalg_true result; | |
|   }; | |
|    | |
|   template<> struct is_gmm_interfaced_<abstract_null_type> { | |
|     typedef linalg_false result; | |
|   }; | |
|    | |
|   template <typename T> struct is_gmm_interfaced { | |
|     typedef typename is_gmm_interfaced_<typename gmm::linalg_traits<T>::this_type >::result result; | |
|   }; | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*  types to deal with const object representing a modifiable reference */ | |
|   /* ******************************************************************** */ | |
|    | |
|   template <typename PT, typename R> struct mref_type_  | |
|   { typedef abstract_null_type return_type; }; | |
|   template <typename L, typename R> struct mref_type_<L *, R> | |
|   { typedef L & return_type; }; | |
|   template <typename L, typename R> struct mref_type_<const L *, R> | |
|   { typedef const L & return_type; }; | |
|   template <typename L> struct mref_type_<L *, linalg_const> | |
|   { typedef const L & return_type; }; | |
|   template <typename L> struct mref_type_<const L *, linalg_const> | |
|   { typedef const L & return_type; }; | |
|   template <typename L> struct mref_type_<const L *, linalg_modifiable> | |
|   { typedef L & return_type; }; | |
|   template <typename L> struct mref_type_<L *, linalg_modifiable> | |
|   { typedef L & return_type; }; | |
| 
 | |
|   template <typename PT> struct mref_type { | |
|     typedef typename std::iterator_traits<PT>::value_type L; | |
|     typedef typename mref_type_<PT,  | |
|       typename linalg_traits<L>::is_reference>::return_type return_type; | |
|   }; | |
| 
 | |
|   template <typename L> typename mref_type<const L *>::return_type  | |
|   linalg_cast(const L &l) | |
|   { return const_cast<typename mref_type<const L *>::return_type>(l); } | |
| 
 | |
|   template <typename L> typename mref_type<L *>::return_type linalg_cast(L &l) | |
|   { return const_cast<typename mref_type<L *>::return_type>(l); } | |
| 
 | |
|   template <typename L, typename R> struct cref_type_ | |
|   { typedef abstract_null_type return_type; }; | |
|   template <typename L> struct cref_type_<L, linalg_modifiable> | |
|   { typedef L & return_type; }; | |
|   template <typename L> struct cref_type { | |
|     typedef typename cref_type_<L,  | |
|       typename linalg_traits<L>::is_reference>::return_type return_type; | |
|   }; | |
| 
 | |
|   template <typename L> typename cref_type<L>::return_type  | |
|   linalg_const_cast(const L &l) | |
|   { return const_cast<typename cref_type<L>::return_type>(l); } | |
| 
 | |
| 
 | |
|   // To be used to select between a reference or a const refercence for | |
|   // the return type of a function | |
|   // select_return<C1, C2, L *> return C1 if L is a const reference, | |
|   //                                   C2 otherwise. | |
|   // select_return<C1, C2, const L *> return C2 if L is a modifiable reference | |
|   //                                         C1 otherwise.  | |
|   template <typename C1, typename C2, typename REF> struct select_return_ { | |
|     typedef abstract_null_type return_type; | |
|   }; | |
|   template <typename C1, typename C2, typename L> | |
|   struct select_return_<C1, C2, const L &> { typedef C1 return_type; }; | |
|   template <typename C1, typename C2, typename L> | |
|   struct select_return_<C1, C2, L &> { typedef C2 return_type; }; | |
|   template <typename C1, typename C2, typename PT> struct select_return { | |
|     typedef typename std::iterator_traits<PT>::value_type L; | |
|     typedef typename select_return_<C1, C2,  | |
|       typename mref_type<PT>::return_type>::return_type return_type; | |
|   }; | |
| 
 | |
|    | |
|   // To be used to select between a reference or a const refercence inside | |
|   // a structure or a linagl_traits | |
|   // select_ref<C1, C2, L *> return C1 if L is a const reference, | |
|   //                                C2 otherwise. | |
|   // select_ref<C1, C2, const L *> return C2 in any case.  | |
|   template <typename C1, typename C2, typename REF> struct select_ref_ | |
|   { typedef abstract_null_type ref_type; }; | |
|   template <typename C1, typename C2, typename L> | |
|   struct select_ref_<C1, C2, const L &> { typedef C1 ref_type; }; | |
|   template <typename C1, typename C2, typename L> | |
|   struct select_ref_<C1, C2, L &> { typedef C2 ref_type; }; | |
|   template <typename C1, typename C2, typename PT> struct select_ref { | |
|     typedef typename std::iterator_traits<PT>::value_type L; | |
|     typedef typename select_ref_<C1, C2,  | |
|       typename mref_type<PT>::return_type>::ref_type ref_type; | |
|   }; | |
|   template <typename C1, typename C2, typename L> | |
|   struct select_ref<C1, C2, const L *> | |
|   { typedef C1 ref_type; }; | |
| 
 | |
| 
 | |
|   template<typename R> struct is_a_reference_ | |
|   { typedef linalg_true reference; }; | |
|   template<> struct is_a_reference_<linalg_false> | |
|   { typedef linalg_false reference; }; | |
| 
 | |
|   template<typename L> struct is_a_reference { | |
|     typedef typename is_a_reference_<typename linalg_traits<L>::is_reference> | |
|       ::reference reference; | |
|   }; | |
| 
 | |
| 
 | |
|   template <typename L> inline bool is_original_linalg(const L &)  | |
|   { return is_original_linalg(typename is_a_reference<L>::reference()); } | |
|   inline bool is_original_linalg(linalg_false) { return true; } | |
|   inline bool is_original_linalg(linalg_true) { return false; } | |
| 
 | |
| 
 | |
|   template <typename PT> struct which_reference  | |
|   { typedef abstract_null_type is_reference; }; | |
|   template <typename PT> struct which_reference<PT *> | |
|   { typedef linalg_modifiable is_reference; }; | |
|   template <typename PT> struct which_reference<const PT *> | |
|   { typedef linalg_const is_reference; }; | |
| 
 | |
| 
 | |
|   template <typename C1, typename C2, typename R> struct select_orientation_ | |
|   { typedef abstract_null_type return_type; }; | |
|   template <typename C1, typename C2> | |
|   struct select_orientation_<C1, C2, row_major> | |
|   { typedef C1 return_type; }; | |
|   template <typename C1, typename C2> | |
|   struct select_orientation_<C1, C2, col_major> | |
|   { typedef C2 return_type; }; | |
|   template <typename C1, typename C2, typename L> struct select_orientation { | |
|     typedef typename select_orientation_<C1, C2, | |
|       typename principal_orientation_type<typename | |
|       linalg_traits<L>::sub_orientation>::potype>::return_type return_type; | |
|   }; | |
|    | |
|   /* ******************************************************************** */ | |
|   /*		Operations on scalars                         		  */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename T> inline T sqr(T a) { return T(a * a); } | |
|   template <typename T> inline T abs(T a) { return (a < T(0)) ? T(-a) : a; } | |
|   template <typename T> inline T abs(std::complex<T> a) | |
|   { T x = a.real(), y = a.imag(); return T(::sqrt(x*x+y*y)); } | |
|   template <typename T> inline T abs_sqr(T a) { return T(a*a); } | |
|   template <typename T> inline T abs_sqr(std::complex<T> a) | |
|   { return gmm::sqr(a.real()) + gmm::sqr(a.imag()); } | |
|   template <typename T> inline T pos(T a) { return (a < T(0)) ? T(0) : a; } | |
|   template <typename T> inline T neg(T a) { return (a < T(0)) ? T(-a) : T(0); } | |
|   template <typename T> inline T sgn(T a) { return (a < T(0)) ? T(-1) : T(1); } | |
|   template <typename T> inline T Heaviside(T a) { return (a < T(0)) ? T(0) : T(1); } | |
|   inline double random() { return double(rand())/(RAND_MAX+0.5); } | |
|   template <typename T> inline T random(T) | |
|   { return T(rand()*2.0)/(T(RAND_MAX)+T(1)/T(2)) - T(1); } | |
|   template <typename T> inline std::complex<T> random(std::complex<T>) | |
|   { return std::complex<T>(gmm::random(T()), gmm::random(T())); } | |
|   template <typename T> inline T irandom(T max) | |
|   { return T(gmm::random() * double(max)); } | |
|   template <typename T> inline T conj(T a) { return a; } | |
|   template <typename T> inline std::complex<T> conj(std::complex<T> a) | |
|   { return std::conj(a); } | |
|   template <typename T> inline T real(T a) { return a; } | |
|   template <typename T> inline T real(std::complex<T> a) { return a.real(); } | |
|   template <typename T> inline T imag(T ) { return T(0); } | |
|   template <typename T> inline T imag(std::complex<T> a) { return a.imag(); }   | |
|   template <typename T> inline T sqrt(T a) { return T(::sqrt(a)); } | |
|   template <typename T> inline std::complex<T> sqrt(std::complex<T> a) { | |
|     T x = a.real(), y = a.imag(); | |
|     if (x == T(0)) { | |
|       T t = T(::sqrt(gmm::abs(y) / T(2))); | |
|       return std::complex<T>(t, y < T(0) ? -t : t); | |
|     } | |
|     T t = T(::sqrt(T(2) * (gmm::abs(a) + gmm::abs(x)))), u = t / T(2); | |
|     return x > T(0) ? std::complex<T>(u, y / t) | |
|       : std::complex<T>(gmm::abs(y) / t, y < T(0) ? -u : u); | |
|   } | |
|   using std::swap; | |
| 
 | |
| 
 | |
|   template <typename T> struct number_traits { | |
|     typedef T magnitude_type; | |
|   }; | |
|   | |
|   template <typename T> struct number_traits<std::complex<T> > { | |
|     typedef T magnitude_type; | |
|   }; | |
| 
 | |
|   template <typename T> inline T conj_product(T a, T b) { return a * b; } | |
|   template <typename T> inline | |
|   std::complex<T> conj_product(std::complex<T> a, std::complex<T> b) | |
|   { return std::conj(a) * b; } // to be optimized ? | |
|  | |
|   template <typename T> inline bool is_complex(T) { return false; } | |
|   template <typename T> inline bool is_complex(std::complex<T> ) | |
|   { return true; } | |
| 
 | |
| # define magnitude_of_linalg(M) typename number_traits<typename \ | |
|                     linalg_traits<M>::value_type>::magnitude_type | |
|    | |
|   template<typename T> inline std::complex<T> operator*(const std::complex<T>& a, int b) { | |
|     return a*T(b); | |
|   } | |
|   template<typename T> inline std::complex<T> operator*(int b, const std::complex<T>& a) { | |
|     return a*T(b); | |
|   } | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*  types promotion                                                     */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   /* should be completed for more specific cases <unsigned int, float> etc */ | |
|   template <typename T1, typename T2, bool c> | |
|   struct strongest_numeric_type_aux { | |
|     typedef T1 T; | |
|   }; | |
|   template <typename T1, typename T2> | |
|   struct strongest_numeric_type_aux<T1,T2,false> { | |
|     typedef T2 T; | |
|   }; | |
| 
 | |
|   template <typename T1, typename T2> | |
|   struct strongest_numeric_type { | |
|     typedef typename | |
|     strongest_numeric_type_aux<T1,T2,(sizeof(T1)>sizeof(T2))>::T T; | |
|   }; | |
|   template <typename T1, typename T2> | |
|   struct strongest_numeric_type<T1,std::complex<T2> > { | |
|     typedef typename number_traits<T1>::magnitude_type R1; | |
|     typedef std::complex<typename strongest_numeric_type<R1,T2>::T > T; | |
|   }; | |
|   template <typename T1, typename T2> | |
|   struct strongest_numeric_type<std::complex<T1>,T2 > { | |
|     typedef typename number_traits<T2>::magnitude_type R2; | |
|     typedef std::complex<typename strongest_numeric_type<T1,R2>::T > T; | |
|   }; | |
|   template <typename T1, typename T2>  | |
|   struct strongest_numeric_type<std::complex<T1>,std::complex<T2> > { | |
|     typedef std::complex<typename strongest_numeric_type<T1,T2>::T > T; | |
|   }; | |
| 
 | |
|   template<> struct strongest_numeric_type<int,float>   { typedef float T;  }; | |
|   template<> struct strongest_numeric_type<float,int>   { typedef float T;  }; | |
|   template<> struct strongest_numeric_type<long,float>  { typedef float T;  }; | |
|   template<> struct strongest_numeric_type<float,long>  { typedef float T;  }; | |
|   template<> struct strongest_numeric_type<long,double> { typedef double T; }; | |
|   template<> struct strongest_numeric_type<double,long> { typedef double T; }; | |
| 
 | |
|   template <typename V1, typename V2> | |
|   struct strongest_value_type { | |
|     typedef typename | |
|     strongest_numeric_type<typename linalg_traits<V1>::value_type, | |
| 			   typename linalg_traits<V2>::value_type>::T | |
|     value_type; | |
|   }; | |
|   template <typename V1, typename V2, typename V3> | |
|   struct strongest_value_type3 { | |
|     typedef typename | |
|     strongest_value_type<V1, typename | |
| 			 strongest_value_type<V2,V3>::value_type>::value_type | |
|     value_type; | |
|   }; | |
| 
 | |
|    | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*		Basic vectors used                         		  */ | |
|   /* ******************************************************************** */ | |
|    | |
|   template<typename T> struct dense_vector_type  | |
|   { typedef std::vector<T> vector_type; }; | |
| 
 | |
|   template <typename T> class wsvector; | |
|   template <typename T> class rsvector; | |
|   template<typename T> struct sparse_vector_type  | |
|   { typedef wsvector<T> vector_type; }; | |
| 
 | |
|   template <typename T> class slvector; | |
|   template <typename T> class dense_matrix; | |
|   template <typename VECT> class row_matrix; | |
|   template <typename VECT> class col_matrix; | |
|    | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*   Selects a temporary vector type                                    */ | |
|   /*   V if V is a valid vector type,                                     */ | |
|   /*   wsvector if V is a reference on a sparse vector,                   */ | |
|   /*   std::vector if V is a reference on a dense vector.                 */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|    | |
|   template <typename R, typename S, typename L, typename V> | |
|   struct temporary_vector_ { | |
|     typedef abstract_null_type vector_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_vector_<linalg_true, abstract_sparse, L, V> | |
|   { typedef wsvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V, typename L> | |
|   struct temporary_vector_<linalg_true, abstract_skyline, L, V> | |
|   { typedef slvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V, typename L> | |
|   struct temporary_vector_<linalg_true, abstract_dense, L, V> | |
|   { typedef std::vector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename S, typename V> | |
|   struct temporary_vector_<linalg_false, S, abstract_vector, V> | |
|   { typedef V vector_type; }; | |
|   template <typename V> | |
|   struct temporary_vector_<linalg_false, abstract_dense, abstract_matrix, V> | |
|   { typedef std::vector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_vector_<linalg_false, abstract_sparse, abstract_matrix, V> | |
|   { typedef wsvector<typename linalg_traits<V>::value_type> vector_type; }; | |
| 
 | |
|   template <typename V> struct temporary_vector { | |
|     typedef typename temporary_vector_<typename is_a_reference<V>::reference, | |
| 				       typename linalg_traits<V>::storage_type, | |
| 				       typename linalg_traits<V>::linalg_type, | |
| 				       V>::vector_type vector_type; | |
|   }; | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*   Selects a temporary matrix type                                    */ | |
|   /*   M if M is a valid matrix type,                                     */ | |
|   /*   row_matrix<wsvector> if M is a reference on a sparse matrix,       */ | |
|   /*   dense_matrix if M is a reference on a dense matrix.                */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|    | |
|   template <typename R, typename S, typename L, typename V> | |
|   struct temporary_matrix_ { typedef abstract_null_type matrix_type; }; | |
|   template <typename V, typename L> | |
|   struct temporary_matrix_<linalg_true, abstract_sparse, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef row_matrix<wsvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_matrix_<linalg_true, abstract_skyline, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef row_matrix<slvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_matrix_<linalg_true, abstract_dense, L, V> | |
|   { typedef dense_matrix<typename linalg_traits<V>::value_type> matrix_type; }; | |
|   template <typename S, typename V> | |
|   struct temporary_matrix_<linalg_false, S, abstract_matrix, V> | |
|   { typedef V matrix_type; }; | |
| 
 | |
|   template <typename V> struct temporary_matrix { | |
|     typedef typename temporary_matrix_<typename is_a_reference<V>::reference, | |
| 				       typename linalg_traits<V>::storage_type, | |
| 				       typename linalg_traits<V>::linalg_type, | |
| 				       V>::matrix_type matrix_type; | |
|   }; | |
| 
 | |
|    | |
|   template <typename S, typename L, typename V> | |
|   struct temporary_col_matrix_ { typedef abstract_null_type matrix_type; }; | |
|   template <typename V, typename L> | |
|   struct temporary_col_matrix_<abstract_sparse, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef col_matrix<wsvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_col_matrix_<abstract_skyline, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef col_matrix<slvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_col_matrix_<abstract_dense, L, V> | |
|   { typedef dense_matrix<typename linalg_traits<V>::value_type> matrix_type; }; | |
| 
 | |
|   template <typename V> struct temporary_col_matrix { | |
|     typedef typename temporary_col_matrix_< | |
|       typename linalg_traits<V>::storage_type, | |
|       typename linalg_traits<V>::linalg_type, | |
|       V>::matrix_type matrix_type; | |
|   }; | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|   template <typename S, typename L, typename V> | |
|   struct temporary_row_matrix_ { typedef abstract_null_type matrix_type; }; | |
|   template <typename V, typename L> | |
|   struct temporary_row_matrix_<abstract_sparse, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef row_matrix<wsvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_row_matrix_<abstract_skyline, L, V> { | |
|     typedef typename linalg_traits<V>::value_type T; | |
|     typedef row_matrix<slvector<T> > matrix_type; | |
|   }; | |
|   template <typename V, typename L> | |
|   struct temporary_row_matrix_<abstract_dense, L, V> | |
|   { typedef dense_matrix<typename linalg_traits<V>::value_type> matrix_type; }; | |
| 
 | |
|   template <typename V> struct temporary_row_matrix { | |
|     typedef typename temporary_row_matrix_< | |
|       typename linalg_traits<V>::storage_type, | |
|       typename linalg_traits<V>::linalg_type, | |
|       V>::matrix_type matrix_type; | |
|   }; | |
| 
 | |
| 
 | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*   Selects a temporary dense vector type                              */ | |
|   /*   V if V is a valid dense vector type,                               */ | |
|   /*   std::vector if V is a reference or another type of vector          */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename R, typename S, typename V> | |
|   struct temporary_dense_vector_ { typedef abstract_null_type vector_type; }; | |
|   template <typename S, typename V> | |
|   struct temporary_dense_vector_<linalg_true, S, V> | |
|   { typedef std::vector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_dense_vector_<linalg_false, abstract_sparse, V> | |
|   { typedef std::vector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_dense_vector_<linalg_false, abstract_skyline, V> | |
|   { typedef std::vector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_dense_vector_<linalg_false, abstract_dense, V> | |
|   { typedef V vector_type; }; | |
| 
 | |
|   template <typename V> struct temporary_dense_vector { | |
|     typedef typename temporary_dense_vector_<typename | |
|     is_a_reference<V>::reference, | |
|     typename linalg_traits<V>::storage_type, V>::vector_type vector_type; | |
|   }; | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*   Selects a temporary sparse vector type                             */ | |
|   /*   V if V is a valid sparse vector type,                              */ | |
|   /*   wsvector if V is a reference or another type of vector             */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename R, typename S, typename V> | |
|   struct temporary_sparse_vector_ { typedef abstract_null_type vector_type; }; | |
|   template <typename S, typename V> | |
|   struct temporary_sparse_vector_<linalg_true, S, V> | |
|   { typedef wsvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_sparse_vector_<linalg_false, abstract_sparse, V> | |
|   { typedef V vector_type; }; | |
|   template <typename V> | |
|   struct temporary_sparse_vector_<linalg_false, abstract_dense, V> | |
|   { typedef wsvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_sparse_vector_<linalg_false, abstract_skyline, V> | |
|   { typedef wsvector<typename linalg_traits<V>::value_type> vector_type; }; | |
| 
 | |
|   template <typename V> struct temporary_sparse_vector { | |
|     typedef typename temporary_sparse_vector_<typename | |
|     is_a_reference<V>::reference, | |
|     typename linalg_traits<V>::storage_type, V>::vector_type vector_type; | |
|   }; | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*   Selects a temporary sky-line vector type                           */ | |
|   /*   V if V is a valid sky-line vector type,                            */ | |
|   /*   slvector if V is a reference or another type of vector             */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename R, typename S, typename V> | |
|   struct temporary_skyline_vector_ | |
|   { typedef abstract_null_type vector_type; }; | |
|   template <typename S, typename V> | |
|   struct temporary_skyline_vector_<linalg_true, S, V> | |
|   { typedef slvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_skyline_vector_<linalg_false, abstract_skyline, V> | |
|   { typedef V vector_type; }; | |
|   template <typename V> | |
|   struct temporary_skyline_vector_<linalg_false, abstract_dense, V> | |
|   { typedef slvector<typename linalg_traits<V>::value_type> vector_type; }; | |
|   template <typename V> | |
|   struct temporary_skyline_vector_<linalg_false, abstract_sparse, V> | |
|   { typedef slvector<typename linalg_traits<V>::value_type> vector_type; }; | |
| 
 | |
|   template <typename V> struct temporary_skylines_vector { | |
|     typedef typename temporary_skyline_vector_<typename | |
|     is_a_reference<V>::reference, | |
|     typename linalg_traits<V>::storage_type, V>::vector_type vector_type; | |
|   }; | |
| 
 | |
|   /* ********************************************************************* */ | |
|   /*  Definition & Comparison of origins.                                  */ | |
|   /* ********************************************************************* */ | |
| 
 | |
|   template <typename L>  | |
|   typename select_return<const typename linalg_traits<L>::origin_type *, | |
| 			 typename linalg_traits<L>::origin_type *, | |
| 			 L *>::return_type | |
|   linalg_origin(L &l) | |
|   { return linalg_traits<L>::origin(linalg_cast(l)); } | |
| 
 | |
|   template <typename L>  | |
|   typename select_return<const typename linalg_traits<L>::origin_type *, | |
| 			 typename linalg_traits<L>::origin_type *, | |
| 			 const L *>::return_type | |
|   linalg_origin(const L &l) | |
|   { return linalg_traits<L>::origin(linalg_cast(l)); } | |
| 
 | |
|   template <typename PT1, typename PT2> | |
|   bool same_porigin(PT1, PT2) { return false; } | |
| 
 | |
|   template <typename PT> | |
|   bool same_porigin(PT pt1, PT pt2) { return (pt1 == pt2); } | |
| 
 | |
|   template <typename L1, typename L2> | |
|   bool same_origin(const L1 &l1, const L2 &l2) | |
|   { return same_porigin(linalg_origin(l1), linalg_origin(l2)); } | |
| 
 | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*		Miscellaneous                           		  */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename V> inline size_type vect_size(const V &v) | |
|   { return linalg_traits<V>::size(v); } | |
| 
 | |
|   template <typename MAT> inline size_type mat_nrows(const MAT &m) | |
|   { return linalg_traits<MAT>::nrows(m); } | |
| 
 | |
|   template <typename MAT> inline size_type mat_ncols(const MAT &m) | |
|   { return linalg_traits<MAT>::ncols(m); } | |
| 
 | |
| 
 | |
|   template <typename V> inline | |
|   typename select_return<typename linalg_traits<V>::const_iterator, | |
|            typename linalg_traits<V>::iterator, V *>::return_type | |
|   vect_begin(V &v) | |
|   { return linalg_traits<V>::begin(linalg_cast(v)); } | |
| 
 | |
|   template <typename V> inline | |
|   typename select_return<typename linalg_traits<V>::const_iterator, | |
| 	   typename linalg_traits<V>::iterator, const V *>::return_type | |
|   vect_begin(const V &v) | |
|   { return linalg_traits<V>::begin(linalg_cast(v)); } | |
| 
 | |
|   template <typename V> inline | |
|   typename linalg_traits<V>::const_iterator | |
|   vect_const_begin(const V &v) | |
|   { return linalg_traits<V>::begin(v); } | |
| 
 | |
|   template <typename V> inline | |
|   typename select_return<typename linalg_traits<V>::const_iterator, | |
|     typename linalg_traits<V>::iterator, V *>::return_type | |
|   vect_end(V &v) | |
|   { return linalg_traits<V>::end(linalg_cast(v)); } | |
| 
 | |
|   template <typename V> inline | |
|   typename select_return<typename linalg_traits<V>::const_iterator, | |
|     typename linalg_traits<V>::iterator, const V *>::return_type | |
|   vect_end(const V &v) | |
|   { return linalg_traits<V>::end(linalg_cast(v)); } | |
| 
 | |
|   template <typename V> inline | |
|   typename linalg_traits<V>::const_iterator | |
|   vect_const_end(const V &v) | |
|   { return linalg_traits<V>::end(v); } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_row_iterator, | |
|     typename linalg_traits<M>::row_iterator, M *>::return_type | |
|   mat_row_begin(M &m) { return linalg_traits<M>::row_begin(linalg_cast(m)); } | |
|    | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_row_iterator, | |
|     typename linalg_traits<M>::row_iterator, const M *>::return_type | |
|   mat_row_begin(const M &m) | |
|   { return linalg_traits<M>::row_begin(linalg_cast(m)); } | |
|    | |
|   template <typename M> inline typename linalg_traits<M>::const_row_iterator | |
|   mat_row_const_begin(const M &m) | |
|   { return linalg_traits<M>::row_begin(m); } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_row_iterator, | |
|     typename linalg_traits<M>::row_iterator, M *>::return_type | |
|   mat_row_end(M &v) { | |
|     return linalg_traits<M>::row_end(linalg_cast(v)); | |
|   } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_row_iterator, | |
|     typename linalg_traits<M>::row_iterator, const M *>::return_type | |
|   mat_row_end(const M &v) { | |
|     return linalg_traits<M>::row_end(linalg_cast(v)); | |
|   } | |
| 
 | |
|   template <typename M> inline | |
|   typename linalg_traits<M>::const_row_iterator | |
|   mat_row_const_end(const M &v) | |
|   { return linalg_traits<M>::row_end(v); } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_col_iterator, | |
|     typename linalg_traits<M>::col_iterator, M *>::return_type | |
|   mat_col_begin(M &v) { | |
|     return linalg_traits<M>::col_begin(linalg_cast(v)); | |
|   } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_col_iterator, | |
|     typename linalg_traits<M>::col_iterator, const M *>::return_type | |
|   mat_col_begin(const M &v) { | |
|     return linalg_traits<M>::col_begin(linalg_cast(v)); | |
|   } | |
| 
 | |
|   template <typename M> inline | |
|   typename linalg_traits<M>::const_col_iterator | |
|   mat_col_const_begin(const M &v) | |
|   { return linalg_traits<M>::col_begin(v); } | |
| 
 | |
|   template <typename M> inline | |
|   typename linalg_traits<M>::const_col_iterator | |
|   mat_col_const_end(const M &v) | |
|   { return linalg_traits<M>::col_end(v); } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_col_iterator, | |
|                          typename linalg_traits<M>::col_iterator, | |
|                          M *>::return_type | |
|   mat_col_end(M &m) | |
|   { return linalg_traits<M>::col_end(linalg_cast(m)); } | |
| 
 | |
|   template <typename M> inline | |
|   typename select_return<typename linalg_traits<M>::const_col_iterator, | |
|                          typename linalg_traits<M>::col_iterator, | |
|                          const M *>::return_type | |
|   mat_col_end(const M &m) | |
|   { return linalg_traits<M>::col_end(linalg_cast(m)); } | |
| 
 | |
|   template <typename MAT> inline | |
|   typename select_return<typename linalg_traits<MAT>::const_sub_row_type, | |
|                          typename linalg_traits<MAT>::sub_row_type, | |
|                          const MAT *>::return_type | |
|   mat_row(const MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::row(mat_row_begin(m) + i); } | |
| 
 | |
|   template <typename MAT> inline | |
|   typename select_return<typename linalg_traits<MAT>::const_sub_row_type, | |
|                          typename linalg_traits<MAT>::sub_row_type, | |
|                          MAT *>::return_type | |
|   mat_row(MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::row(mat_row_begin(m) + i); } | |
| 
 | |
|   template <typename MAT> inline | |
|   typename linalg_traits<MAT>::const_sub_row_type | |
|   mat_const_row(const MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::row(mat_row_const_begin(m) + i); } | |
| 
 | |
|   template <typename MAT> inline | |
|   typename select_return<typename linalg_traits<MAT>::const_sub_col_type, | |
|                          typename linalg_traits<MAT>::sub_col_type, | |
|                          const MAT *>::return_type | |
|   mat_col(const MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::col(mat_col_begin(m) + i); } | |
| 
 | |
| 
 | |
|   template <typename MAT> inline | |
|   typename select_return<typename linalg_traits<MAT>::const_sub_col_type, | |
|                          typename linalg_traits<MAT>::sub_col_type, | |
|                          MAT *>::return_type | |
|   mat_col(MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::col(mat_col_begin(m) + i); } | |
|    | |
|   template <typename MAT> inline | |
|   typename linalg_traits<MAT>::const_sub_col_type | |
|   mat_const_col(const MAT &m, size_type i) | |
|   { return linalg_traits<MAT>::col(mat_col_const_begin(m) + i); } | |
|    | |
|   /* ********************************************************************* */ | |
|   /* Set to begin end set to end for iterators on non-const sparse vectors.*/ | |
|   /* ********************************************************************* */ | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &it, ORG o, VECT *, linalg_false) | |
|   { it = vect_begin(*o); } | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &it, ORG o, const VECT *, linalg_false)  | |
|   { it = vect_const_begin(*o); } | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &it, ORG o, VECT *, linalg_false) | |
|   { it = vect_end(*o); } | |
|    | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &it, ORG o, const VECT *, linalg_false) | |
|   { it = vect_const_end(*o); } | |
| 
 | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &, ORG, VECT *, linalg_const) { } | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &, ORG, const VECT *, linalg_const) { } | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &, ORG, VECT *, linalg_const) { } | |
|    | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &, ORG, const VECT *, linalg_const) { } | |
| 
 | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &, ORG, VECT *v, linalg_modifiable) | |
|   { GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; } | |
| 
 | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_begin(IT &, ORG, const VECT *v, linalg_modifiable) | |
|   { GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; } | |
|   | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &, ORG, VECT *v, linalg_modifiable) | |
|   { GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; } | |
|    | |
|   template <typename IT, typename ORG, typename VECT> inline | |
|   void set_to_end(IT &, ORG, const VECT *v, linalg_modifiable) | |
|   { GMM_ASSERT3(!is_sparse(*v), "internal_error"); v = 0; } | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*		General index for certain algorithms.         		  */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template<class IT>  | |
|   size_type index_of_it(const IT &it, size_type, abstract_sparse) | |
|   { return it.index(); } | |
|   template<class IT>  | |
|   size_type index_of_it(const IT &it, size_type, abstract_skyline) | |
|   { return it.index(); } | |
|   template<class IT>  | |
|   size_type index_of_it(const IT &, size_type k, abstract_dense) | |
|   { return k; } | |
| 
 | |
|   /* ********************************************************************* */ | |
|   /* Numeric limits.                                                       */ | |
|   /* ********************************************************************* */ | |
|    | |
|   template<typename T> inline T default_tol(T) { | |
|     using namespace std; | |
|     static T tol(10); | |
|     if (tol == T(10)) { | |
|       if (numeric_limits<T>::is_specialized) | |
| 	tol = numeric_limits<T>::epsilon(); | |
|       else { | |
| 	int i=sizeof(T)/4; while(i-- > 0) tol*=T(1E-8);  | |
| 	GMM_WARNING1("The numeric type " << typeid(T).name() | |
| 		    << " has no numeric_limits defined !!\n" | |
| 		    << "Taking " << tol << " as default tolerance"); | |
|       } | |
|     } | |
|     return tol; | |
|   } | |
|   template<typename T> inline T default_tol(std::complex<T>) | |
|   { return default_tol(T()); } | |
| 
 | |
|   template<typename T> inline T default_min(T) { | |
|     using namespace std; | |
|     static T mi(10); | |
|     if (mi == T(10)) { | |
|       if (numeric_limits<T>::is_specialized) | |
| 	mi = std::numeric_limits<T>::min(); | |
|       else { | |
| 	mi = T(0); | |
| 	GMM_WARNING1("The numeric type " << typeid(T).name() | |
| 		    << " has no numeric_limits defined !!\n" | |
| 		    << "Taking 0 as default minimum"); | |
|       } | |
|     } | |
|     return mi; | |
|   } | |
|   template<typename T> inline T default_min(std::complex<T>) | |
|   { return default_min(T()); } | |
| 
 | |
|   template<typename T> inline T default_max(T) { | |
|     using namespace std; | |
|     static T mi(10); | |
|     if (mi == T(10)) { | |
|       if (numeric_limits<T>::is_specialized) | |
| 	mi = std::numeric_limits<T>::max(); | |
|       else { | |
| 	mi = T(1); | |
| 	GMM_WARNING1("The numeric type " << typeid(T).name() | |
| 		    << " has no numeric_limits defined !!\n" | |
| 		    << "Taking 1 as default maximum !"); | |
|       } | |
|     } | |
|     return mi; | |
|   } | |
|   template<typename T> inline T default_max(std::complex<T>) | |
|   { return default_max(T()); } | |
| 
 | |
|    | |
|   /* | |
|     use safe_divide to avoid NaNs when dividing very small complex | |
|     numbers, for example | |
|     std::complex<float>(1e-23,1e-30)/std::complex<float>(1e-23,1e-30) | |
|   */ | |
|   template<typename T> inline T safe_divide(T a, T b) { return a/b; } | |
|   template<typename T> inline std::complex<T> | |
|   safe_divide(std::complex<T> a, std::complex<T> b) { | |
|     T m = std::max(gmm::abs(b.real()), gmm::abs(b.imag())); | |
|     a = std::complex<T>(a.real()/m, a.imag()/m); | |
|     b = std::complex<T>(b.real()/m, b.imag()/m); | |
|     return a / b; | |
|   } | |
| 
 | |
| 
 | |
|   /* ******************************************************************** */ | |
|   /*		Write                                   		  */ | |
|   /* ******************************************************************** */ | |
| 
 | |
|   template <typename T> struct cast_char_type { typedef T return_type; }; | |
|   template <> struct cast_char_type<signed char> { typedef int return_type; }; | |
|   template <> struct cast_char_type<unsigned char> | |
|   { typedef unsigned int return_type; }; | |
|   template <typename T> inline typename cast_char_type<T>::return_type | |
|   cast_char(const T &c) { return typename cast_char_type<T>::return_type(c); } | |
| 
 | |
| 
 | |
|   template <typename L> inline void write(std::ostream &o, const L &l) | |
|   { write(o, l, typename linalg_traits<L>::linalg_type()); } | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, | |
| 				       abstract_vector) { | |
|     o << "vector(" << vect_size(l) << ") ["; | |
|     write(o, l, typename linalg_traits<L>::storage_type()); | |
|     o << " ]"; | |
|   } | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, | |
| 				       abstract_sparse) { | |
|     typename linalg_traits<L>::const_iterator it = vect_const_begin(l), | |
|       ite = vect_const_end(l); | |
|     for (; it != ite; ++it)  | |
|       o << " (r" << it.index() << "," << cast_char(*it) << ")"; | |
|   } | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, | |
| 				       abstract_dense) { | |
|     typename linalg_traits<L>::const_iterator it = vect_const_begin(l), | |
|       ite = vect_const_end(l); | |
|     if (it != ite) o << " " << cast_char(*it++); | |
|     for (; it != ite; ++it) o << ", " << cast_char(*it); | |
|   } | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, | |
| 				       abstract_skyline) { | |
|     typedef typename linalg_traits<L>::const_iterator const_iterator; | |
|     const_iterator it = vect_const_begin(l), ite = vect_const_end(l); | |
|     if (it != ite) { | |
|       o << "<r+" << it.index() << ">"; | |
|       if (it != ite) o << " " << cast_char(*it++); | |
|       for (; it != ite; ++it) { o << ", " << cast_char(*it); } | |
|     } | |
|   } | |
| 
 | |
|   template <typename L> inline void write(std::ostream &o, const L &l, | |
| 				       abstract_matrix) { | |
|     write(o, l, typename linalg_traits<L>::sub_orientation()); | |
|   } | |
| 
 | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, | |
| 				       row_major) { | |
|     o << "matrix(" << mat_nrows(l) << ", " << mat_ncols(l) << ")" << endl; | |
|     for (size_type i = 0; i < mat_nrows(l); ++i) { | |
|       o << "("; | |
|       write(o, mat_const_row(l, i), typename linalg_traits<L>::storage_type()); | |
|       o << " )\n"; | |
|     } | |
|   } | |
| 
 | |
|   template <typename L> inline | |
|   void write(std::ostream &o, const L &l, row_and_col)  | |
|   { write(o, l, row_major()); } | |
| 
 | |
|   template <typename L> inline | |
|   void write(std::ostream &o, const L &l, col_and_row) | |
|   { write(o, l, row_major()); } | |
| 
 | |
|   template <typename L> void write(std::ostream &o, const L &l, col_major) { | |
|     o << "matrix(" << mat_nrows(l) << ", " << mat_ncols(l) << ")" << endl; | |
|     for (size_type i = 0; i < mat_nrows(l); ++i) { | |
|       o << "("; | |
|       if (is_sparse(l)) { // not optimized ... | |
| 	for (size_type j = 0; j < mat_ncols(l); ++j) | |
| 	  if (l(i,j) != typename linalg_traits<L>::value_type(0))  | |
| 	    o << " (r" << j << ", " << l(i,j) << ")"; | |
|       } | |
|       else { | |
| 	if (mat_ncols(l) != 0) o << ' ' << l(i, 0); | |
| 	for (size_type j = 1; j < mat_ncols(l); ++j) o << ", " << l(i, j);  | |
|       } | |
|       o << " )\n"; | |
|     } | |
|   } | |
| 
 | |
| } | |
| 
 | |
| #endif //  GMM_DEF_H__
 |