Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/numeric/ublas/traits.hpp @ 33

Last change on this file since 33 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 18.5 KB
RevLine 
[29]1//
2//  Copyright (c) 2000-2002
3//  Joerg Walter, Mathias Koch
4//
5//  Permission to use, copy, modify, distribute and sell this software
6//  and its documentation for any purpose is hereby granted without fee,
7//  provided that the above copyright notice appear in all copies and
8//  that both that copyright notice and this permission notice appear
9//  in supporting documentation.  The authors make no representations
10//  about the suitability of this software for any purpose.
11//  It is provided "as is" without express or implied warranty.
12//
13//  The authors gratefully acknowledge the support of
14//  GeNeSys mbH & Co. KG in producing this work.
15//
16
17#ifndef _BOOST_UBLAS_TRAITS_
18#define _BOOST_UBLAS_TRAITS_
19
20#include <iterator>
21#include <complex>
22#include <cmath>
23
24#include <boost/numeric/ublas/detail/config.hpp>
25#include <boost/numeric/ublas/detail/iterator.hpp>
26#include <boost/numeric/ublas/detail/returntype_deduction.hpp>
27
28
29namespace boost { namespace numeric { namespace ublas {
30
31    // Use Joel de Guzman's return type deduction
32    // uBLAS assumes a common return type for all binary arithmetic operators
33    template<class X, class Y>
34    struct promote_traits {
35        typedef type_deduction_detail::base_result_of<X, Y> base_type;
36        static typename base_type::x_type x;
37        static typename base_type::y_type y;
38        static const std::size_t size = sizeof (
39                type_deduction_detail::test<
40                    typename base_type::x_type
41                  , typename base_type::y_type
42                >(x + y)     // Use x+y to stand of all the arithmetic actions
43            );
44
45        static const std::size_t index = (size / sizeof (char)) - 1;
46        typedef typename mpl::at_c<
47            typename base_type::types, index>::type id;
48        typedef typename id::type promote_type;
49    };
50
51
52        // Type traits - generic numeric properties and functions
53    template<class T>
54    struct type_traits;
55       
56    // Define properties for a generic scalar type
57    template<class T>
58    struct scalar_traits {
59        typedef scalar_traits<T> self_type;
60        typedef T value_type;
61        typedef const T &const_reference;
62        typedef T &reference;
63
64        typedef T real_type;
65        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
66
67        static const unsigned plus_complexity = 1;
68        static const unsigned multiplies_complexity = 1;
69
70        static
71        BOOST_UBLAS_INLINE
72        real_type real (const_reference t) {
73                return t;
74        }
75        static
76        BOOST_UBLAS_INLINE
77        real_type imag (const_reference /*t*/) {
78                return 0;
79        }
80        static
81        BOOST_UBLAS_INLINE
82        value_type conj (const_reference t) {
83                return t;
84        }
85
86        static
87        BOOST_UBLAS_INLINE
88        real_type type_abs (const_reference t) {
89            return std::abs (t);    // must use explict std:: as bultin types are not in std namespace
90        }
91        static
92        BOOST_UBLAS_INLINE
93        value_type type_sqrt (const_reference t) {
94               // force a type conversion back to value_type for intgral types
95            return value_type (std::sqrt (t));   // must use explict std:: as bultin types are not in std namespace
96        }
97
98        static
99        BOOST_UBLAS_INLINE
100        real_type norm_1 (const_reference t) {
101            return self_type::type_abs (t);
102        }
103        static
104        BOOST_UBLAS_INLINE
105        real_type norm_2 (const_reference t) {
106            return self_type::type_abs (t);
107        }
108        static
109        BOOST_UBLAS_INLINE
110        real_type norm_inf (const_reference t) {
111            return self_type::type_abs (t);
112        }
113
114        static
115        BOOST_UBLAS_INLINE
116        bool equals (const_reference t1, const_reference t2) {
117            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
118                   (std::max) ((std::max) (self_type::norm_inf (t1),
119                                       self_type::norm_inf (t2)),
120                             BOOST_UBLAS_TYPE_CHECK_MIN);
121        }
122    };
123
124    // Define default type traits, assume T is a scalar type
125    template<class T>
126    struct type_traits : scalar_traits <T> {
127        typedef type_traits<T> self_type;
128        typedef T value_type;
129        typedef const T &const_reference;
130        typedef T &reference;
131
132        typedef T real_type;
133        typedef real_type precision_type;
134        static const unsigned multiplies_complexity = 1;
135
136    };
137
138    // Define real type traits
139    template<>
140    struct type_traits<float> : scalar_traits<float> {
141        typedef type_traits<float> self_type;
142        typedef float value_type;
143        typedef const value_type &const_reference;
144        typedef value_type &reference;
145        typedef value_type real_type;
146        typedef double precision_type;
147    };
148    template<>
149    struct type_traits<double> : scalar_traits<double> {
150        typedef type_traits<double> self_type;
151        typedef double value_type;
152        typedef const value_type &const_reference;
153        typedef value_type &reference;
154        typedef value_type real_type;
155        typedef long double precision_type;
156    };
157    template<>
158    struct type_traits<long double>  : scalar_traits<long double> {
159        typedef type_traits<long double> self_type;
160        typedef long double value_type;
161        typedef const value_type &const_reference;
162        typedef value_type &reference;
163        typedef value_type real_type;
164        typedef value_type precision_type;
165    };
166
167    // Define properties for a generic complex type
168    template<class T>
169    struct complex_traits {
170        typedef complex_traits<T> self_type;
171        typedef T value_type;
172        typedef const T &const_reference;
173        typedef T &reference;
174
175        typedef typename T::value_type real_type;
176        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
177
178        static const unsigned plus_complexity = 2;
179        static const unsigned multiplies_complexity = 6;
180
181        static
182        BOOST_UBLAS_INLINE
183        real_type real (const_reference t) {
184                return std::real (t);
185        }
186        static
187        BOOST_UBLAS_INLINE
188        real_type imag (const_reference t) {
189                return std::imag (t);
190        }
191        static
192        BOOST_UBLAS_INLINE
193        value_type conj (const_reference t) {
194                return std::conj (t);
195        }
196
197        static
198        BOOST_UBLAS_INLINE
199        real_type type_abs (const_reference t) {
200                return abs (t);
201        }
202        static
203        BOOST_UBLAS_INLINE
204        value_type type_sqrt (const_reference t) {
205                return sqrt (t);
206        }
207
208        static
209        BOOST_UBLAS_INLINE
210        real_type norm_1 (const_reference t) {
211            return type_traits<real_type>::type_abs (self_type::real (t)) +
212                   type_traits<real_type>::type_abs (self_type::imag (t));
213        }
214        static
215        BOOST_UBLAS_INLINE
216        real_type norm_2 (const_reference t) {
217            return self_type::type_abs (t);
218        }
219        static
220        BOOST_UBLAS_INLINE
221        real_type norm_inf (const_reference t) {
222            return (std::max) (type_traits<real_type>::type_abs (self_type::real (t)),
223                             type_traits<real_type>::type_abs (self_type::imag (t)));
224        }
225
226        static
227        BOOST_UBLAS_INLINE
228        bool equals (const_reference t1, const_reference t2) {
229            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
230                   (std::max) ((std::max) (self_type::norm_inf (t1),
231                                       self_type::norm_inf (t2)),
232                             BOOST_UBLAS_TYPE_CHECK_MIN);
233        }
234    };
235   
236    // Define complex type traits
237    template<>
238    struct type_traits<std::complex<float> > : complex_traits<std::complex<float> >{
239        typedef type_traits<std::complex<float> > self_type;
240        typedef std::complex<float> value_type;
241        typedef const value_type &const_reference;
242        typedef value_type &reference;
243        typedef float real_type;
244        typedef std::complex<double> precision_type;
245
246    };
247    template<>
248    struct type_traits<std::complex<double> > : complex_traits<std::complex<double> >{
249        typedef type_traits<std::complex<double> > self_type;
250        typedef std::complex<double> value_type;
251        typedef const value_type &const_reference;
252        typedef value_type &reference;
253        typedef double real_type;
254        typedef std::complex<long double> precision_type;
255    };
256    template<>
257    struct type_traits<std::complex<long double> > : complex_traits<std::complex<long double> > {
258        typedef type_traits<std::complex<long double> > self_type;
259        typedef std::complex<long double> value_type;
260        typedef const value_type &const_reference;
261        typedef value_type &reference;
262        typedef long double real_type;
263        typedef value_type precision_type;
264    };
265
266#ifdef BOOST_UBLAS_USE_INTERVAL
267    // Define properties for a generic scalar interval type
268    template<class T>
269    struct scalar_interval_type_traits : scalar_type_traits<T> {
270        typedef scalar_interval_type_traits<T> self_type;
271        typedef boost::numeric::interval<float> value_type;
272        typedef const value_type &const_reference;
273        typedef value_type &reference;
274        typedef value_type real_type;
275        typedef real_type precision_type;       // we do not know what type has more precision then the real_type
276
277        static const unsigned plus_complexity = 1;
278        static const unsigned multiplies_complexity = 1;
279
280        static
281        BOOST_UBLAS_INLINE
282        real_type type_abs (const_reference t) {
283            return abs (t);
284        }
285        static
286        BOOST_UBLAS_INLINE
287        value_type type_sqrt (const_reference t) {
288            return sqrt (t);
289        }
290
291        static
292        BOOST_UBLAS_INLINE
293        real_type norm_1 (const_reference t) {
294            return self_type::type_abs (t);
295        }
296        static
297        BOOST_UBLAS_INLINE
298        real_type norm_2 (const_reference t) {
299            return self_type::type_abs (t);
300        }
301        static
302        BOOST_UBLAS_INLINE
303        real_type norm_inf (const_reference t) {
304            return self_type::type_abs (t);
305        }
306
307        static
308        BOOST_UBLAS_INLINE
309        bool equals (const_reference t1, const_reference t2) {
310            return self_type::norm_inf (t1 - t2) < BOOST_UBLAS_TYPE_CHECK_EPSILON *
311                   (std::max) ((std::max) (self_type::norm_inf (t1),
312                                       self_type::norm_inf (t2)),
313                             BOOST_UBLAS_TYPE_CHECK_MIN);
314        }
315    };
316
317    // Define scalar interval type traits
318    template<>
319    struct type_traits<boost::numeric::interval<float> > : scalar_interval_type_traits<boost::numeric::interval<float> > {
320        typedef type_traits<boost::numeric::interval<float> > self_type;
321        typedef boost::numeric::interval<float> value_type;
322        typedef const value_type &const_reference;
323        typedef value_type &reference;
324        typedef value_type real_type;
325        typedef boost::numeric::interval<double> precision_type;
326
327    };
328    template<>
329    struct type_traits<boost::numeric::interval<double> > : scalar_interval_type_traits<boost::numeric::interval<double> > {
330        typedef type_traits<boost::numeric::interval<double> > self_type;
331        typedef boost::numeric::interval<double> value_type;
332        typedef const value_type &const_reference;
333        typedef value_type &reference;
334        typedef value_type real_type;
335        typedef boost::numeric::interval<long double> precision_type;
336    };
337    template<>
338    struct type_traits<boost::numeric::interval<long double> > : scalar_interval_type_traits<boost::numeric::interval<long double> > {
339        typedef type_traits<boost::numeric::interval<long double> > self_type;
340        typedef boost::numeric::interval<long double> value_type;
341        typedef const value_type &const_reference;
342        typedef value_type &reference;
343        typedef value_type real_type;
344        typedef value_type precision_type;
345    };
346
347#endif
348
349
350    // Storage tags -- hierarchical definition of storage characteristics
351
352    struct unknown_storage_tag {};
353    struct sparse_proxy_tag: public unknown_storage_tag {};
354    struct sparse_tag: public sparse_proxy_tag {};
355    struct packed_proxy_tag: public sparse_proxy_tag {};
356    struct packed_tag: public packed_proxy_tag {};
357    struct dense_proxy_tag: public packed_proxy_tag {};
358    struct dense_tag: public dense_proxy_tag {};
359
360    template<class S1, class S2>
361    struct storage_restrict_traits {
362        typedef S1 storage_category;
363    };
364
365    template<>
366    struct storage_restrict_traits<sparse_tag, dense_proxy_tag> {
367        typedef sparse_proxy_tag storage_category;
368    };
369    template<>
370    struct storage_restrict_traits<sparse_tag, packed_proxy_tag> {
371        typedef sparse_proxy_tag storage_category;
372    };
373    template<>
374    struct storage_restrict_traits<sparse_tag, sparse_proxy_tag> {
375        typedef sparse_proxy_tag storage_category;
376    };
377
378    template<>
379    struct storage_restrict_traits<packed_tag, dense_proxy_tag> {
380        typedef packed_proxy_tag storage_category;
381    };
382    template<>
383    struct storage_restrict_traits<packed_tag, packed_proxy_tag> {
384        typedef packed_proxy_tag storage_category;
385    };
386    template<>
387    struct storage_restrict_traits<packed_tag, sparse_proxy_tag> {
388        typedef sparse_proxy_tag storage_category;
389    };
390
391    template<>
392    struct storage_restrict_traits<packed_proxy_tag, sparse_proxy_tag> {
393        typedef sparse_proxy_tag storage_category;
394    };
395
396    template<>
397    struct storage_restrict_traits<dense_tag, dense_proxy_tag> {
398        typedef dense_proxy_tag storage_category;
399    };
400    template<>
401    struct storage_restrict_traits<dense_tag, packed_proxy_tag> {
402        typedef packed_proxy_tag storage_category;
403    };
404    template<>
405    struct storage_restrict_traits<dense_tag, sparse_proxy_tag> {
406        typedef sparse_proxy_tag storage_category;
407    };
408
409    template<>
410    struct storage_restrict_traits<dense_proxy_tag, packed_proxy_tag> {
411        typedef packed_proxy_tag storage_category;
412    };
413    template<>
414    struct storage_restrict_traits<dense_proxy_tag, sparse_proxy_tag> {
415        typedef sparse_proxy_tag storage_category;
416    };
417
418
419    // Iterator tags -- hierarchical definition of storage characteristics
420
421    struct sparse_bidirectional_iterator_tag : public std::bidirectional_iterator_tag {};
422    struct packed_random_access_iterator_tag : public std::random_access_iterator_tag {};
423    struct dense_random_access_iterator_tag : public packed_random_access_iterator_tag {};
424
425    // Thanks to Kresimir Fresl for convincing Comeau with iterator_base_traits ;-)
426    template<class IC>
427    struct iterator_base_traits {};
428
429    template<>
430    struct iterator_base_traits<std::forward_iterator_tag> {
431        template<class I, class T>
432        struct iterator_base {
433            typedef forward_iterator_base<std::forward_iterator_tag, I, T> type;
434        };
435    };
436
437    template<>
438    struct iterator_base_traits<std::bidirectional_iterator_tag> {
439        template<class I, class T>
440        struct iterator_base {
441            typedef bidirectional_iterator_base<std::bidirectional_iterator_tag, I, T> type;
442        };
443    };
444    template<>
445    struct iterator_base_traits<sparse_bidirectional_iterator_tag> {
446        template<class I, class T>
447        struct iterator_base {
448            typedef bidirectional_iterator_base<sparse_bidirectional_iterator_tag, I, T> type;
449        };
450    };
451
452    template<>
453    struct iterator_base_traits<std::random_access_iterator_tag> {
454        template<class I, class T>
455        struct iterator_base {
456            typedef random_access_iterator_base<std::random_access_iterator_tag, I, T> type;
457        };
458    };
459    template<>
460    struct iterator_base_traits<packed_random_access_iterator_tag> {
461        template<class I, class T>
462        struct iterator_base {
463            typedef random_access_iterator_base<packed_random_access_iterator_tag, I, T> type;
464        };
465    };
466    template<>
467    struct iterator_base_traits<dense_random_access_iterator_tag> {
468        template<class I, class T>
469        struct iterator_base {
470            typedef random_access_iterator_base<dense_random_access_iterator_tag, I, T> type;
471        };
472    };
473
474    template<class I1, class I2>
475    struct iterator_restrict_traits {
476        typedef I1 iterator_category;
477    };
478
479    template<>
480    struct iterator_restrict_traits<packed_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
481        typedef sparse_bidirectional_iterator_tag iterator_category;
482    };
483    template<>
484    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, packed_random_access_iterator_tag> {
485        typedef sparse_bidirectional_iterator_tag iterator_category;
486    };
487
488    template<>
489    struct iterator_restrict_traits<dense_random_access_iterator_tag, sparse_bidirectional_iterator_tag> {
490        typedef sparse_bidirectional_iterator_tag iterator_category;
491    };
492    template<>
493    struct iterator_restrict_traits<sparse_bidirectional_iterator_tag, dense_random_access_iterator_tag> {
494        typedef sparse_bidirectional_iterator_tag iterator_category;
495    };
496
497    template<>
498    struct iterator_restrict_traits<dense_random_access_iterator_tag, packed_random_access_iterator_tag> {
499        typedef packed_random_access_iterator_tag iterator_category;
500    };
501    template<>
502    struct iterator_restrict_traits<packed_random_access_iterator_tag, dense_random_access_iterator_tag> {
503        typedef packed_random_access_iterator_tag iterator_category;
504    };
505
506    template<class I>
507    BOOST_UBLAS_INLINE
508    void increment (I &it, const I &it_end, typename I::difference_type compare, packed_random_access_iterator_tag) {
509        it += (std::min) (compare, it_end - it);
510    }
511    template<class I>
512    BOOST_UBLAS_INLINE
513    void increment (I &it, const I &/* it_end */, typename I::difference_type /* compare */, sparse_bidirectional_iterator_tag) {
514        ++ it;
515    }
516    template<class I>
517    BOOST_UBLAS_INLINE
518    void increment (I &it, const I &it_end, typename I::difference_type compare) {
519        increment (it, it_end, compare, typename I::iterator_category ());
520    }
521
522    template<class I>
523    BOOST_UBLAS_INLINE
524    void increment (I &it, const I &it_end) {
525#if BOOST_UBLAS_TYPE_CHECK
526        I cit (it);
527        while (cit != it_end) {
528            BOOST_UBLAS_CHECK (*cit == typename I::value_type/*zero*/(), internal_logic ());
529            ++ cit;
530        }
531#endif
532        it = it_end;
533    }
534
535}}}
536
537#endif
Note: See TracBrowser for help on using the repository browser.