00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef LA_CONCEPTS_INCLUDE
00014 #define LA_CONCEPTS_INCLUDE
00015
00016 #include <boost/config/concept_macros.hpp>
00017
00018 #ifdef __GXX_CONCEPTS__
00019 # include <concepts>
00020 #else
00021 # ifdef LA_SHOW_WARNINGS
00022 # warning "Concepts are not used"
00023 # endif
00024 #endif
00025
00026
00027 #include <boost/numeric/linear_algebra/identity.hpp>
00028 #include <boost/numeric/linear_algebra/is_invertible.hpp>
00029 #include <boost/numeric/linear_algebra/inverse.hpp>
00030 #include <boost/numeric/linear_algebra/operators.hpp>
00031 #include <boost/numeric/linear_algebra/algebraic_concepts.hpp>
00032 #include <complex>
00033
00034
00035
00036
00037
00038
00040
00042 namespace math {
00043
00044 #ifdef __GXX_CONCEPTS__
00045
00046
00047
00048
00049
00050
00051
00052 #if 0
00053
00054
00055 concept Float<typename T>
00056 : std::DefaultConstructible<T>, std::CopyConstructible<T>,
00057 std::LessThanComparable<T>, std::EqualityComparable<T>
00058 {
00059 T operator+(T);
00060 T operator+(T, T);
00061 T& operator+=(T&, T);
00062 T operator-(T, T);
00063 T operator-(T);
00064 T& operator-=(T&, T);
00065 T operator*(T, T);
00066 T& operator*=(T&, T);
00067 T operator/(T, T);
00068 T& operator/=(T&, T);
00069
00070 requires std::CopyAssignable<T>
00071 && std::SameType<std::CopyAssignable<T>::result_type, T&>;
00072 }
00073
00074 concept_map Float<float> {}
00075 concept_map Float<double> {}
00076 concept_map Float<long double> {}
00077
00078
00079 concept Complex<typename T>
00080 : std::DefaultConstructible<T>, std::CopyConstructible<T>,
00081 std::EqualityComparable<T>
00082 {
00083 T operator+(T);
00084 T operator+(T, T);
00085 T& operator+=(T&, T);
00086 T operator-(T, T);
00087 T operator-(T);
00088 T& operator-=(T&, T);
00089 T operator*(T, T);
00090 T& operator*=(T&, T);
00091 T operator/(T, T);
00092 T& operator/=(T&, T);
00093
00094 requires std::CopyAssignable<T>
00095 && std::SameType<std::CopyAssignable<T>::result_type, T&>;
00096 }
00097
00098 template <typename T>
00099 requires Float<T>
00100 concept_map Complex<std::complex<T> > {}
00101
00102
00103
00104
00105 concept Arithmetic<typename T> {}
00106
00107 template <typename T>
00108 requires std::Integral<T>
00109 concept_map Arithmetic<T> {}
00110
00111 template <typename T>
00112 requires Float<T>
00113 concept_map Arithmetic<T> {}
00114
00115 template <typename T>
00116 requires Arithmetic<T>
00117 concept_map Arithmetic< std::complex<T> > {}
00118
00119 #endif
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 concept IntrinsicSignedIntegral<typename T>
00131 : std::SignedIntegralLike<T>
00132 {}
00133
00134 concept IntrinsicUnsignedIntegral<typename T>
00135 : std::UnsignedIntegralLike<T>
00136 {}
00137
00138 concept IntrinsicFloatingPoint<typename T>
00139 : std::FloatingPointLike<T>
00140 {}
00141
00142
00143
00144
00145 concept_map IntrinsicSignedIntegral<char> {}
00146 concept_map IntrinsicSignedIntegral<signed char> {}
00147 concept_map IntrinsicUnsignedIntegral<unsigned char> {}
00148 concept_map IntrinsicSignedIntegral<short> {}
00149 concept_map IntrinsicUnsignedIntegral<unsigned short> {}
00150 concept_map IntrinsicSignedIntegral<int> {}
00151 concept_map IntrinsicUnsignedIntegral<unsigned int> {}
00152 concept_map IntrinsicSignedIntegral<long> {}
00153 concept_map IntrinsicUnsignedIntegral<unsigned long> {}
00154 concept_map IntrinsicSignedIntegral<long long> {}
00155 concept_map IntrinsicUnsignedIntegral<unsigned long long> {}
00156
00157 concept_map IntrinsicFloatingPoint<float> {}
00158 concept_map IntrinsicFloatingPoint<double> {}
00159
00160
00161
00162
00163
00164
00165
00166
00167 auto concept UnaryIsoFunction<typename Operation, typename Element>
00168 {
00169 requires std::Callable1<Operation, Element>;
00170 requires std::Convertible<std::Callable1<Operation, Element>::result_type, Element>;
00171
00172 typename result_type = std::Callable1<Operation, Element>::result_type;
00173 };
00174
00175
00176 auto concept BinaryIsoFunction<typename Operation, typename Element>
00177 {
00178 requires std::Callable2<Operation, Element, Element>;
00179 requires std::Convertible<std::Callable2<Operation, Element, Element>::result_type, Element>;
00180
00181 typename result_type = std::Callable2<Operation, Element, Element>::result_type;
00182 };
00183
00184 #if 0
00185 auto concept CompatibleBinaryFunction<typename A1, typename A2, typename Result>
00186 {
00187 typename result_type;
00188 result_type F(A1, A2);
00189 requires std::Convertible<result_type, Result>;
00190 }
00191 #endif
00192
00193
00194
00195
00196
00197
00198 auto concept Magma<typename Operation, typename Element>
00199 : BinaryIsoFunction<Operation, Element>
00200 {
00201 requires std::CopyAssignable<Element>
00202 && std::CopyAssignable<Element, BinaryIsoFunction<Operation, Element>::result_type>;
00203 };
00204
00205
00206
00207
00208
00209 auto concept CommutativeMagma<typename Operation, typename Element>
00210 : Magma<Operation, Element>,
00211 algebra::Commutative<Operation, Element>
00212 {};
00213
00214
00215
00216 auto concept SemiGroup<typename Operation, typename Element>
00217 : Magma<Operation, Element>,
00218 algebra::SemiGroup<Operation, Element>
00219 {};
00220
00221
00222 auto concept CommutativeSemiGroup<typename Operation, typename Element>
00223 : SemiGroup<Operation, Element>,
00224 CommutativeMagma<Operation, Element>
00225 {};
00226
00227
00228
00229
00230 concept Monoid<typename Operation, typename Element>
00231 : SemiGroup<Operation, Element>,
00232 algebra::Monoid<Operation, Element>
00233 {
00234 requires std::Convertible<identity_result_type, Element>;
00235 };
00236
00237
00238 auto concept CommutativeMonoid<typename Operation, typename Element>
00239 : CommutativeSemiGroup<Operation, Element>,
00240 Monoid<Operation, Element>
00241 {};
00242
00243
00244 concept PartiallyInvertibleMonoid<typename Operation, typename Element>
00245 : Monoid<Operation, Element>,
00246 algebra::Inversion<Operation, Element>
00247 {
00248 typename is_invertible_result_type;
00249 is_invertible_result_type is_invertible(Operation, Element);
00250 requires std::Convertible<is_invertible_result_type, bool>;
00251
00252 requires std::Convertible<inverse_result_type, Element>;
00253
00254
00255 axiom Inversivity(Operation op, Element x)
00256 {
00257
00258 if (is_invertible(op, x))
00259 op( x, inverse(op, x) ) == identity(op, x);
00260 if ( is_invertible(op, x) )
00261 op( inverse(op, x), x ) == identity(op, x);
00262 }
00263 };
00264
00265
00266 auto concept PartiallyInvertibleCommutativeMonoid<typename Operation, typename Element>
00267 : PartiallyInvertibleMonoid<Operation, Element>,
00268 CommutativeMonoid<Operation, Element>
00269 {};
00270
00271
00272 concept Group<typename Operation, typename Element>
00273 : PartiallyInvertibleMonoid<Operation, Element>,
00274 algebra::Group<Operation, Element>
00275 {
00276 axiom AlwaysInvertible(Operation op, Element x)
00277 {
00278 is_invertible(op, x);
00279 }
00280
00281 axiom GlobalInversivity(Operation op, Element x)
00282 {
00283
00284
00285 op( x, inverse(op, x) ) == identity(op, x);
00286 op( inverse(op, x), x ) == identity(op, x);
00287 }
00288 };
00289
00290
00291 auto concept AbelianGroup<typename Operation, typename Element>
00292 : Group<Operation, Element>,
00293 PartiallyInvertibleCommutativeMonoid<Operation, Element>,
00294 algebra::AbelianGroup<Operation, Element>
00295 {};
00296
00297
00298
00299
00300
00301
00302
00303 concept AdditiveMagma<typename Element>
00304 : Magma< math::add<Element>, Element >
00305 {
00306 typename plus_assign_result_type;
00307 plus_assign_result_type operator+=(Element& x, Element y);
00308
00309
00310
00311 typename addition_result_type;
00312 addition_result_type operator+(Element x, Element y);
00313 #if 0
00314 {
00315 Element tmp(x);
00316 return tmp += y; defaults NYS
00317 }
00318 #endif
00319 requires std::Convertible<addition_result_type, Element>;
00320
00321
00322 requires std::Convertible< addition_result_type,
00323 Magma< math::add<Element>, Element >::result_type>;
00324
00325
00326
00327
00328
00329 axiom Consistency(math::add<Element> op, Element x, Element y)
00330 {
00331 op(x, y) == x + y;
00332
00333
00334 x + y == x += y;
00335
00336 }
00337 }
00338
00339
00340 auto concept AdditiveCommutativeMagma<typename Element>
00341 : AdditiveMagma<Element>,
00342 CommutativeMagma< math::add<Element>, Element >
00343 {};
00344
00345
00346 auto concept AdditiveSemiGroup<typename Element>
00347 : AdditiveMagma<Element>,
00348 SemiGroup< math::add<Element>, Element >
00349 {};
00350
00351
00352
00353
00354
00355
00356 auto concept AdditiveCommutativeSemiGroup<typename Element>
00357 : AdditiveSemiGroup<Element>,
00358 AdditiveCommutativeMagma<Element>,
00359 CommutativeSemiGroup< math::add<Element>, Element >
00360 {};
00361
00362
00363 concept AdditiveMonoid<typename Element>
00364 : AdditiveSemiGroup<Element>,
00365 Monoid< math::add<Element>, Element >
00366 {
00367 Element zero(Element v);
00368
00369 axiom Consistency (math::add<Element> op, Element x)
00370 {
00371 zero(x) == identity(op, x);
00372 }
00373 };
00374
00375
00376
00377
00378
00379
00380 auto concept AdditiveCommutativeMonoid<typename Element>
00381 : AdditiveMonoid<Element>,
00382 AdditiveCommutativeSemiGroup<Element>,
00383 CommutativeMonoid< math::add<Element>, Element >
00384 {};
00385
00386
00387 concept AdditivePartiallyInvertibleMonoid<typename Element>
00388 : AdditiveMonoid<Element>,
00389 PartiallyInvertibleMonoid< math::add<Element>, Element >
00390 {
00391 typename minus_assign_result_type;
00392 minus_assign_result_type operator-=(Element& x, Element y);
00393
00394
00395
00396 typename subtraction_result_type;
00397 subtraction_result_type operator-(Element& x, Element y);
00398 #if 0
00399 {
00400 Element tmp(x);
00401 return tmp -= y; defaults NYS
00402 }
00403 #endif
00404 requires std::Convertible<subtraction_result_type, Element>;
00405
00406
00407 typename unary_result_type;
00408 unary_result_type operator-(Element x);
00409 #if 0
00410 {
00411 return zero(x) - x; defaults NYS
00412 }
00413 #endif
00414 requires std::Convertible<unary_result_type, Element>;
00415
00416 axiom Consistency(math::add<Element> op, Element x, Element y)
00417 {
00418
00419 if ( is_invertible(op, y) )
00420 op(x, inverse(op, y)) == x - y;
00421 if ( is_invertible(op, y) )
00422 inverse(op, y) == -y;
00423
00424
00425 if ( is_invertible(op, x) )
00426 identity(op, x) - x == -x;
00427
00428
00429 if ( is_invertible(op, y) )
00430 x - y == x -= y;
00431
00432 }
00433
00434 };
00435
00436
00437 auto concept AdditivePartiallyInvertibleCommutativeMonoid<typename Element>
00438 : AdditivePartiallyInvertibleMonoid<Element>,
00439 AdditiveCommutativeMonoid<Element>,
00440 PartiallyInvertibleCommutativeMonoid< math::add<Element>, Element >
00441 {};
00442
00443
00444
00445 auto concept AdditiveGroup<typename Element>
00446 : AdditivePartiallyInvertibleMonoid<Element>,
00447 Group< math::add<Element>, Element >
00448 {};
00449
00450
00451 auto concept AdditiveAbelianGroup<typename Element>
00452 : AdditiveGroup<Element>,
00453 AdditiveCommutativeMonoid<Element>,
00454 AbelianGroup< math::add<Element>, Element >
00455 {};
00456
00457
00458
00459
00460
00461
00462
00463 concept MultiplicativeMagma<typename Element>
00464 : Magma< math::mult<Element>, Element >
00465 {
00466 typename mult_assign_result_type;
00467 mult_assign_result_type operator*=(Element& x, Element y);
00468
00469
00470
00471 typename mult_result_type;
00472 mult_result_type operator*(Element x, Element y);
00473 #if 0
00474 {
00475 Element tmp(x);
00476 return tmp *= y; defaults NYS
00477 }
00478 #endif
00479 requires std::Convertible<mult_result_type, Element>;
00480
00481
00482 requires std::Convertible< mult_result_type,
00483 Magma< math::mult<Element>, Element >::result_type>;
00484
00485
00486
00487
00488
00489
00490 axiom Consistency(math::mult<Element> op, Element x, Element y)
00491 {
00492 op(x, y) == x * y;
00493
00494
00495 x * y == x *= y;
00496
00497 }
00498
00499 }
00500
00501
00502 auto concept MultiplicativeSemiGroup<typename Element>
00503 : MultiplicativeMagma<Element>,
00504 SemiGroup< math::mult<Element>, Element >
00505 {};
00506
00507
00508 auto concept MultiplicativeCommutativeSemiGroup<typename Element>
00509 : MultiplicativeSemiGroup<Element>,
00510 CommutativeSemiGroup< math::mult<Element>, Element >
00511 {};
00512
00513
00514 concept MultiplicativeMonoid<typename Element>
00515 : MultiplicativeSemiGroup<Element>,
00516 Monoid< math::mult<Element>, Element >
00517 {
00518 Element one(Element v);
00519
00520 axiom Consistency (math::mult<Element> op, Element x)
00521 {
00522 one(x) == identity(op, x);
00523 }
00524 };
00525
00526
00527 auto concept MultiplicativeCommutativeMonoid<typename Element>
00528 : MultiplicativeMonoid<Element>,
00529 MultiplicativeCommutativeSemiGroup<Element>,
00530 CommutativeMonoid< math::mult<Element>, Element >
00531 {};
00532
00533
00534 concept MultiplicativePartiallyInvertibleMonoid<typename Element>
00535 : MultiplicativeMonoid<Element>,
00536 PartiallyInvertibleMonoid< math::mult<Element>, Element >
00537 {
00538 typename divide_assign_result_type;
00539 divide_assign_result_type operator/=(Element& x, Element y);
00540
00541
00542
00543 typename division_result_type = Element;
00544 division_result_type operator/(Element x, Element y);
00545 #if 0
00546 {
00547 Element tmp(x);
00548 return tmp /= y; defaults NYS
00549 }
00550 #endif
00551 requires std::Convertible<division_result_type, Element>;
00552
00553 axiom Consistency(math::mult<Element> op, Element x, Element y)
00554 {
00555
00556 if ( is_invertible(op, y) )
00557 op(x, inverse(op, y)) == x / y;
00558
00559
00560 if ( is_invertible(op, y) )
00561 x / y == x /= y;
00562
00563 }
00564 };
00565
00566
00567 auto concept MultiplicativePartiallyInvertibleCommutativeMonoid<typename Element>
00568 : MultiplicativePartiallyInvertibleMonoid<Element>,
00569 MultiplicativeCommutativeMonoid<Element>,
00570 PartiallyInvertibleCommutativeMonoid< math::mult<Element>, Element >
00571 {};
00572
00573
00574 auto concept MultiplicativeGroup<typename Element>
00575 : MultiplicativeMonoid<Element>,
00576 Group< math::mult<Element>, Element >
00577 {};
00578
00579
00580 auto concept MultiplicativeAbelianGroup<typename Element>
00581 : MultiplicativeGroup<Element>,
00582 MultiplicativeCommutativeMonoid<Element>,
00583 AbelianGroup< math::mult<Element>, Element >
00584 {};
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597 auto concept GenericRing<typename AddOp, typename MultOp, typename Element>
00598 : AbelianGroup<AddOp, Element>,
00599 SemiGroup<MultOp, Element>,
00600 algebra::Ring<AddOp, MultOp, Element>
00601 {};
00602
00603
00604 auto concept GenericCommutativeRing<typename AddOp, typename MultOp, typename Element>
00605 : GenericRing<AddOp, MultOp, Element>,
00606 CommutativeSemiGroup<MultOp, Element>
00607 {};
00608
00609
00610 auto concept GenericRingWithIdentity<typename AddOp, typename MultOp, typename Element>
00611 : GenericRing<AddOp, MultOp, Element>,
00612 Monoid<MultOp, Element>,
00613 algebra::RingWithIdentity<AddOp, MultOp, Element>
00614 {};
00615
00616
00617 auto concept GenericCommutativeRingWithIdentity<typename AddOp, typename MultOp, typename Element>
00618 : GenericRingWithIdentity<AddOp, MultOp, Element>,
00619 GenericCommutativeRing<AddOp, MultOp, Element>,
00620 CommutativeMonoid<MultOp, Element>
00621 {};
00622
00623
00624
00625 concept GenericDivisionRing<typename AddOp, typename MultOp, typename Element>
00626 : GenericRingWithIdentity<AddOp, MultOp, Element>,
00627 algebra::DivisionRing<AddOp, MultOp, Element>
00628 {
00629 requires std::Convertible<inverse_result_type, Element>;
00630 };
00631
00632
00633 auto concept GenericField<typename AddOp, typename MultOp, typename Element>
00634 : GenericDivisionRing<AddOp, MultOp, Element>,
00635 GenericCommutativeRingWithIdentity<AddOp, MultOp, Element>,
00636 algebra::Field<AddOp, MultOp, Element>
00637 {};
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 auto concept Ring<typename Element>
00651 : AdditiveAbelianGroup<Element>,
00652 MultiplicativeSemiGroup<Element>,
00653 GenericRing<math::add<Element>, math::mult<Element>, Element>
00654 {};
00655
00656
00657 auto concept CommutativeRing<typename Element>
00658 : Ring<Element>,
00659 MultiplicativeCommutativeSemiGroup<Element>,
00660 GenericCommutativeRing<math::add<Element>, math::mult<Element>, Element>
00661 {};
00662
00663
00664 auto concept RingWithIdentity<typename Element>
00665 : Ring<Element>,
00666 MultiplicativeMonoid<Element>,
00667 GenericRingWithIdentity<math::add<Element>, math::mult<Element>, Element>
00668 {};
00669
00670
00671 auto concept CommutativeRingWithIdentity<typename Element>
00672 : RingWithIdentity<Element>,
00673 CommutativeRing<Element>,
00674 MultiplicativeCommutativeMonoid<Element>,
00675 GenericCommutativeRingWithIdentity<math::add<Element>, math::mult<Element>, Element>
00676 {};
00677
00678
00679 concept DivisionRing<typename Element>
00680 : RingWithIdentity<Element>,
00681 MultiplicativePartiallyInvertibleMonoid<Element>,
00682 GenericDivisionRing<math::add<Element>, math::mult<Element>, Element>
00683 {
00684 axiom NonZeroDivisibility(Element x)
00685 {
00686 if (x != zero(x))
00687 x / x == one(x);
00688 }
00689 };
00690
00691
00692 auto concept Field<typename Element>
00693 : DivisionRing<Element>,
00694 CommutativeRingWithIdentity<Element>,
00695 GenericField<math::add<Element>, math::mult<Element>, Element>
00696 {};
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 auto concept FullEqualityComparable<typename T, typename U = T>
00709 {
00710
00711
00712 bool operator==(const T&, const U&);
00713 bool operator!=(const T&, const U&);
00714 };
00715
00716
00717
00718
00719 auto concept Closed2EqualityComparable<typename Operation, typename Element>
00720 : BinaryIsoFunction<Operation, Element>
00721 {
00722 requires FullEqualityComparable<Element>;
00723 requires FullEqualityComparable< BinaryIsoFunction<Operation, Element>::result_type >;
00724 requires FullEqualityComparable< Element, BinaryIsoFunction<Operation, Element>::result_type >;
00725 requires FullEqualityComparable< BinaryIsoFunction<Operation, Element>::result_type, Element >;
00726 };
00727
00728
00729
00730
00731 auto concept FullLessThanComparable<typename T, typename U = T>
00732 {
00733 bool operator<(const T&, const U&);
00734 bool operator<=(const T&, const U&);
00735 bool operator>(const T&, const U&);
00736 bool operator>=(const T&, const U&);
00737 };
00738
00739
00740
00741 auto concept Closed2LessThanComparable<typename Operation, typename Element>
00742 : BinaryIsoFunction<Operation, Element>
00743 {
00744 requires FullLessThanComparable<Element>;
00745 requires FullLessThanComparable< BinaryIsoFunction<Operation, Element>::result_type >;
00746 requires FullLessThanComparable< Element, BinaryIsoFunction<Operation, Element>::result_type >;
00747 requires FullLessThanComparable< BinaryIsoFunction<Operation, Element>::result_type, Element >;
00748 };
00749
00750 #if 0
00751 auto concept NumericOperatorResultConvertible<typename T>
00752 : AddableWithAssign<T>,
00753 SubtractableWithAssign<T>,
00754 MultiplicableWithAssign<T>,
00755 DivisibleWithAssign<T>
00756 {
00757 requires std::Convertible< AddableWithAssign<T>::result_type, T>;
00758 requires std::Convertible< SubtractableWithAssign<T>::result_type, T>;
00759 requires std::Convertible< MultiplicableWithAssign<T>::result_type, T>;
00760 requires std::Convertible< DivisibleWithAssign<T>::result_type, T>;
00761 }
00762 #endif
00763
00764 auto concept AdditionResultConvertible<typename T>
00765 {
00766 typename result_type;
00767 result_type operator+(T t, T u);
00768 requires std::Convertible<result_type, T>;
00769
00770 typename result_type;
00771 result_type operator+=(T& t, T u);
00772 requires std::Convertible<result_type, T>;
00773 };
00774
00775
00776 auto concept SubtractionResultConvertible<typename T>
00777 {
00778 typename result_type;
00779 result_type operator-(T t, T u);
00780 requires std::Convertible<result_type, T>;
00781
00782 typename result_type;
00783 result_type operator-=(T& t, T u);
00784 requires std::Convertible<result_type, T>;
00785 };
00786
00787 auto concept NumericOperatorResultConvertible<typename T>
00788 : AdditionResultConvertible<T>,
00789 SubtractionResultConvertible<T>
00790 {};
00791
00792
00793
00794
00795
00796 #ifndef LA_NO_CONCEPT_MAPS
00797
00798
00799
00800
00801
00802 template <typename T>
00803 requires IntrinsicSignedIntegral<T>
00804 concept_map CommutativeRingWithIdentity<T> {}
00805
00806
00807 template <typename T>
00808 requires IntrinsicUnsignedIntegral<T>
00809 concept_map AdditiveCommutativeMonoid<T> {}
00810
00811 template <typename T>
00812 requires IntrinsicUnsignedIntegral<T>
00813 concept_map MultiplicativeCommutativeMonoid<T> {}
00814
00815
00816
00817
00818
00819
00820 template <typename T>
00821 requires IntrinsicFloatingPoint<T>
00822 concept_map Field<T> {}
00823
00824
00825 template <typename T>
00826 requires IntrinsicFloatingPoint<T>
00827 concept_map Field< std::complex<T> > {}
00828
00829
00830
00831
00832
00833
00834
00835
00836 template <typename Element>
00837 concept_map CommutativeMonoid< max<Element>, Element >
00838 {
00839
00840 typedef Element identity_result_type;
00841 }
00842
00843 template <typename Element>
00844 concept_map CommutativeMonoid< min<Element>, Element >
00845 {
00846
00847 typedef Element identity_result_type;
00848 }
00849
00850 #endif // LA_NO_CONCEPT_MAPS
00851
00852
00853
00855
00858 concept NaturalNumber<typename T> {}
00859
00861
00865 concept IntegralNumber<typename T> : NaturalNumber<T> {}
00866
00868
00871 concept ComplexNumber<typename T> {}
00872
00874
00877 concept RealNumber<typename T> : ComplexNumber<T> {}
00878
00879 #endif // __GXX_CONCEPTS__
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 #ifdef __GXX_CONCEPTS__
00890
00891
00892
00893
00894 auto concept Magnitude<typename T>
00895 {
00896 typename type = T;
00897 };
00898
00899 template <typename T>
00900 concept_map Magnitude<std::complex<T> >
00901 {
00902 typedef T type;
00903 }
00904
00905
00906
00907 auto concept RealMagnitude<typename T>
00908 : Magnitude<T>
00909 {
00910 requires FullEqualityComparable<type>;
00911 requires FullLessThanComparable<type>;
00912
00913 requires Field<type>;
00914
00915 type sqrt(type);
00916
00917
00918
00919
00920
00921 type abs(T);
00922 }
00923
00924 #else // now without concepts
00925
00926 template <typename T>
00927 struct Magnitude
00928 {
00929 typename type = T;
00930 };
00931
00932 template <typename T>
00933 struct Magnitude<std::complex<T> >
00934 {
00935 typedef T type;
00936 }
00937
00938 template <typename T> struct RealMagnitude
00939 : public Magnitude<T>
00940 {}
00941
00942 #endif // __GXX_CONCEPTS__
00943
00944
00945
00946 template <typename T>
00947 struct magnitude_type_trait
00948 {
00949 typedef T type;
00950 };
00951
00952 template <typename T>
00953 struct magnitude_type_trait< std::complex<T> >
00954 {
00955 typedef T type;
00956 };
00957
00958
00959
00960
00961
00962
00963
00964 #ifdef __GXX_CONCEPTS__
00965
00966
00967
00968
00969 auto concept Addable<typename T, typename U = T>
00970 {
00971 typename result_type;
00972 result_type operator+(const T& t, const U& u);
00973 };
00974
00975
00976
00977
00978 auto concept AddableWithAssign<typename T, typename U = T>
00979 {
00980 typename assign_result_type;
00981 assign_result_type operator+=(T& x, U y);
00982
00983
00984 typename result_type;
00985 result_type operator+(T x, U y);
00986 #if 0
00987 {
00988
00989 Element tmp(x);
00990 return tmp += y; defaults NYS
00991 }
00992 #endif
00993 };
00994
00995
00996 auto concept Subtractable<typename T, typename U = T>
00997 {
00998 typename result_type;
00999 result_type operator-(const T& t, const U& u);
01000 };
01001
01002
01003
01004
01005 auto concept SubtractableWithAssign<typename T, typename U = T>
01006 {
01007 typename assign_result_type;
01008 assign_result_type operator-=(T& x, U y);
01009
01010
01011 typename result_type;
01012 result_type operator-(T x, U y);
01013 #if 0
01014 {
01015
01016 Element tmp(x);
01017 return tmp -= y; defaults NYS
01018 }
01019 #endif
01020 };
01021
01022
01023 auto concept Multiplicable<typename T, typename U = T>
01024 {
01025 typename result_type;
01026 result_type operator*(const T& t, const U& u);
01027 };
01028
01029
01030
01031
01032 auto concept MultiplicableWithAssign<typename T, typename U = T>
01033 {
01034 typename assign_result_type;
01035 assign_result_type operator*=(T& x, U y);
01036
01037
01038 typename result_type;
01039 result_type operator*(T x, U y);
01040 #if 0
01041 {
01042
01043 Element tmp(x);
01044 return tmp *= y; defaults NYS
01045 }
01046 #endif
01047 };
01048
01049
01050 auto concept Divisible<typename T, typename U = T>
01051 {
01052 typename result_type;
01053 result_type operator / (const T&, const U&);
01054 };
01055
01056
01057
01058
01059 auto concept DivisibleWithAssign<typename T, typename U = T>
01060 {
01061 typename assign_result_type;
01062 assign_result_type operator*=(T& x, U y);
01063
01064
01065 typename result_type;
01066 result_type operator*(T x, U y);
01067 #if 0
01068 {
01069
01070 Element tmp(x);
01071 return tmp *= y; defaults NYS
01072 }
01073 #endif
01074 };
01075
01076
01077 auto concept Transposable<typename T>
01078 {
01079 typename result_type;
01080 result_type trans(T&);
01081 };
01082
01083
01084
01085 auto concept Negatable<typename S>
01086 {
01087 typename result_type = S;
01088 result_type operator-(const S&);
01089 };
01090
01091
01092 using std::abs;
01093 auto concept AbsApplicable<typename S>
01094 {
01095
01096
01097 typename result_type;
01098 result_type abs(const S&);
01099 };
01100
01101
01102 using std::conj;
01103 auto concept HasConjugate<typename S>
01104 {
01105 typename result_type;
01106 result_type conj(const S&);
01107 };
01108
01109
01110
01111 template <Float T>
01112 concept_map HasConjugate<T>
01113 {
01114 typedef T result_type;
01115 result_type conj(const T& s) {return s;}
01116 }
01117
01118
01119
01120
01121 auto concept Dottable<typename T, typename U = T>
01122 {
01123 typename result_type = T;
01124 result_type dot(const T&t, const U& u);
01125 };
01126
01127
01128 auto concept OneNormApplicable<typename V>
01129 {
01130 typename result_type;
01131 result_type one_norm(const V&);
01132 };
01133
01134
01135 auto concept TwoNormApplicable<typename V>
01136 {
01137 typename result_type;
01138 result_type two_norm(const V&);
01139 };
01140
01141
01142 auto concept InfinityNormApplicable<typename V>
01143 {
01144 typename result_type;
01145 result_type inf_norm(const V&);
01146 };
01147
01148
01149
01150
01151 #endif // __GXX_CONCEPTS__
01152
01153
01154 }
01155
01156
01157
01158 #endif // LA_CONCEPTS_INCLUDE