![]() |
Boost.uBlas 1.49
Linear Algebra in C++: matrices, vectors and numeric algorithms
|
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