00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef LA_VECTOR_CONCEPTS_INCLUDE
00014 #define LA_VECTOR_CONCEPTS_INCLUDE
00015
00016
00017 #include <boost/numeric/linear_algebra/concepts.hpp>
00018 #include <boost/numeric/linear_algebra/ets_concepts.hpp>
00019
00020 #ifdef __GXX_CONCEPTS__
00021 # include <concepts>
00022 #else
00023 # include <boost/numeric/linear_algebra/pseudo_concept.hpp>
00024 #endif
00025
00026
00027 namespace math {
00028
00033 #ifdef __GXX_CONCEPTS__
00034 concept VectorSpace<typename Vector, typename Scalar = typename Vector::value_type>
00035 : AdditiveAbelianGroup<Vector>
00036 {
00037 requires Field<Scalar>;
00038 requires Multiplicable<Scalar, Vector>;
00039 requires MultiplicableWithAssign<Vector, Scalar>;
00040 requires DivisibleWithAssign<Vector, Scalar>;
00041
00042 requires std::Assignable<Vector, Multiplicable<Scalar, Vector>::result_type>;
00043 requires std::Assignable<Vector, Multiplicable<Vector, Scalar>::result_type>;
00044 requires std::Assignable<Vector, Divisible<Vector, Scalar>::result_type>;
00045
00046
00047
00048
00049
00050 axiom Distributivity(Vector v, Vector w, Scalar a, Scalar b)
00051 {
00052 a * (v + w) == a * v + a * w;
00053 (a + b) * v == a * v + b * v;
00054
00055
00056 (v + w) * a == v * a + w * a;
00057 v * (a + b) == v * a + v * b;
00058 }
00059 }
00060 #else
00061
00062
00076 template <typename Vector, typename Scalar = typename Vector::value_type>
00077 struct VectorSpace
00078 : AdditiveAbelianGroup<Vector>
00079 {
00081 axiom Distributivity(Vector v, Vector w, Scalar a, Scalar b)
00082 {
00084
00086
00088
00090 }
00091 };
00092 #endif
00093
00094 #ifdef __GXX_CONCEPTS__
00095 concept Norm<typename N, typename Vector,
00096 typename Scalar = typename Vector::value_type>
00097 : std::Callable1<N, Vector>
00098 {
00099 requires VectorSpace<Vector, Scalar>;
00100 requires RealMagnitude<Scalar>;
00101 typename magnitude_type = MagnitudeType<Scalar>::type;
00102 requires std::Convertible<magnitude_type, Scalar>;
00103
00104 typename result_type_norm = std::Callable1<N, Vector>::result_type;
00105 requires std::Convertible<result_type_norm, RealMagnitude<Scalar>::magnitude_type>;
00106 requires std::Convertible<result_type_norm, Scalar>;
00107
00108
00109
00110 #if 0
00111 typename result_type_norm;
00112 result_type_norm norm(const Vector&);
00113 requires std::Convertible<result_type_norm, magnitude_type>;
00114 requires std::Convertible<result_type_norm, Scalar>;
00115 #endif
00116
00117 axiom Positivity(N norm, Vector v, magnitude_type ref)
00118 {
00119 norm(v) >= zero(ref);
00120 }
00121
00122
00123
00124
00125
00126
00127 axiom PositiveHomogeneity(N norm, Vector v, Scalar a)
00128 {
00129 norm(a * v) == abs(a) * norm(v);
00130 }
00131
00132 axiom TriangleInequality(N norm, Vector u, Vector v)
00133 {
00134 norm(u + v) <= norm(u) + norm(v);
00135 }
00136 }
00137 #else
00138
00139
00161 template <typename N, typename Vector,
00162 typename Scalar = typename Vector::value_type>
00163 struct Norm
00164 : std::Callable1<N, Vector>
00165 {
00167
00168 typedef associated_type magnitude_type;
00169
00171
00172 typedef associated_type result_type_norm;
00173
00175 axiom Positivity(N norm, Vector v, magnitude_type ref)
00176 {
00178 }
00179
00181 axiom PositiveHomogeneity(N norm, Vector v, Scalar a)
00182 {
00184 }
00185
00187 axiom TriangleInequality(N norm, Vector u, Vector v)
00188 {
00190 }
00191 };
00192 #endif
00193
00194
00195 #ifdef __GXX_CONCEPTS__
00196 concept SemiNorm<typename N, typename Vector,
00197 typename Scalar = typename Vector::value_type>
00198 : Norm<N, Vector, Scalar>
00199 {
00200 axiom PositiveDefiniteness(N norm, Vector v, magnitude_type ref)
00201 {
00202 if (norm(v) == zero(ref))
00203 v == zero(v);
00204 if (v == zero(v))
00205 norm(v) == zero(ref);
00206 }
00207 }
00208 #else
00209
00210
00220 template <typename N, typename Vector,
00221 typename Scalar = typename Vector::value_type>
00222 struct SemiNorm
00223 : Norm<N, Vector, Scalar>
00224 {
00226 axiom PositiveDefiniteness(N norm, Vector v, magnitude_type ref)
00227 {
00229
00231 }
00232 };
00233 #endif
00234
00235 #ifdef __GXX_CONCEPTS__
00236 concept BanachSpace<typename N, typename Vector,
00237 typename Scalar = typename Vector::value_type>
00238 : Norm<N, Vector, Scalar>,
00239 VectorSpace<Vector, Scalar>
00240 {};
00241 #else
00242
00243
00262 template <typename N, typename Vector,
00263 typename Scalar = typename Vector::value_type>
00264 struct BanachSpace
00265 : Norm<N, Vector, Scalar>,
00266 VectorSpace<Vector, Scalar>
00267 {};
00268 #endif
00269
00270
00271 #ifdef __GXX_CONCEPTS__
00272 concept InnerProduct<typename I, typename Vector,
00273 typename Scalar = typename Vector::value_type>
00274 : std::Callable2<I, Vector, Vector>
00275 {
00276
00277 requires std::Convertible<std::Callable2<I, Vector, Vector>::result_type, Scalar>;
00278
00279
00280
00281
00282 requires HasConjugate<Scalar>;
00283
00284 axiom ConjugateSymmetry(I inner, Vector v, Vector w)
00285 {
00286 inner(v, w) == conj(inner(w, v));
00287 }
00288
00289 axiom SequiLinearity(I inner, Scalar a, Scalar b, Vector u, Vector v, Vector w)
00290 {
00291 inner(v, b * w) == b * inner(v, w);
00292 inner(u, v + w) == inner(u, v) + inner(u, w);
00293
00294 inner(a * v, w) == conj(a) * inner(v, w);
00295 inner(u + v, w) == inner(u, w) + inner(v, w);
00296 }
00297
00298 requires RealMagnitude<Scalar>;
00299 typename magnitude_type = RealMagnitude<Scalar>::type;
00300
00301
00302 axiom NonNegativity(I inner, Vector v, MagnitudeType<Scalar>::type magnitude)
00303 {
00304
00305
00306 magnitude_type(inner(v, v)) >= zero(magnitude)
00307 }
00308
00309 axiom NonDegeneracy(I inner, Vector v, Vector w, Scalar s)
00310 {
00311 if (v == zero(v))
00312 inner(v, w) == zero(s);
00313 if (inner(v, w) == zero(s))
00314 v == zero(v);
00315 }
00316 };
00317 #else
00318
00319
00338 template <typename I, typename Vector,
00339 typename Scalar = typename Vector::value_type>
00340 struct InnerProduct
00341 : std::Callable2<I, Vector, Vector>
00342 {
00344
00345 typename associated_type magnitude_type;
00346
00347
00349 axiom ConjugateSymmetry(I inner, Vector v, Vector w)
00350 {
00352 }
00353
00355
00356 axiom SequiLinearity(I inner, Scalar a, Scalar b, Vector u, Vector v, Vector w)
00357 {
00359
00361
00363
00365 }
00366
00368
00369 axiom NonNegativity(I inner, Vector v, MagnitudeType<Scalar>::type magnitude)
00370 {
00372 }
00373
00375 axiom NonDegeneracy(I inner, Vector v, Vector w, Scalar s)
00376 {
00378 }
00379 };
00380 #endif
00381
00382
00383
00384
00385 #ifdef __GXX_CONCEPTS_
00386
00387
00388 concept DotProduct<typename I, typename Vector,
00389 typename Scalar = typename Vector::value_type>
00390 : InnerProduct<I, Vector, Scalar>
00391 {};
00392 #else
00393
00394
00404 template <typename I, typename Vector,
00405 typename Scalar = typename Vector::value_type>
00406 struct DotProduct
00407 : InnerProduct<I, Vector, Scalar>
00408 {};
00409 #endif
00410
00411
00412
00413
00414
00415
00416
00417
00418 template <typename I, typename Vector,
00419 typename Scalar = typename Vector::value_type>
00420 _GLIBCXX_WHERE(InnerProduct<I, Vector, Scalar>
00421 && RealMagnitude<Scalar>)
00422 struct induced_norm_t
00423 {
00424
00425 typename magnitude_type_trait<Scalar>::type
00426 operator() (const I& inner, const Vector& v)
00427 {
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 typedef typename magnitude_type_trait<Scalar>::type magnitude_type;
00438 return sqrt(static_cast<magnitude_type> (inner(v, v)));
00439 }
00440 };
00441
00442
00443 #if 0
00444 template <typename I, typename Vector,
00445 typename Scalar = typename Vector::value_type>
00446 LA_WHERE( InnerProduct<I, Vector, Scalar>
00447 && RealMagnitude<Scalar> )
00448 magnitude_type_trait<Scalar>::type
00449 induced_norm(const I& inner, const Vector& v)
00450 {
00451 return induced_norm_t<I, Vector, Scalar>() (inner, v);
00452 }
00453 #endif
00454
00455 #ifdef __GXX_CONCEPTS__
00456
00457
00458 concept HilbertSpace<typename I, typename Vector,
00459 typename Scalar = typename Vector::value_type,
00460 typename N = induced_norm_t<I, Vector, Scalar> >
00461 : InnerProduct<I, Vector, Scalar>,
00462 BanachSpace<N, Vector, Scalar>
00463 {
00464 axiom Consistency(Vector v)
00465 {
00466 math::induced_norm_t<I, Vector, Scalar>()(v) == N()(v);
00467 }
00468 };
00469 #else
00470
00471
00488 template <typename I, typename Vector,
00489 typename Scalar = typename Vector::value_type,
00490 typename N = induced_norm_t<I, Vector, Scalar> >
00491 struct HilbertSpace
00492 : InnerProduct<I, Vector, Scalar>,
00493 BanachSpace<N, Vector, Scalar>
00494 {
00496 axiom Consistency(Vector v)
00497 {
00499 }
00500 };
00501 #endif // __GXX_CONCEPTS__
00502
00504
00505 }
00506
00507 #endif // LA_VECTOR_CONCEPTS_INCLUDE