00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE
00013 #define LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE
00014
00015 #ifdef __GXX_CONCEPTS__
00016 # include <concepts>
00017 #else
00018 # include <boost/numeric/linear_algebra/pseudo_concept.hpp>
00019 #endif
00020
00021 #include <boost/numeric/linear_algebra/identity.hpp>
00022 #include <boost/numeric/linear_algebra/inverse.hpp>
00023
00025 namespace algebra {
00026
00031 #ifndef __GXX_CONCEPTS__
00032
00033
00056 template <typename Operation, typename Element>
00057 struct Commutative
00058 {};
00059 #else
00060 concept Commutative<typename Operation, typename Element>
00061 {
00062 axiom Commutativity(Operation op, Element x, Element y)
00063 {
00064 op(x, y) == op(y, x);
00065 }
00066 };
00067 #endif
00068
00069
00070 #ifndef __GXX_CONCEPTS__
00071
00072
00095 template <typename Operation, typename Element>
00096 struct Associative
00097 {};
00098 #else
00099 concept Associative<typename Operation, typename Element>
00100 {
00101 axiom Associativity(Operation op, Element x, Element y, Element z)
00102 {
00103 op(x, op(y, z)) == op(op(x, y), z);
00104 }
00105 };
00106 #endif
00107
00108
00109 #ifndef __GXX_CONCEPTS__
00110
00111
00118 template <typename Operation, typename Element>
00119 struct SemiGroup
00120 : Associative<Operation, Element>
00121 {};
00122 #else
00123 auto concept SemiGroup<typename Operation, typename Element>
00124 : Associative<Operation, Element>
00125 {};
00126 #endif
00127
00128
00129 #ifndef __GXX_CONCEPTS__
00130
00131
00160 template <typename Operation, typename Element>
00161 struct Monoid
00162 : SemiGroup<Operation, Element>
00163 {
00165 typedef associated_type identity_result_type;
00166 identity_result_type identity(Operation, Element);
00167 };
00168 #else
00169 concept Monoid<typename Operation, typename Element>
00170 : SemiGroup<Operation, Element>
00171 {
00172 typename identity_result_type;
00173 identity_result_type identity(Operation, Element);
00174
00175 axiom Neutrality(Operation op, Element x)
00176 {
00177 op( x, identity(op, x) ) == x;
00178 op( identity(op, x), x ) == x;
00179 }
00180 };
00181 #endif
00182
00183 #ifdef __GXX_CONCEPTS__
00184 auto concept Inversion<typename Operation, typename Element>
00185 {
00186 typename inverse_result_type;
00187 inverse_result_type inverse(Operation, Element);
00188
00189 };
00190 #else
00191
00192
00201 template <typename Operation, typename Element>
00202 struct Inversion
00203 {
00205 typedef associated_type inverse_result_type;
00206
00208 inverse_result_type inverse(Operation op, Element x);
00209 };
00210 #endif
00211
00212
00213 #ifdef __GXX_CONCEPTS__
00214 concept Group<typename Operation, typename Element>
00215 : Monoid<Operation, Element>, Inversion<Operation, Element>
00216 {
00217 axiom Inversion(Operation op, Element x)
00218 {
00219 op( x, inverse(op, x) ) == identity(op, x);
00220 op( inverse(op, x), x ) == identity(op, x);
00221 }
00222 };
00223 #else
00224
00225
00255 template <typename Operation, typename Element>
00256 struct Group
00257 : Monoid<Operation, Element>,
00258 Inversion<Operation, Element>
00259 {};
00260 #endif
00261
00262
00263 #ifdef __GXX_CONCEPTS__
00264 auto concept AbelianGroup<typename Operation, typename Element>
00265 : Group<Operation, Element>, Commutative<Operation, Element>
00266 {};
00267 #else
00268
00269
00277 template <typename Operation, typename Element>
00278 struct AbelianGroup
00279 : Group<Operation, Element>,
00280 Commutative<Operation, Element>
00281 {};
00282 #endif
00283
00284
00285 #ifdef __GXX_CONCEPTS__
00286 concept Distributive<typename AddOp, typename MultOp, typename Element>
00287 {
00288 axiom Distributivity(AddOp add, MultOp mult, Element x, Element y, Element z)
00289 {
00290
00291 mult(x, add(y, z)) == add(mult(x, y), mult(x, z));
00292
00293 mult(add(x, y), z) == add(mult(x, z), mult(y, z));
00294 }
00295 };
00296 #else
00297
00298
00330 template <typename AddOp, typename MultOp, typename Element>
00331 struct Distributive
00332 {};
00333 #endif
00334
00335
00336 #ifdef __GXX_CONCEPTS__
00337 auto concept Ring<typename AddOp, typename MultOp, typename Element>
00338 : AbelianGroup<AddOp, Element>,
00339 SemiGroup<MultOp, Element>,
00340 Distributive<AddOp, MultOp, Element>
00341 {};
00342 #else
00343
00344
00354 template <typename AddOp, typename MultOp, typename Element>
00355 struct Ring
00356 : AbelianGroup<AddOp, Element>,
00357 SemiGroup<MultOp, Element>,
00358 Distributive<AddOp, MultOp, Element>
00359 {};
00360 #endif
00361
00362
00363 #ifdef __GXX_CONCEPTS__
00364 auto concept RingWithIdentity<typename AddOp, typename MultOp, typename Element>
00365 : Ring<AddOp, MultOp, Element>,
00366 Monoid<MultOp, Element>
00367 {};
00368 #else
00369
00370
00379 template <typename AddOp, typename MultOp, typename Element>
00380 struct RingWithIdentity
00381 : Ring<AddOp, MultOp, Element>,
00382 Monoid<MultOp, Element>
00383 {};
00384 #endif
00385
00386
00387 #ifdef __GXX_CONCEPTS__
00388 concept DivisionRing<typename AddOp, typename MultOp, typename Element>
00389 : RingWithIdentity<AddOp, MultOp, Element>,
00390 Inversion<MultOp, Element>
00391 {
00392
00393 axiom ZeroIsDifferentFromOne(AddOp add, MultOp mult, Element x)
00394 {
00395 identity(add, x) != identity(mult, x);
00396 }
00397
00398
00399 axiom NonZeroDivisibility(AddOp add, MultOp mult, Element x)
00400 {
00401 if (x != identity(add, x))
00402 mult(inverse(mult, x), x) == identity(mult, x);
00403 if (x != identity(add, x))
00404 mult(x, inverse(mult, x)) == identity(mult, x);
00405 }
00406 };
00407 #else
00408
00409
00460 template <typename AddOp, typename MultOp, typename Element>
00461 struct DivisionRing
00462 : RingWithIdentity<AddOp, MultOp, Element>,
00463 Inversion<MultOp, Element>
00464 {};
00465 #endif
00466
00467
00468 #ifdef __GXX_CONCEPTS__
00469
00470 auto concept SkewField<typename AddOp, typename MultOp, typename Element>
00471 : DivisionRing<AddOp, MultOp, Element>
00472 {};
00473 #else
00474
00475
00486 template <typename AddOp, typename MultOp, typename Element>
00487 struct SkewField
00488 : DivisionRing<AddOp, MultOp, Element>
00489 {};
00490 #endif
00491
00492
00493 #ifdef __GXX_CONCEPTS__
00494 auto concept Field<typename AddOp, typename MultOp, typename Element>
00495 : DivisionRing<AddOp, MultOp, Element>,
00496 Commutative<MultOp, Element>
00497 {};
00498 #else
00499
00500
00509 template <typename AddOp, typename MultOp, typename Element>
00510 struct Field
00511 : DivisionRing<AddOp, MultOp, Element>,
00512 Commutative<MultOp, Element>
00513 {};
00514 #endif
00515
00517
00518 }
00519
00520 #endif // LA_ALGEBRAIC_CONCEPTS_DOC_INCLUDE