Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
vector_space.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <type_traits>
7#include <utility>
8
9namespace uni20::krylov
10{
19template <RealOrComplex S, class Ops, class Prototype>
20 requires(!std::is_reference_v<Prototype>) &&
21 KrylovVectorOps<Ops, decltype(std::declval<Ops&>().allocate_like(std::declval<Prototype const&>())), S>
23{
24 using scalar_type = S;
26 using prototype_type = Prototype;
27 using vector_type = decltype(std::declval<Ops&>().allocate_like(std::declval<Prototype const&>()));
28 Ops& ops;
29 Prototype prototype;
31
32 void validate() const
33 {
34 require_precision<S>(precision);
35 (void)precision.bit_count();
36 if (ops.vector_dimension(prototype) != ops.problem_dimension())
37 throw std::invalid_argument("Krylov prototype does not belong to the vector space");
38 }
39};
40
45template <RealOrComplex S, class Ops, class V>
46 requires requires(Ops& ops, V&& source) { ops.prototype_view(std::forward<V>(source)); }
47auto krylov_space(Ops& ops, V&& source, Precision p)
48{
49 using prototype_type = decltype(ops.prototype_view(std::forward<V>(source)));
50 KrylovVectorSpace<S, Ops, prototype_type> space{ops, ops.prototype_view(std::forward<V>(source)), p};
51 space.validate();
52 return space;
53}
54
56template <RealOrComplex S, class Ops, class V>
57 requires(!has_runtime_precision_v<S>) &&
58 requires(Ops& ops, V&& source) { ops.prototype_view(std::forward<V>(source)); }
59auto krylov_space(Ops& ops, V&& source)
60{
61 return krylov_space<S>(ops, std::forward<V>(source), native_precision<S>());
62}
63
64namespace gmres_detail
65{
66// Scalar conversion for explicit workspace boundaries, including complex
67// components and native extension types not covered by std::complex constructors.
68template <RealOrComplex To, RealOrComplex From>
69 requires(Complex<To> == Complex<From>)
71{
72 require_precision<To>(p);
73 if constexpr (Complex<To>)
75 convert_scalar<make_real_t<To>>(uni20::imag(value), p));
76 else if constexpr (has_runtime_precision_v<To>)
77 return scalar_at_precision<To>(value, p);
78 else
79 return static_cast<To>(value);
80}
81} // namespace gmres_detail
82} // namespace uni20::krylov
Exact arithmetic or an explicit binary working precision.
Definition core/precision.hpp:13
constexpr bit_count_type bit_count() const
Number of binary significand bits.
Definition core/precision.hpp:43
Concept for complex scalar types.
Definition scalar_concepts.hpp:75
locale_t value
Definition data_table.cpp:49
constexpr T & imag(detail::standard_complex< T > &z) noexcept
Provides mutable access to the imaginary component of a uni20::complex value.
Definition math.hpp:184
typename make_real< T >::type make_real_t
Alias for the underlying real-valued type of T.
Definition scalar_traits.hpp:168
constexpr T & real(detail::standard_complex< T > &z) noexcept
Provides mutable access to the real component of a uni20::complex value.
Definition math.hpp:173
To convert_scalar(From const &value, Precision p)
Definition vector_space.hpp:70
Definition block_tensor_vector.hpp:23
auto krylov_space(Ops &ops, V &&source, Precision p)
Bind vector operations and an allocation prototype to finite precision.
Definition vector_space.hpp:47
Definition data_table.cpp:8
An opaque vector space with one explicit arithmetic precision.
Definition vector_space.hpp:23
Ops & ops
Definition vector_space.hpp:28
void validate() const
Definition vector_space.hpp:32
S scalar_type
Definition vector_space.hpp:24
Precision precision
Definition vector_space.hpp:30
decltype(std::declval< Ops & >().allocate_like(std::declval< Prototype const & >())) vector_type
Definition vector_space.hpp:27
Prototype prototype_type
Definition vector_space.hpp:26
Prototype prototype
Definition vector_space.hpp:29
make_real_t< S > real_type
Definition vector_space.hpp:25