Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms

concepts.hpp

Go to the documentation of this file.
00001 //
00002 //  Copyright (c) 2000-2002
00003 //  Joerg Walter, Mathias Koch
00004 //
00005 //  Distributed under the Boost Software License, Version 1.0. (See
00006 //  accompanying file LICENSE_1_0.txt or copy at
00007 //  http://www.boost.org/LICENSE_1_0.txt)
00008 //
00009 //  The authors gratefully acknowledge the support of
00010 //  GeNeSys mbH & Co. KG in producing this work.
00011 //
00012 
00013 #ifndef _BOOST_UBLAS_CONCEPTS_
00014 #define _BOOST_UBLAS_CONCEPTS_
00015 
00016 #include <boost/concept_check.hpp>
00017 
00018 // Concept checks based on ideas of Jeremy Siek
00019 
00020 namespace boost { namespace numeric { namespace ublas {
00021 
00022 
00023     template<class I>
00024     struct Indexed1DIteratorConcept {
00025         typedef I iterator_type;
00026 
00027         void constraints () {
00028             iterator_type it = iterator_type ();
00029             // Index
00030             it.index ();
00031         }
00032     };
00033 
00034     template<class I>
00035     struct IndexedBidirectional1DIteratorConcept {
00036         typedef I iterator_type;
00037 
00038         void constraints () {
00039             function_requires< BidirectionalIteratorConcept<iterator_type> >();
00040             function_requires< Indexed1DIteratorConcept<iterator_type> >();
00041         }
00042     };
00043 
00044     template<class I>
00045     struct Mutable_IndexedBidirectional1DIteratorConcept {
00046         typedef I iterator_type;
00047 
00048         void constraints () {
00049             function_requires< Mutable_BidirectionalIteratorConcept<iterator_type> >();
00050             function_requires< Indexed1DIteratorConcept<iterator_type> >();
00051         }
00052     };
00053 
00054     template<class I>
00055     struct IndexedRandomAccess1DIteratorConcept {
00056         typedef I iterator_type;
00057 
00058         void constraints () {
00059             function_requires< RandomAccessIteratorConcept<iterator_type> >();
00060             function_requires< Indexed1DIteratorConcept<iterator_type> >();
00061         }
00062     };
00063 
00064     template<class I>
00065     struct Mutable_IndexedRandomAccess1DIteratorConcept {
00066         typedef I iterator_type;
00067 
00068         void constraints () {
00069             function_requires< Mutable_RandomAccessIteratorConcept<iterator_type> >();
00070             function_requires< Indexed1DIteratorConcept<iterator_type> >();
00071         }
00072     };
00073 
00074     template<class I>
00075     struct Indexed2DIteratorConcept {
00076         typedef I iterator_type;
00077         typedef typename I::dual_iterator_type dual_iterator_type;
00078         typedef typename I::dual_reverse_iterator_type dual_reverse_iterator_type;
00079 
00080         void constraints () {
00081             iterator_type it = iterator_type ();
00082             // Indices
00083             it.index1 ();
00084             it.index2 ();
00085             // Iterator begin/end
00086             dual_iterator_type it_begin (it.begin ());
00087             dual_iterator_type it_end (it.end ());
00088             // Reverse iterator begin/end
00089             dual_reverse_iterator_type it_rbegin (it.rbegin ());
00090             dual_reverse_iterator_type it_rend (it.rend ());
00091             ignore_unused_variable_warning (it_begin);
00092             ignore_unused_variable_warning (it_end);
00093             ignore_unused_variable_warning (it_rbegin);
00094             ignore_unused_variable_warning (it_rend);
00095         }
00096     };
00097 
00098     template<class I1, class I2>
00099     struct IndexedBidirectional2DIteratorConcept {
00100         typedef I1 subiterator1_type;
00101         typedef I2 subiterator2_type;
00102 
00103         void constraints () {
00104             function_requires< BidirectionalIteratorConcept<subiterator1_type> >();
00105             function_requires< BidirectionalIteratorConcept<subiterator2_type> >();
00106             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
00107             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
00108         }
00109     };
00110 
00111     template<class I1, class I2>
00112     struct Mutable_IndexedBidirectional2DIteratorConcept {
00113         typedef I1 subiterator1_type;
00114         typedef I2 subiterator2_type;
00115 
00116         void constraints () {
00117             function_requires< Mutable_BidirectionalIteratorConcept<subiterator1_type> >();
00118             function_requires< Mutable_BidirectionalIteratorConcept<subiterator2_type> >();
00119             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
00120             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
00121         }
00122     };
00123 
00124     template<class I1, class I2>
00125     struct IndexedRandomAccess2DIteratorConcept {
00126         typedef I1 subiterator1_type;
00127         typedef I2 subiterator2_type;
00128 
00129         void constraints () {
00130             function_requires< RandomAccessIteratorConcept<subiterator1_type> >();
00131             function_requires< RandomAccessIteratorConcept<subiterator2_type> >();
00132             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
00133             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
00134         }
00135     };
00136 
00137     template<class I1, class I2>
00138     struct Mutable_IndexedRandomAccess2DIteratorConcept {
00139         typedef I1 subiterator1_type;
00140         typedef I2 subiterator2_type;
00141 
00142         void constraints () {
00143             function_requires< Mutable_RandomAccessIteratorConcept<subiterator1_type> >();
00144             function_requires< Mutable_RandomAccessIteratorConcept<subiterator2_type> >();
00145             function_requires< Indexed2DIteratorConcept<subiterator1_type> >();
00146             function_requires< Indexed2DIteratorConcept<subiterator2_type> >();
00147         }
00148     };
00149 
00150     template<class C>
00151     struct StorageArrayConcept {
00152         typedef C container_type;
00153         typedef typename C::size_type size_type;
00154         typedef typename C::value_type value_type;
00155 
00156         void constraints () {
00157             function_requires< RandomAccessContainerConcept<container_type> >();
00158             size_type n (0);
00159             // Sizing constructor
00160             container_type c = container_type (n);
00161             // Initialised sizing constructor
00162             container_type (n, value_type (5));
00163             ignore_unused_variable_warning (c);
00164         }
00165     };
00166 
00167     template<class C>
00168     struct Mutable_StorageArrayConcept {
00169         typedef C container_type;
00170         typedef typename C::size_type size_type;
00171         typedef typename C::value_type value_type;
00172         typedef typename C::iterator iterator_type;
00173 
00174         void constraints () {
00175             function_requires< Mutable_RandomAccessContainerConcept<container_type> > ();
00176             size_type n (0);
00177             // Sizing constructor
00178             container_type c = container_type (n);
00179             // Initialised sizing constructor
00180             c = container_type (n, value_type (3));
00181             // Resize
00182             c.resize (n, value_type (5));
00183             // Resize - none preserving
00184             c.resize (n);
00185         }
00186     };
00187 
00188     template<class C>
00189     struct StorageSparseConcept {
00190         typedef C container_type;
00191         typedef typename C::size_type size_type;
00192 
00193         void constraints () {
00194             function_requires< ReversibleContainerConcept<container_type> > ();
00195         }
00196     };
00197 
00198     template<class C>
00199     struct Mutable_StorageSparseConcept {
00200         typedef C container_type;
00201         typedef typename C::size_type size_type;
00202         typedef typename C::value_type value_type;
00203         typedef typename C::iterator iterator_type;
00204 
00205         void constraints () {
00206             // NOTE - Not Mutable_ReversibleContainerConcept
00207             function_requires< ReversibleContainerConcept<container_type> >();
00208             container_type c = container_type ();
00209             value_type t = value_type ();
00210             iterator_type it = iterator_type (), it1 = iterator_type (), it2 = iterator_type ();
00211             // Insert
00212             c.insert (it, t);
00213             // Erase
00214             c.erase (it);
00215             // Range erase
00216             c.erase (it1, it2);
00217             // Clear
00218             c.clear ();
00219         }
00220     };
00221 
00222     template<class G>
00223     struct IndexSetConcept {
00224         typedef G generator_type;
00225         typedef typename G::size_type size_type;
00226         typedef typename G::value_type value_type;
00227 
00228         void constraints () {
00229             function_requires< AssignableConcept<generator_type> >();
00230             function_requires< ReversibleContainerConcept<generator_type> >();
00231             generator_type g = generator_type ();
00232             size_type n (0);
00233             value_type t;
00234             // Element access
00235             t = g (n);
00236             ignore_unused_variable_warning (t);
00237         }
00238     };
00239 
00249     template<class SE>
00250     struct ScalarExpressionConcept {
00251         typedef SE scalar_expression_type;
00252         typedef typename SE::value_type value_type;
00253 
00254         static const unsigned complexity = SE::complexity;
00255 
00256         void constraints () {
00257             scalar_expression_type *sp;
00258             scalar_expression_type s = *sp;
00259             value_type t;
00260             // Conversion
00261             t = s;
00262             ignore_unused_variable_warning (t);
00263         }
00264     };
00265 
00280     template<class VE>
00281     struct VectorExpressionConcept {
00282         typedef VE vector_expression_type;
00283         typedef typename VE::type_category type_category;
00284         typedef typename VE::size_type size_type;
00285         typedef typename VE::difference_type difference_type;
00286         typedef typename VE::value_type value_type;
00287         typedef typename VE::const_reference const_reference;
00288         typedef typename VE::const_iterator const_iterator_type;
00289         typedef typename VE::const_reverse_iterator const_reverse_iterator_type;
00290 
00291         void constraints () {
00292             vector_expression_type *vp;
00293             const vector_expression_type *cvp;
00294             vector_expression_type v = *vp;
00295             const vector_expression_type cv = *cvp;
00296             size_type n (0), i (0);
00297             value_type t;
00298             // Find (internal?)
00299             const_iterator_type cit (v.find (i));
00300             // Beginning of range
00301             const_iterator_type cit_begin (v.begin ());
00302             // End of range
00303             const_iterator_type cit_end (v.end ());
00304             // Size
00305             n = v.size ();
00306             // Beginning of reverse range
00307             const_reverse_iterator_type crit_begin (cv.rbegin ());
00308             // End of reverse range
00309             const_reverse_iterator_type crit_end (cv.rend ());
00310             // Element access
00311             t = v (i);
00312             ignore_unused_variable_warning (n);
00313             ignore_unused_variable_warning (cit);
00314             ignore_unused_variable_warning (cit_begin);
00315             ignore_unused_variable_warning (cit_end);
00316             ignore_unused_variable_warning (crit_begin);
00317             ignore_unused_variable_warning (crit_end);
00318             ignore_unused_variable_warning (t);
00319         }
00320     };
00321 
00322     template<class VE>
00323     struct Mutable_VectorExpressionConcept {
00324         typedef VE vector_expression_type;
00325         typedef typename VE::size_type size_type;
00326         typedef typename VE::value_type value_type;
00327         typedef typename VE::iterator iterator_type;
00328         typedef typename VE::reverse_iterator reverse_iterator_type;
00329 
00330         void constraints () {
00331             function_requires< AssignableConcept<vector_expression_type> >();
00332             function_requires< VectorExpressionConcept<vector_expression_type> >();
00333             vector_expression_type *vp;
00334             vector_expression_type v = *vp, v1 = *vp, v2 = *vp;
00335             size_type i (0);
00336             value_type t = value_type ();
00337             // Find (internal?)
00338             iterator_type it (v.find (i));
00339             // Beginning of range
00340             iterator_type it_begin (v.begin ());
00341             // End of range
00342             iterator_type it_end (v.end ());
00343             // Swap
00344             v1.swap (v2);
00345             // Beginning of reverse range
00346             reverse_iterator_type rit_begin (v.rbegin ());
00347             // End of reverse range
00348             reverse_iterator_type rit_end (v.rend ());
00349             // Assignments
00350             v2 = v1;
00351             v2.assign (v1);
00352             v2 += v1;
00353             v2.plus_assign (v1);
00354             v2 -= v1;
00355             v2.minus_assign (v1);
00356             v *= t;
00357             ignore_unused_variable_warning (it);
00358             ignore_unused_variable_warning (it_begin);
00359             ignore_unused_variable_warning (it_end);
00360             ignore_unused_variable_warning (rit_begin);
00361             ignore_unused_variable_warning (rit_end);
00362         }
00363     };
00364 
00365     template<class ME>
00366     struct MatrixExpressionConcept {
00367         typedef ME matrix_expression_type;
00368         typedef typename ME::type_category type_category;
00369         typedef typename ME::size_type size_type;
00370         typedef typename ME::value_type value_type;
00371         typedef typename ME::const_iterator1 const_subiterator1_type;
00372         typedef typename ME::const_iterator2 const_subiterator2_type;
00373         typedef typename ME::const_reverse_iterator1 const_reverse_subiterator1_type;
00374         typedef typename ME::const_reverse_iterator2 const_reverse_subiterator2_type;
00375 
00376         void constraints () {
00377             matrix_expression_type *mp;
00378             const matrix_expression_type *cmp;
00379             matrix_expression_type m = *mp;
00380             const matrix_expression_type cm = *cmp;
00381             size_type n (0), i (0), j (0);
00382             value_type t;
00383             // Find (internal?)
00384             const_subiterator1_type cit1 (m.find1 (0, i, j));
00385             const_subiterator2_type cit2 (m.find2 (0, i, j));
00386             // Beginning of range
00387             const_subiterator1_type cit1_begin (m.begin1 ());
00388             const_subiterator2_type cit2_begin (m.begin2 ());
00389             // End of range
00390             const_subiterator1_type cit1_end (m.end1 ());
00391             const_subiterator2_type cit2_end (m.end2 ());
00392             // Size
00393             n = m.size1 ();
00394             n = m.size2 ();
00395             // Beginning of reverse range
00396             const_reverse_subiterator1_type crit1_begin (cm.rbegin1 ());
00397             const_reverse_subiterator2_type crit2_begin (cm.rbegin2 ());
00398             // End of reverse range
00399             const_reverse_subiterator1_type crit1_end (cm.rend1 ());
00400             const_reverse_subiterator2_type crit2_end (cm.rend2 ());
00401             // Element access
00402             t = m (i, j);
00403             ignore_unused_variable_warning (n);
00404             ignore_unused_variable_warning (cit1);
00405             ignore_unused_variable_warning (cit2);
00406             ignore_unused_variable_warning (cit1_begin);
00407             ignore_unused_variable_warning (cit2_begin);
00408             ignore_unused_variable_warning (cit1_end);
00409             ignore_unused_variable_warning (cit2_end);
00410             ignore_unused_variable_warning (crit1_begin);
00411             ignore_unused_variable_warning (crit2_begin);
00412             ignore_unused_variable_warning (crit1_end);
00413             ignore_unused_variable_warning (crit2_end);
00414             ignore_unused_variable_warning (t);
00415         }
00416     };
00417 
00418     template<class ME>
00419     struct Mutable_MatrixExpressionConcept {
00420         typedef ME matrix_expression_type;
00421         typedef typename ME::size_type size_type;
00422         typedef typename ME::value_type value_type;
00423         typedef typename ME::iterator1 subiterator1_type;
00424         typedef typename ME::iterator2 subiterator2_type;
00425         typedef typename ME::reverse_iterator1 reverse_subiterator1_type;
00426         typedef typename ME::reverse_iterator2 reverse_subiterator2_type;
00427 
00428         void constraints () {
00429             function_requires< AssignableConcept<matrix_expression_type> >();
00430             function_requires< MatrixExpressionConcept<matrix_expression_type> >();
00431             matrix_expression_type *mp;
00432             matrix_expression_type m = *mp, m1 = *mp, m2 = *mp;
00433             size_type i (0), j (0);
00434             value_type t = value_type ();
00435             // Find (internal?)
00436             subiterator1_type it1 (m.find1 (0, i, j));
00437             subiterator2_type it2 (m.find2 (0, i, j));
00438             // Beginning of range
00439             subiterator1_type it1_begin (m.begin1 ());
00440             subiterator2_type it2_begin (m.begin2 ());
00441             // End of range
00442             subiterator1_type it1_end (m.end1 ());
00443             subiterator2_type it2_end (m.end2 ());
00444             // Swap
00445             m1.swap (m2);
00446             // Beginning of reverse range
00447             reverse_subiterator1_type rit1_begin (m.rbegin1 ());
00448             reverse_subiterator2_type rit2_begin (m.rbegin2 ());
00449             // End of reverse range
00450             reverse_subiterator1_type rit1_end (m.rend1 ());
00451             reverse_subiterator2_type rit2_end (m.rend2 ());
00452             // Assignments
00453             m2 = m1;
00454             m2.assign (m1);
00455             m2 += m1;
00456             m2.plus_assign (m1);
00457             m2 -= m1;
00458             m2.minus_assign (m1);
00459             m *= t;
00460             ignore_unused_variable_warning (it1);
00461             ignore_unused_variable_warning (it2);
00462             ignore_unused_variable_warning (it1_begin);
00463             ignore_unused_variable_warning (it2_begin);
00464             ignore_unused_variable_warning (it1_end);
00465             ignore_unused_variable_warning (it2_end);
00466             ignore_unused_variable_warning (rit1_begin);
00467             ignore_unused_variable_warning (rit2_begin);
00468             ignore_unused_variable_warning (rit1_end);
00469             ignore_unused_variable_warning (rit2_end);
00470         }
00471     };
00472 
00473     template<class V>
00474     struct VectorConcept {
00475         typedef V vector_type;
00476         typedef typename V::size_type size_type;
00477         typedef typename V::value_type value_type;
00478         typedef const value_type *const_pointer;
00479 
00480         void constraints () {
00481             function_requires< VectorExpressionConcept<vector_type> >();
00482             size_type n (0);
00483             size_type i (0);
00484             // Sizing constructor
00485             vector_type v (n);
00486             // Element support
00487             const_pointer p = v.find_element (i);
00488 
00489             ignore_unused_variable_warning (p);
00490         }
00491     };
00492 
00493     template<class V>
00494     struct Mutable_VectorConcept {
00495         typedef V vector_type;
00496         typedef typename V::size_type size_type;
00497         typedef typename V::value_type value_type;
00498         typedef value_type *pointer;
00499 
00500         void constraints () {
00501             function_requires< VectorConcept<vector_type> >();
00502             function_requires< DefaultConstructible<vector_type> >();
00503             function_requires< Mutable_VectorExpressionConcept<vector_type> >();
00504             size_type n (0);
00505             value_type t = value_type ();
00506             size_type i (0);
00507             vector_type v;
00508             // Element support
00509             pointer p = v.find_element (i);
00510             // Element assignment
00511             value_type r = v.insert_element (i, t);
00512             v.insert_element (i, t) = r;
00513             // Zeroing
00514             v.clear ();
00515             // Resize
00516             v.resize (n);
00517 
00518             ignore_unused_variable_warning (p);
00519             ignore_unused_variable_warning (r);
00520         }
00521     };
00522 
00523     template<class V>
00524     struct SparseVectorConcept {
00525         typedef V vector_type;
00526         typedef typename V::size_type size_type;
00527 
00528         void constraints () {
00529             function_requires< VectorConcept<vector_type> >();
00530         }
00531     };
00532 
00533     template<class V>
00534     struct Mutable_SparseVectorConcept {
00535         typedef V vector_type;
00536         typedef typename V::size_type size_type;
00537         typedef typename V::value_type value_type;
00538 
00539         void constraints () {
00540             function_requires< SparseVectorConcept<vector_type> >();
00541             function_requires< Mutable_VectorConcept<vector_type> >();
00542             size_type i (0);
00543             vector_type v;
00544             // Element erasure
00545             v.erase_element (i);
00546         }
00547     };
00548 
00549     template<class M>
00550     struct MatrixConcept {
00551         typedef M matrix_type;
00552         typedef typename M::size_type size_type;
00553         typedef typename M::value_type value_type;
00554         typedef const value_type *const_pointer;
00555 
00556         void constraints () {
00557             function_requires< MatrixExpressionConcept<matrix_type> >();
00558             size_type n (0);
00559             size_type i (0), j (0);
00560             // Sizing constructor
00561             matrix_type m (n, n);
00562             // Element support
00563 #ifndef SKIP_BAD
00564             const_pointer p = m.find_element (i, j);
00565 #else
00566             const_pointer p;
00567             ignore_unused_variable_warning (i);
00568             ignore_unused_variable_warning (j);
00569 #endif
00570             ignore_unused_variable_warning (p);
00571         }
00572     };
00573 
00574     template<class M>
00575     struct Mutable_MatrixConcept {
00576         typedef M matrix_type;
00577         typedef typename M::size_type size_type;
00578         typedef typename M::value_type value_type;
00579         typedef value_type *pointer;
00580 
00581         void constraints () {
00582             function_requires< MatrixConcept<matrix_type> >();
00583             function_requires< DefaultConstructible<matrix_type> >();
00584             function_requires< Mutable_MatrixExpressionConcept<matrix_type> >();
00585             size_type n (0);
00586             value_type t = value_type ();
00587             size_type i (0), j (0);
00588             matrix_type m;
00589             // Element support
00590 #ifndef SKIP_BAD
00591             pointer p = m.find_element (i, j);
00592             ignore_unused_variable_warning (i);
00593             ignore_unused_variable_warning (j);
00594 #else
00595             pointer p;
00596 #endif
00597             // Element assigment
00598             value_type r = m.insert_element (i, j, t);
00599             m.insert_element (i, j, t) = r;
00600             // Zeroing
00601             m.clear ();
00602             // Resize
00603             m.resize (n, n);
00604             m.resize (n, n, false);
00605 
00606             ignore_unused_variable_warning (p);
00607             ignore_unused_variable_warning (r);
00608         }
00609     };
00610 
00611     template<class M>
00612     struct SparseMatrixConcept {
00613         typedef M matrix_type;
00614         typedef typename M::size_type size_type;
00615 
00616         void constraints () {
00617             function_requires< MatrixConcept<matrix_type> >();
00618         }
00619     };
00620 
00621     template<class M>
00622     struct Mutable_SparseMatrixConcept {
00623         typedef M matrix_type;
00624         typedef typename M::size_type size_type;
00625         typedef typename M::value_type value_type;
00626 
00627         void constraints () {
00628             function_requires< SparseMatrixConcept<matrix_type> >();
00629             function_requires< Mutable_MatrixConcept<matrix_type> >();
00630             size_type i (0), j (0);
00631             matrix_type m;
00632             // Elemnent erasure
00633             m.erase_element (i, j);
00634         }
00635     };
00636 
00640     namespace {
00641 
00642     template<class T>
00643     T
00644     ZeroElement (T);
00645     template<>
00646     float
00647     ZeroElement (float) {
00648         return 0.f;
00649     }
00650     template<>
00651     double
00652     ZeroElement (double) {
00653         return 0.;
00654     }
00655     template<>
00656     vector<float>
00657     ZeroElement (vector<float>) {
00658         return zero_vector<float> ();
00659     }
00660     template<>
00661     vector<double>
00662     ZeroElement (vector<double>) {
00663         return zero_vector<double> ();
00664     }
00665     template<>
00666     matrix<float>
00667     ZeroElement (matrix<float>) {
00668         return zero_matrix<float> ();
00669     }
00670     template<>
00671     matrix<double>
00672     ZeroElement (matrix<double>) {
00673         return zero_matrix<double> ();
00674     }
00675     template<>
00676     std::complex<float>
00677     ZeroElement (std::complex<float>) {
00678         return std::complex<float> (0.f);
00679     }
00680     template<>
00681     std::complex<double>
00682     ZeroElement (std::complex<double>) {
00683         return std::complex<double> (0.);
00684     }
00685     template<>
00686     vector<std::complex<float> >
00687     ZeroElement (vector<std::complex<float> >) {
00688         return zero_vector<std::complex<float> > ();
00689     }
00690     template<>
00691     vector<std::complex<double> >
00692     ZeroElement (vector<std::complex<double> >) {
00693         return zero_vector<std::complex<double> > ();
00694     }
00695     template<>
00696     matrix<std::complex<float> >
00697     ZeroElement (matrix<std::complex<float> >) {
00698         return zero_matrix<std::complex<float> > ();
00699     }
00700     template<>
00701     matrix<std::complex<double> >
00702     ZeroElement (matrix<std::complex<double> >) {
00703         return zero_matrix<std::complex<double> > ();
00704     }
00705 
00706     template<class T>
00707     T
00708     OneElement (T);
00709     template<>
00710     float
00711     OneElement (float) {
00712         return 1.f;
00713     }
00714     template<>
00715     double
00716     OneElement (double) {
00717         return 1.;
00718     }
00719     template<>
00720     matrix<float>
00721     OneElement (matrix<float>) {
00722         return identity_matrix<float> ();
00723     }
00724     template<>
00725     matrix<double>
00726     OneElement (matrix<double>) {
00727         return identity_matrix<double> ();
00728     }
00729     template<>
00730     std::complex<float>
00731     OneElement (std::complex<float>) {
00732         return std::complex<float> (1.f);
00733     }
00734     template<>
00735     std::complex<double>
00736     OneElement (std::complex<double>) {
00737         return std::complex<double> (1.);
00738     }
00739     template<>
00740     matrix<std::complex<float> >
00741     OneElement (matrix<std::complex<float> >) {
00742         return identity_matrix<std::complex<float> > ();
00743     }
00744     template<>
00745     matrix<std::complex<double> >
00746     OneElement (matrix<std::complex<double> >) {
00747         return identity_matrix<std::complex<double> > ();
00748     }
00749 
00750     template<class E1, class E2>
00751     bool
00752     operator == (const vector_expression<E1> &e1, const vector_expression<E2> &e2) {
00753         typedef typename promote_traits<typename E1::value_type,
00754                                                     typename E2::value_type>::promote_type value_type;
00755         typedef typename type_traits<value_type>::real_type real_type;
00756         return norm_inf (e1 - e2) == real_type/*zero*/();
00757     }
00758     template<class E1, class E2>
00759     bool
00760     operator == (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
00761         typedef typename promote_traits<typename E1::value_type,
00762                                                     typename E2::value_type>::promote_type value_type;
00763         typedef typename type_traits<value_type>::real_type real_type;
00764         return norm_inf (e1 - e2) == real_type/*zero*/();
00765     }
00766 
00767     template<class T>
00768     struct AdditiveAbelianGroupConcept {
00769         typedef T value_type;
00770 
00771         void constraints () {
00772             bool r;
00773             value_type a = value_type (), b = value_type (), c = value_type ();
00774             r = (a + b) + c == a + (b + c);
00775             r = ZeroElement (value_type ()) + a == a;
00776             r = a + ZeroElement (value_type ()) == a;
00777             r = a + (- a) == ZeroElement (value_type ());
00778             r = (- a) + a == ZeroElement (value_type ());
00779             r = a + b == b + a;
00780             ignore_unused_variable_warning (r);
00781         }
00782     };
00783 
00784     template<class T>
00785     struct MultiplicativeAbelianGroupConcept {
00786         typedef T value_type;
00787 
00788         void constraints () {
00789             bool r;
00790             value_type a = value_type (), b = value_type (), c = value_type ();
00791             r = (a * b) * c == a * (b * c);
00792             r = OneElement (value_type ()) * a == a;
00793             r = a * OneElement (value_type ()) == a;
00794             r = a * (OneElement (value_type ()) / a) == a;
00795             r = (OneElement (value_type ()) / a) * a == a;
00796             r = a * b == b * a;
00797             ignore_unused_variable_warning (r);
00798         }
00799     };
00800 
00801     template<class T>
00802     struct RingWithIdentityConcept {
00803         typedef T value_type;
00804 
00805         void constraints () {
00806             function_requires< AdditiveAbelianGroupConcept<value_type> >();
00807             bool r;
00808             value_type a = value_type (), b = value_type (), c = value_type ();
00809             r = (a * b) * c == a * (b * c);
00810             r = (a + b) * c == a * c + b * c;
00811             r = OneElement (value_type ()) * a == a;
00812             r = a * OneElement (value_type ()) == a;
00813             ignore_unused_variable_warning (r);
00814         }
00815     };
00816 
00817     template<class T>
00818     struct Prod_RingWithIdentityConcept {
00819         typedef T value_type;
00820 
00821         void constraints () {
00822             function_requires< AdditiveAbelianGroupConcept<value_type> >();
00823             bool r;
00824             value_type a = value_type (), b = value_type (), c = value_type ();
00825             r = prod (T (prod (a, b)), c) == prod (a, T (prod (b, c)));
00826             r = prod (a + b, c) == prod (a, c) + prod (b, c);
00827             r = prod (OneElement (value_type ()), a) == a;
00828             r = prod (a, OneElement (value_type ())) == a;
00829             ignore_unused_variable_warning (r);
00830         }
00831     };
00832 
00833     template<class T>
00834     struct CommutativeRingWithIdentityConcept {
00835         typedef T value_type;
00836 
00837         void constraints () {
00838             function_requires< RingWithIdentityConcept<value_type> >();
00839             bool r;
00840             value_type a = value_type (), b = value_type ();
00841             r = a * b == b * a;
00842             ignore_unused_variable_warning (r);
00843         }
00844     };
00845 
00846     template<class T>
00847     struct FieldConcept {
00848         typedef T value_type;
00849 
00850         void constraints () {
00851             function_requires< CommutativeRingWithIdentityConcept<value_type> >();
00852             bool r;
00853             value_type a = value_type ();
00854             r = a == ZeroElement (value_type ()) || a * (OneElement (value_type ()) / a) == a;
00855             r = a == ZeroElement (value_type ()) || (OneElement (value_type ()) / a) * a == a;
00856             ignore_unused_variable_warning (r);
00857         }
00858     };
00859 
00860     template<class T, class V>
00861     struct VectorSpaceConcept {
00862         typedef T value_type;
00863         typedef V vector_type;
00864 
00865         void constraints () {
00866             function_requires< FieldConcept<value_type> >();
00867             function_requires< AdditiveAbelianGroupConcept<vector_type> >();
00868             bool r;
00869             value_type alpha = value_type (), beta = value_type ();
00870             vector_type a = vector_type (), b = vector_type ();
00871             r = alpha * (a + b) == alpha * a + alpha * b;
00872             r = (alpha + beta) * a == alpha * a + beta * a;
00873             r = (alpha * beta) * a == alpha * (beta * a);
00874             r = OneElement (value_type ()) * a == a;
00875             ignore_unused_variable_warning (r);
00876         }
00877     };
00878 
00879     template<class T, class V, class M>
00880     struct LinearOperatorConcept {
00881         typedef T value_type;
00882         typedef V vector_type;
00883         typedef M matrix_type;
00884 
00885         void constraints () {
00886             function_requires< VectorSpaceConcept<value_type, vector_type> >();
00887             bool r;
00888             value_type alpha = value_type (), beta = value_type ();
00889             vector_type a = vector_type (), b = vector_type ();
00890             matrix_type A = matrix_type ();
00891             r = prod (A, alpha * a + beta * b) == alpha * prod (A, a) + beta * prod (A, b);
00892             ignore_unused_variable_warning (r);
00893         }
00894     };
00895 
00896     void concept_checks () {
00897 
00898         // Allow tests to be group to keep down compiler storage requirement
00899 #ifdef INTERAL
00900 #define INTERNAL_STORAGE
00901 #define INTERNAL_VECTOR
00902 #define INTERNAL_MATRIX
00903 #define INTERNAL_SPECIAL
00904 #define INTERNAL_SPARSE
00905 #define INTERNAL_EXPRESSION
00906 #endif
00907 
00908         // TODO enable this for development
00909         // #define VIEW_CONCEPTS
00910 
00911         // Element value type for tests
00912         typedef float T;
00913 
00914         // Storage Array
00915 #if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_DENSE)
00916         {
00917             typedef std::vector<T> container_model;
00918             function_requires< Mutable_StorageArrayConcept<container_model> >();
00919             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
00920             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
00921         }
00922 
00923         {
00924             typedef bounded_array<T, 1> container_model;
00925             function_requires< Mutable_StorageArrayConcept<container_model> >();
00926             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
00927             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
00928         }
00929 
00930         {
00931             typedef unbounded_array<T> container_model;
00932             function_requires< Mutable_StorageArrayConcept<container_model> >();
00933             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
00934             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
00935         }
00936 
00937 /* FIXME array_adaptors are in progress
00938         {
00939             typedef array_adaptor<T> container_model;
00940             function_requires< Mutable_StorageArrayConcept<container_model> >();
00941             function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
00942             function_requires< Mutable_RandomAccessIteratorConcept<container_model::iterator> >();
00943         }
00944 */
00945 
00946         {
00947             typedef range container_model;
00948             function_requires< IndexSetConcept<range> >();
00949             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
00950         }
00951 
00952         {
00953             typedef slice container_model;
00954             function_requires< IndexSetConcept<range> >();
00955             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
00956         }
00957 
00958         {
00959             typedef indirect_array<> container_model;
00960             function_requires< IndexSetConcept<range> >();
00961             function_requires< RandomAccessIteratorConcept<range::const_iterator> >();
00962         }
00963 #endif
00964 
00965         // Storage Sparse
00966 #if defined (INTERNAL_STORAGE) || defined (INTERNAL_STORAGE_SPARSE)
00967         {
00968            typedef map_array<std::size_t, T> container_model;
00969            function_requires< Mutable_StorageSparseConcept<container_model> >();
00970            function_requires< RandomAccessIteratorConcept<container_model::const_iterator> >();
00971            function_requires< RandomAccessIteratorConcept<container_model::iterator> >();
00972         }
00973 
00974         {
00975            typedef std::map<std::size_t, T> container_model;
00976            function_requires< Mutable_StorageSparseConcept<container_model > >();
00977            function_requires< BidirectionalIteratorConcept<container_model::const_iterator> >();
00978            function_requires< BidirectionalIteratorConcept<container_model::iterator> >();
00979         }
00980 #endif
00981 
00982 #ifdef VIEW_CONCEPTS
00983         // read only vectors
00984         {
00985            typedef vector_view<T> container_model;
00986            function_requires< RandomAccessContainerConcept<container_model> >();
00987            function_requires< VectorConcept<container_model> >();
00988            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
00989            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
00990         }
00991 #endif
00992 
00993         // Vector
00994 #if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_DENSE)
00995         {
00996            typedef vector<T> container_model;
00997            function_requires< RandomAccessContainerConcept<container_model> >();
00998            function_requires< Mutable_VectorConcept<container_model> >();
00999            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01000            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01001            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01002            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01003         }
01004 
01005         {
01006            typedef zero_vector<T> container_model;
01007            function_requires< VectorConcept<container_model> >();
01008            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
01009            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
01010         }
01011 
01012         {
01013            typedef unit_vector<T> container_model;
01014            function_requires< VectorConcept<container_model> >();
01015            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
01016            function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
01017         }
01018 
01019         {
01020            typedef scalar_vector<T> container_model;
01021            function_requires< VectorConcept<container_model> >();
01022            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01023            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01024         }
01025 
01026         {
01027            typedef c_vector<T, 1> container_model;
01028            function_requires< Mutable_VectorConcept<container_model> >();
01029            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01030            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01031            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01032            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01033         }
01034 #endif
01035 
01036         // Vector Proxies
01037 #if defined (INTERNAL_VECTOR) || defined (INTERNAL_VECTOR_PROXY)
01038         {
01039            typedef vector_range<vector<T> > container_model;
01040            function_requires< Mutable_VectorExpressionConcept<container_model> >();
01041            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01042            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01043            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01044            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01045         }
01046 
01047         {
01048            typedef vector_slice<vector<T> > container_model;
01049            function_requires< Mutable_VectorExpressionConcept<container_model> >();
01050            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01051            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01052            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01053            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01054         }
01055 
01056         {
01057            typedef vector_indirect<vector<T> > container_model;
01058            function_requires< Mutable_VectorExpressionConcept<container_model> >();
01059            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01060            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01061            function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01062            function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01063         }
01064 #endif
01065 
01066         // Sparse Vector
01067 #if defined (INTERNAL_SPARSE) || defined (INTERNAL_VECTOR_SPARSE)
01068         {
01069             typedef mapped_vector<T> container_model;
01070             function_requires< Mutable_SparseVectorConcept<container_model> >();
01071             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
01072             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
01073             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
01074             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
01075         }
01076 
01077         {
01078             typedef compressed_vector<T> container_model;
01079             function_requires< Mutable_SparseVectorConcept<container_model> >();
01080             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
01081             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
01082             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
01083             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
01084         }
01085 
01086         {
01087             typedef coordinate_vector<T> container_model;
01088             function_requires< Mutable_SparseVectorConcept<container_model> >();
01089             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_iterator> >();
01090             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::iterator> >();
01091             function_requires< IndexedBidirectional1DIteratorConcept<container_model::const_reverse_iterator> >();
01092             function_requires< Mutable_IndexedBidirectional1DIteratorConcept<container_model::reverse_iterator> >();
01093         }
01094 #endif
01095 
01096         // Matrix
01097 #if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_DENSE)
01098         {
01099             typedef matrix<T> container_model;
01100             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01101             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01102             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01103             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01104             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01105         }
01106 
01107         {
01108             typedef vector_of_vector<T> container_model;
01109             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01110             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01111             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01112             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01113             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01114         }
01115 
01116         {
01117             typedef zero_matrix<T> container_model;
01118             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01119             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01120             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01121         }
01122 
01123         {
01124             typedef identity_matrix<T> container_model;
01125             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01126             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01127             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01128         }
01129 
01130         {
01131             typedef scalar_matrix<T> container_model;
01132             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01133             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01134             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01135         }
01136 
01137         {
01138             typedef c_matrix<T, 1, 1> container_model;
01139             function_requires< Mutable_MatrixConcept<matrix<T> > >();
01140             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01141             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01142             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01143             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01144         }
01145 #endif
01146 
01147         // Matrix Proxies
01148 #if defined (INTERNAL_MATRIX) || defined (INTERNAL_MATRIX_PROXY)
01149         {
01150             typedef matrix_row<matrix<T> > container_model;
01151             function_requires< Mutable_VectorExpressionConcept<container_model> >();
01152             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01153             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01154             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01155             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01156         }
01157 
01158         {
01159             typedef matrix_column<matrix<T> > container_model;
01160             function_requires< Mutable_VectorExpressionConcept<container_model> >();
01161             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01162             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01163             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01164             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01165         }
01166 
01167         {
01168             typedef matrix_vector_range<matrix<T> > container_model;
01169             function_requires< Mutable_VectorExpressionConcept<container_model> >();
01170             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01171             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01172             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01173             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01174         }
01175 
01176         {
01177             typedef matrix_vector_slice<matrix<T> > container_model;
01178             function_requires< Mutable_VectorExpressionConcept<container_model> >();
01179             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01180             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01181             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01182             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01183         }
01184 
01185         {
01186             typedef matrix_vector_indirect<matrix<T> > container_model;
01187             function_requires< Mutable_VectorExpressionConcept<container_model> >();
01188             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_iterator> >();
01189             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::iterator> >();
01190             function_requires< IndexedRandomAccess1DIteratorConcept<container_model::const_reverse_iterator> >();
01191             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<container_model::reverse_iterator> >();
01192         }
01193 
01194         {
01195             typedef matrix_range<matrix<T> > container_model;
01196             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01197             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01198             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01199             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01200             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01201         }
01202 
01203         {
01204             typedef matrix_slice<matrix<T> > container_model;
01205             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01206             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01207             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01208             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01209             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01210         }
01211 
01212         {
01213             typedef matrix_indirect<matrix<T> > container_model;
01214             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01215             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01216             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01217             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01218             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01219         }
01220 #endif
01221 
01222         // Banded Matrix
01223 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_BANDED)
01224         {
01225             typedef banded_matrix<T> container_model;
01226             function_requires< Mutable_MatrixConcept<container_model> >();
01227             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01228             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01229             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01230             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01231         }
01232 
01233         {
01234             typedef banded_adaptor<matrix<T> > container_model;
01235             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01236             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01237             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01238             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01239             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01240         }
01241 #endif
01242 
01243         // Triangular Matrix
01244 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_TRIANGULAR)
01245         {
01246             typedef triangular_matrix<T> container_model;
01247             function_requires< Mutable_MatrixConcept<container_model> >();
01248             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01249             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01250             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01251             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01252         }
01253 
01254         {
01255             typedef triangular_adaptor<matrix<T> > container_model;
01256             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01257             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01258             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01259             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01260             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01261         }
01262 #endif
01263 
01264         // Symmetric Matrix
01265 #if defined (INTERNA_SPECIAL) || defined (INTERNAL_SYMMETRIC)
01266         {
01267             typedef symmetric_matrix<T> container_model;
01268             function_requires< Mutable_MatrixConcept<container_model> >();
01269             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01270             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01271             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01272             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01273         }
01274 
01275         {
01276             typedef banded_adaptor<matrix<T> > container_model;
01277 #ifndef SKIP_BAD
01278            // const_iterator (iterator) constructor is bad
01279             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01280 #endif
01281             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01282             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01283             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01284             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01285         }
01286 #endif
01287 
01288         // Hermitian Matrix
01289 #if defined (INTERNAL_SPECIAL) || defined (INTERNAL_HERMITIAN)
01290         {
01291             typedef hermitian_matrix<T> container_model;
01292             function_requires< Mutable_MatrixConcept<container_model> >();
01293             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01294             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01295             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01296             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01297         }
01298         
01299         {
01300             typedef hermitian_adaptor<matrix<T> > container_model;
01301 #ifndef SKIP_BAD
01302            // const_iterator (iterator) constructor is bad
01303             function_requires< Mutable_MatrixExpressionConcept<container_model> >();
01304 #endif
01305             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01306             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01307             function_requires< IndexedRandomAccess2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01308             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01309         }
01310 #endif
01311 
01312         // Sparse Matrix
01313 #if defined (INTERNAL_SPARSE) || defined (INTERNAL_MATRIX_SPARSE)
01314         {
01315             typedef mapped_matrix<T> container_model;
01316             function_requires< Mutable_SparseMatrixConcept<container_model> >();
01317             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01318             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01319             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01320             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01321         }
01322         {
01323             typedef mapped_vector_of_mapped_vector<T> container_model;
01324             function_requires< Mutable_SparseMatrixConcept<container_model> >();
01325             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01326             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01327             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01328             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01329         }
01330         {
01331             typedef compressed_matrix<T> container_model;
01332             function_requires< Mutable_SparseMatrixConcept<container_model> >();
01333             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01334             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01335             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01336             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01337         }
01338         {
01339             typedef coordinate_matrix<T> container_model;
01340             function_requires< Mutable_SparseMatrixConcept<container_model> >();
01341             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01342             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01343             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01344             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01345         }
01346         {
01347             typedef generalized_vector_of_vector<T, row_major, vector< coordinate_vector<T> > > container_model;
01348             function_requires< Mutable_SparseMatrixConcept<container_model> >();
01349             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_iterator1, container_model::const_iterator2> >();
01350             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::iterator1, container_model::iterator2> >();
01351             function_requires< IndexedBidirectional2DIteratorConcept<container_model::const_reverse_iterator1, container_model::const_reverse_iterator2> >();
01352             function_requires< Mutable_IndexedBidirectional2DIteratorConcept<container_model::reverse_iterator1, container_model::reverse_iterator2> >();
01353         }
01354 
01355 #endif
01356 
01357         // Scalar Expressions
01358 #if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_VECTOR_EXPRESSION)
01359         function_requires< ScalarExpressionConcept<scalar_value<T> > >();
01360         function_requires< ScalarExpressionConcept<scalar_reference<T> > >();
01361 
01362         // Vector Expressions
01363         {
01364             typedef vector_reference<vector<T> > expression_model;
01365             function_requires< VectorExpressionConcept<expression_model> >();
01366             function_requires< Mutable_VectorExpressionConcept<expression_model> >();
01367             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01368             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::iterator> >();
01369             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01370             function_requires< Mutable_IndexedRandomAccess1DIteratorConcept<expression_model::reverse_iterator> >();
01371         }
01372 
01373         {
01374             typedef vector_unary<vector<T>, scalar_identity<T> > expression_model;
01375             function_requires< VectorExpressionConcept<expression_model> >();
01376             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01377             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01378         }
01379 
01380         {
01381             typedef vector_binary<vector<T>, vector<T>, scalar_plus<T, T> > expression_model;
01382             function_requires< VectorExpressionConcept<expression_model> >();
01383             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01384             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01385         }
01386 
01387         {
01388             typedef vector_binary_scalar1<T, vector<T>, scalar_multiplies<T, T> > expression_model;
01389             function_requires< VectorExpressionConcept<expression_model> >();
01390             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01391             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01392         }
01393 
01394         {
01395             typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
01396             function_requires< VectorExpressionConcept<expression_model> >();
01397             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01398             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01399         }
01400 
01401         {
01402             typedef vector_binary_scalar1<scalar_value<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
01403             function_requires< VectorExpressionConcept<expression_model> >();
01404             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01405             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01406         }
01407 
01408         {
01409             typedef vector_binary_scalar2<vector<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
01410             function_requires< VectorExpressionConcept<expression_model> >();
01411             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01412             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01413         }
01414 
01415         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_sum<vector<T> > > > >();
01416         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_1<vector<T> > > > >();
01417         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_2<vector<T> > > > >();
01418         function_requires< ScalarExpressionConcept<vector_scalar_unary<vector<T>, vector_norm_inf<vector<T> > > > >();
01419 
01420         function_requires< ScalarExpressionConcept<vector_scalar_binary<vector<T>, vector<T>, vector_inner_prod<vector<T>, vector<T>, T> > > >();
01421 #endif
01422 
01423         // Matrix Expressions
01424 #if defined (INTERNAL_EXPRESSION) || defined (INTERNAL_MATRIX_EXPRESSION)
01425         {
01426             typedef matrix_reference<matrix<T> > expression_model;
01427             function_requires< MatrixExpressionConcept<expression_model> >();
01428             function_requires< Mutable_MatrixExpressionConcept<expression_model> >();
01429             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01430             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::iterator1, expression_model::iterator2> >();
01431             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01432             function_requires< Mutable_IndexedRandomAccess2DIteratorConcept<expression_model::reverse_iterator1, expression_model::reverse_iterator2> >();
01433         }
01434 
01435         {
01436             typedef vector_matrix_binary<vector<T>, vector<T>, scalar_multiplies<T, T> > expression_model;
01437             function_requires< MatrixExpressionConcept<expression_model> >();
01438             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01439             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01440         }
01441 
01442         {
01443             typedef matrix_unary1<matrix<T>, scalar_identity<T> > expression_model;
01444             function_requires< MatrixExpressionConcept<expression_model> >();
01445             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01446             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01447         }
01448 
01449         {
01450             typedef matrix_unary2<matrix<T>, scalar_identity<T> > expression_model;
01451             function_requires< MatrixExpressionConcept<expression_model> >();
01452             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01453             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01454         }
01455 
01456         {
01457             typedef matrix_binary<matrix<T>, matrix<T>, scalar_plus<T, T> > expression_model;
01458             function_requires< MatrixExpressionConcept<expression_model> >();
01459             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01460             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01461         }
01462 
01463         {
01464             typedef matrix_binary_scalar1<T, matrix<T>, scalar_multiplies<T, T> > expression_model;
01465             function_requires< MatrixExpressionConcept<expression_model> >();
01466             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01467             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01468         }
01469 
01470         {
01471             typedef matrix_binary_scalar2<matrix<T>, T, scalar_multiplies<T, T> > expression_model;
01472             function_requires< MatrixExpressionConcept<expression_model> >();
01473             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01474             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01475         }
01476 
01477         {
01478             typedef matrix_binary_scalar1<scalar_value<T>, matrix<T>, scalar_multiplies<T, T> > expression_model;
01479             function_requires< MatrixExpressionConcept<expression_model> >();
01480             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01481             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01482         }
01483 
01484         {
01485             typedef matrix_binary_scalar2<matrix<T>, scalar_value<T>, scalar_multiplies<T, T> > expression_model;
01486             function_requires< MatrixExpressionConcept<expression_model> >();
01487             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01488             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01489         }
01490 
01491         {
01492             typedef matrix_vector_binary1<matrix<T>, vector<T>, matrix_vector_prod1<matrix<T>, vector<T>, T> > expression_model;
01493             function_requires< VectorExpressionConcept<expression_model> >();
01494             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01495             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01496         }
01497 
01498         {
01499             typedef matrix_vector_binary2<vector<T>, matrix<T>, matrix_vector_prod2<matrix<T>, vector<T>, T > > expression_model;
01500             function_requires< VectorExpressionConcept<expression_model> >();
01501             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_iterator> >();
01502             function_requires< IndexedRandomAccess1DIteratorConcept<expression_model::const_reverse_iterator> >();
01503         }
01504 
01505         {
01506             typedef matrix_matrix_binary<matrix<T>, matrix<T>, matrix_matrix_prod<matrix<T>, matrix<T>, T > > expression_model;
01507             function_requires< MatrixExpressionConcept<expression_model> >();
01508             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_iterator1, expression_model::const_iterator2> >();
01509             function_requires< IndexedRandomAccess2DIteratorConcept<expression_model::const_reverse_iterator1, expression_model::const_reverse_iterator2> >();
01510         }
01511 
01512         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_1<vector<T> > > > >();
01513         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_frobenius<vector<T> > > > >();
01514         function_requires< ScalarExpressionConcept<matrix_scalar_unary<matrix<T>, matrix_norm_inf<vector<T> > > > >();
01515 #endif
01516 
01517 #ifdef EXTERNAL
01518         function_requires< AdditiveAbelianGroupConcept<float> >();
01519         function_requires< CommutativeRingWithIdentityConcept<float> >();
01520         function_requires< FieldConcept<float> >();
01521         function_requires< VectorSpaceConcept<float, vector<float> > >();
01522         function_requires< Prod_RingWithIdentityConcept<matrix<float> > >();
01523         function_requires< VectorSpaceConcept<float, matrix<float> > >();
01524         function_requires< LinearOperatorConcept<float, vector<float>, matrix<float> > >();
01525 
01526         function_requires< AdditiveAbelianGroupConcept<std::complex<float> > >();
01527         function_requires< CommutativeRingWithIdentityConcept<std::complex<float> > >();
01528         function_requires< FieldConcept<std::complex<float> > >();
01529         function_requires< VectorSpaceConcept<std::complex<float>, vector<std::complex<float> > > >();
01530         function_requires< Prod_RingWithIdentityConcept<matrix<std::complex<float> > > >();
01531         function_requires< VectorSpaceConcept<std::complex<float>, matrix<std::complex<float> > > >();
01532         function_requires< LinearOperatorConcept<std::complex<float>, vector<std::complex<float> >, matrix<std::complex<float> > > >();
01533 #endif
01534     }
01535 
01536     } // end of anonymous namespace
01537 
01538 }}}
01539 
01540 #endif