00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE
00013 #define MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE
00014
00015 #include <concepts>
00016 #include <boost/numeric/linear_algebra/intrinsic_concept_maps.hpp>
00017 #include <boost/numeric/linear_algebra/operators.hpp>
00018
00019
00020 namespace math {
00021
00022 concept Commutative<typename Operation, typename Element>
00023 : std::Callable2<Op, Element, Element>
00024 {
00025 axiom Commutativity(Operation op, Element x, Element y)
00026 {
00027 op(x, y) == op(y, x);
00028 }
00029 };
00030
00031
00032 concept SemiGroup<typename Operation, typename Element>
00033 : std::Callable2<Op, Element, Element>
00034 {
00035 axiom Associativity(Operation op, Element x, Element y, Element z)
00036 {
00037 op(x, op(y, z)) == op(op(x, y), z);
00038 }
00039 };
00040
00041
00042 concept Monoid<typename Operation, typename Element>
00043 : SemiGroup<Operation, Element>
00044 {
00045 typename identity_result_type;
00046 identity_result_type identity(Operation, Element);
00047
00048 axiom Neutrality(Operation op, Element x)
00049 {
00050 op( x, identity(op, x) ) == x;
00051 op( identity(op, x), x ) == x;
00052 }
00053 };
00054
00055
00056 auto concept Inversion<typename Operation, typename Element>
00057 {
00058 typename result_type;
00059 result_type inverse(Operation, Element);
00060
00061 };
00062
00063
00064 concept PIMonoid<typename Operation, typename Element>
00065 : Monoid<Operation, Element>,
00066 Inversion<Operation, Element>
00067 {
00068 bool is_invertible(Operation, Element);
00069
00070 requires std::Convertible<Inversion<Operation, Element>::result_type, Element>;
00071
00072 axiom Invertibility(Operation op, Element x)
00073 {
00074
00075 if (is_invertible(op, x))
00076 op( x, inverse(op, x) ) == identity(op, x);
00077 if ( is_invertible(op, x) )
00078 op( inverse(op, x), x ) == identity(op, x);
00079 }
00080 }
00081
00082 #if 0
00083
00084
00085 template <typename Operation, typename Element>
00086 requires PIMonoid<Operation, Element>
00087 concept_map PIMonoid<Operation, Inversion<Operation, Element>::result_type> {}
00088 #endif
00089
00090
00091 concept Group<typename Operation, typename Element>
00092 : PIMonoid<Operation, Element>
00093 {
00094 bool is_invertible(Operation, Element) { return true; }
00095
00096
00097 axiom AlwaysInvertible(Operation op, Element x)
00098 {
00099 is_invertible(op, x);
00100 }
00101
00102
00103
00104 axiom GlobalInvertibility(Operation op, Element x)
00105 {
00106 op( x, inverse(op, x) ) == identity(op, x);
00107 op( inverse(op, x), x ) == identity(op, x);
00108 }
00109 };
00110
00111
00112 auto concept AbelianGroup<typename Operation, typename Element>
00113 : Group<Operation, Element>, Commutative<Operation, Element>
00114 {};
00115
00116
00117
00118
00119
00120
00121
00122 concept Additive<typename Element>
00123 : std::HasPlus<Element>
00124 {
00125 typename plus_assign_result_type;
00126 plus_assign_result_type operator+=(Element& x, Element y)
00127 {
00128 x= x + y; return x;
00129 }
00130
00131 requires std::Convertible<plus_assign_result_type, Element&>;
00132
00133
00134
00135
00136
00137
00138 axiom Consistency(add<Element> op, Element x, Element y)
00139 {
00140 op(x, y) == x + y;
00141 op(x, y) == (x += y, x);
00142 }
00143 }
00144
00145
00146 auto concept AdditiveCommutative<typename Element>
00147 : Additive<Element>,
00148 Commutative< add<Element>, Element >
00149 {}
00150
00151
00152 auto concept AdditiveSemiGroup<typename Element>
00153 : Additive<Element>,
00154 SemiGroup< add<Element>, Element >
00155 {}
00156
00157
00158 concept AdditiveMonoid<typename Element>
00159 : AdditiveSemiGroup<Element>,
00160 Monoid< add<Element>, Element >
00161 {
00162 Element zero(Element x)
00163 {
00164 return identity(add<Element>(), x);
00165 }
00166
00167
00168 axiom IdentityConsistency (add<Element> op, Element x)
00169 {
00170 zero(x) == identity(op, x);
00171 }
00172 };
00173
00174 #ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS // Uncompilable due to error in compiler
00175 concept AdditivePIMonoid<typename Element>
00176 : std::HasMinus<Element>, AdditiveMonoid<Element>,
00177 PIMonoid< add<Element>, Element >
00178 {
00179 typename minus_assign_result_type;
00180 minus_assign_result_type operator-=(Element& x, Element y)
00181 {
00182 x= x - y; return x;
00183 }
00184
00185 requires std::Convertible<minus_assign_result_type, Element&>;
00186
00187 typename unary_result_type;
00188 unary_result_type operator-(Element x)
00189 {
00190 return zero(x) - x;
00191 }
00192
00193 axiom InverseConsistency(add<Element> op, Element x, Element y)
00194 {
00195
00196 if ( is_invertible(op, y) )
00197 op(x, inverse(op, y)) == x - y;
00198 if ( is_invertible(op, y) )
00199 op(x, y) == (x -= y, x);
00200
00201
00202 if ( is_invertible(op, y) )
00203 inverse(op, y) == -y;
00204
00205
00206 if ( is_invertible(op, x) )
00207 identity(op, x) - x == -x;
00208 }
00209 }
00210
00211
00212 auto concept AdditiveGroup<typename Element>
00213 : AdditivePIMonoid<Element>,
00214 Group< add<Element>, Element >
00215 {};
00216
00217
00218 auto concept AdditiveAbelianGroup<typename Element>
00219 : AdditiveGroup<Element>,
00220 Commutative< add<Element>, Element >
00221 {}
00222
00223 #endif
00224
00225
00226 concept Multiplicative<typename Element>
00227 : std::HasMultiply<Element>
00228 {
00229 typename times_assign_result_type;
00230 times_assign_result_type operator*=(Element& x, Element y)
00231 {
00232 x= x * y; return x;
00233 }
00234
00235 requires std::Convertible<times_assign_result_type, Element&>;
00236
00237
00238
00239
00240
00241
00242 axiom Consistency(mult<Element> op, Element x, Element y)
00243 {
00244 op(x, y) == x * y;
00245 op(x, y) == (x *= y, x);
00246 }
00247 }
00248
00249
00250 auto concept MultiplicativeCommutative<typename Element>
00251 : Multiplicative<Element>,
00252 Commutative< mult<Element>, Element >
00253 {}
00254
00255
00256 auto concept MultiplicativeSemiGroup<typename Element>
00257 : Multiplicative<Element>,
00258 SemiGroup< mult<Element>, Element >
00259 {}
00260
00261
00262 concept MultiplicativeMonoid<typename Element>
00263 : MultiplicativeSemiGroup<Element>,
00264 Monoid< mult<Element>, Element >
00265 {
00266 Element one(Element x)
00267 {
00268 return identity(mult<Element>(), x);
00269 }
00270
00271
00272 axiom IdentityConsistency (math::mult<Element> op, Element x)
00273 {
00274 one(x) == identity(op, x);
00275 }
00276 };
00277
00278 #ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS // Uncompilable due to error in compiler
00279 concept MultiplicativePIMonoid<typename Element>
00280 : std::HasDivide<Element>, MultiplicativeMonoid<Element>,
00281 PIMonoid< mult<Element>, Element >
00282 {
00283 typename divide_assign_result_type;
00284 divide_assign_result_type operator/=(Element& x, Element y)
00285 {
00286 x= x / y; return x;
00287 }
00288
00289 requires std::Convertible<divide_assign_result_type, Element&>;
00290
00291 axiom InverseConsistency(mult<Element> op, Element x, Element y)
00292 {
00293
00294 if ( is_invertible(op, y) )
00295 op(x, inverse(op, y)) == x / y;
00296 if ( is_invertible(op, y) )
00297 op(x, y) == (x /= y, x);
00298 }
00299 }
00300
00301
00302 auto concept MultiplicativeGroup<typename Element>
00303 : MultiplicativePIMonoid<Element>,
00304 Group< mult<Element>, Element >
00305 {};
00306
00307
00308 auto concept MultiplicativeAbelianGroup<typename Element>
00309 : MultiplicativeGroup<Element>,
00310 Commutative< mult<Element>, Element >
00311 {}
00312
00313
00314
00315
00316
00317
00318
00319
00320 concept Distributive<typename AddOp, typename MultOp, typename Element>
00321 {
00322 axiom Distributivity(AddOp add, MultOp mult, Element x, Element y, Element z)
00323 {
00324
00325 mult(x, add(y, z)) == add(mult(x, y), mult(x, z));
00326
00327 mult(add(x, y), z) == add(mult(x, z), mult(y, z));
00328 }
00329 }
00330
00331
00332 auto concept Ring<typename AddOp, typename MultOp, typename Element>
00333 : AbelianGroup<AddOp, Element>,
00334 SemiGroup<MultOp, Element>,
00335 Distributive<AddOp, MultOp, Element>
00336 {}
00337
00338
00339 auto concept RingWithIdentity<typename AddOp, typename MultOp, typename Element>
00340 : Ring<AddOp, MultOp, Element>,
00341 Monoid<MultOp, Element>
00342 {}
00343
00344
00345 concept DivisionRing<typename AddOp, typename MultOp, typename Element>
00346 : RingWithIdentity<AddOp, MultOp, Element>,
00347 Inversion<MultOp, Element>
00348 {
00349
00350 axiom ZeroIsDifferentFromOne(AddOp add, MultOp mult, Element x)
00351 {
00352 identity(add, x) != identity(mult, x);
00353 }
00354
00355
00356 axiom NonZeroDivisibility(AddOp add, MultOp mult, Element x)
00357 {
00358 if (x != identity(add, x))
00359 mult(inverse(mult, x), x) == identity(mult, x);
00360 if (x != identity(add, x))
00361 mult(x, inverse(mult, x)) == identity(mult, x);
00362 }
00363 }
00364
00365
00366 auto concept Field<typename AddOp, typename MultOp, typename Element>
00367 : DivisionRing<AddOp, MultOp, Element>,
00368 Commutative<MultOp, Element>
00369 {}
00370
00371
00372 auto concept OperatorRing<typename Element>
00373 : AdditiveAbelianGroup<Element>,
00374 MultiplicativeSemiGroup<Element>,
00375 Ring<add<Element>, mult<Element>, Element>
00376 {}
00377
00378
00379 auto concept OperatorRingWithIdentity<typename Element>
00380 : OperatorRing<Element>,
00381 MultiplicativeMonoid<Element>,
00382 RingWithIdentity<add<Element>, mult<Element>, Element>
00383 {}
00384
00385
00386 auto concept OperatorDivisionRing<typename Element>
00387 : OperatorRingWithIdentity<Element>,
00388 MultiplicativePIMonoid<Element>,
00389 DivisionRing<add<Element>, mult<Element>, Element>
00390 {}
00391
00392
00393 auto concept OperatorField<typename Element>
00394 : OperatorDivisionRing<Element>,
00395 Field<add<Element>, mult<Element>, Element>
00396 {}
00397
00398
00399
00400 #endif
00401
00402 concept IntrinsicType<typename T> {}
00403
00404 concept IntrinsicArithmetic<typename T> : IntrinsicType<T> {}
00405
00406 concept IntrinsicIntegral<typename T> : IntrinsicArithmetic<T> {}
00407
00408 concept IntrinsicSignedIntegral<typename T>
00409 : std::SignedIntegralLike<T>,
00410 IntrinsicIntegral<T>
00411 {}
00412
00413 concept IntrinsicUnsignedIntegral<typename T>
00414 : std::UnsignedIntegralLike<T>,
00415 IntrinsicIntegral<T>
00416 {}
00417
00418 concept IntrinsicFloatingPoint<typename T>
00419 : std::FloatingPointLike<T>,
00420 IntrinsicArithmetic<T>
00421 {}
00422
00423
00424
00425
00426 concept_map IntrinsicSignedIntegral<char> {}
00427 concept_map IntrinsicSignedIntegral<signed char> {}
00428 concept_map IntrinsicUnsignedIntegral<unsigned char> {}
00429 concept_map IntrinsicSignedIntegral<short> {}
00430 concept_map IntrinsicUnsignedIntegral<unsigned short> {}
00431 concept_map IntrinsicSignedIntegral<int> {}
00432 concept_map IntrinsicUnsignedIntegral<unsigned int> {}
00433 concept_map IntrinsicSignedIntegral<long> {}
00434 concept_map IntrinsicUnsignedIntegral<unsigned long> {}
00435 concept_map IntrinsicSignedIntegral<long long> {}
00436 concept_map IntrinsicUnsignedIntegral<unsigned long long> {}
00437
00438 concept_map IntrinsicFloatingPoint<float> {}
00439 concept_map IntrinsicFloatingPoint<double> {}
00440
00441
00442 #ifndef CONCEPTS_WITHOUT_OVERLOADED_REQUIREMENTS
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 template <typename T>
00457 requires IntrinsicSignedIntegral<T>
00458 concept_map OperatorRingWithIdentity<T> {}
00459
00460 template <typename T>
00461 requires IntrinsicSignedIntegral<T>
00462 concept_map MultiplicativeCommutative<T> {}
00463
00464
00465
00466
00467
00468
00469 template <typename T>
00470 requires IntrinsicUnsignedIntegral<T>
00471 concept_map AdditiveCommutative<T> {}
00472
00473 template <typename T>
00474 requires IntrinsicUnsignedIntegral<T>
00475 concept_map AdditiveMonoid<T> {}
00476
00477 template <typename T>
00478 requires IntrinsicUnsignedIntegral<T>
00479 concept_map MultiplicativeCommutative<T> {}
00480
00481 template <typename T>
00482 requires IntrinsicUnsignedIntegral<T>
00483 concept_map MultiplicativeMonoid<T> {}
00484
00485
00486
00487
00488
00489
00490 template <typename T>
00491 requires IntrinsicFloatingPoint<T>
00492 concept_map Field<T> {}
00493
00494 template <typename T>
00495 requires IntrinsicFloatingPoint<T>
00496 concept_map Field< std::complex<T> > {}
00497
00498
00499
00500
00501
00502
00503
00504 template <typename T>
00505 requires IntrinsicArithmetic<T>
00506 concept_map Commutative< max<T>, T > {}
00507
00508 template <typename T>
00509 requires IntrinsicArithmetic<T>
00510 concept_map Monoid< max<T>, T > {}
00511
00512 template <typename T>
00513 requires IntrinsicArithmetic<T>
00514 concept_map Commutative< min<T>, T > {}
00515
00516 template <typename T>
00517 requires IntrinsicArithmetic<T>
00518 concept_map Monoid< min<T>, T > {}
00519
00520
00521
00522
00523
00524
00525 template <typename T>
00526 requires Intrinsic<T> && std::HasLogicalAnd<T>
00527 concept_map Commutative< std::logical_and<T>, T > {}
00528
00529 template <typename T>
00530 requires Intrinsic<T> && std::HasLogicalAnd<T>
00531 concept_map Monoid< std::logical_and<T>, T > {}
00532
00533 template <typename T>
00534 requires Intrinsic<T> && std::HasLogicalOr<T>
00535 concept_map Commutative< std::logical_or<T>, T > {}
00536
00537 template <typename T>
00538 requires Intrinsic<T> && std::HasLogicalOr<T>
00539 concept_map Monoid< std::logical_or<T>, T > {}
00540
00541 template <typename T>
00542 requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T>
00543 concept_map Distributive<std::logical_and<T>, std::logical_or<T>, T> {}
00544
00545 template <typename T>
00546 requires Intrinsic<T> && std::HasLogicalAnd<T> && std::HasLogicalOr<T>
00547 concept_map Distributive<std::logical_or<T>, std::logical_and<T>, T> {}
00548
00549
00550
00551
00552
00553
00554
00555
00556 template <typename T>
00557 requires IntrinsicIntegral<T>
00558 concept_map Commutative< bit_and<T>, T > {}
00559
00560 template <typename T>
00561 requires IntrinsicIntegral<T>
00562 concept_map Monoid< bit_and<T>, T > {}
00563
00564 template <typename T>
00565 requires IntrinsicIntegral<T>
00566 concept_map Commutative< bit_or<T>, T > {}
00567
00568 template <typename T>
00569 requires IntrinsicIntegral<T>
00570 concept_map Monoid< bit_or<T>, T > {}
00571
00572 template <typename T>
00573 requires IntrinsicIntegral<T>
00574 concept_map Distributive<bit_and<T>, bit_or<T>, T> {}
00575
00576 template <typename T>
00577 requires IntrinsicIntegral<T>
00578 concept_map Distributive<bit_or<T>, bit_and<T>, T> {}
00579
00580 template <typename T>
00581 requires IntrinsicIntegral<T>
00582 concept_map Commutative< bit_xor<T>, T > {}
00583
00584 template <typename T>
00585 requires IntrinsicIntegral<T>
00586 concept_map SemiGroup< bit_xor<T>, T > {}
00587
00588
00589
00590
00591
00592 concept_map AdditiveMonoid<std::string> {}
00593
00594
00595 #endif
00596
00597
00598
00599 }
00600
00601 #endif // MTL_NEW_ALGEBRAIC_CONCEPTS_INCLUDE