File indexing completed on 2025-09-17 08:54:10
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <cstddef>
0010 #include <iostream>
0011
0012 #include <covfie/core/algebra/affine.hpp>
0013 #include <covfie/core/algebra/vector.hpp>
0014 #include <covfie/core/concepts.hpp>
0015 #include <covfie/core/parameter_pack.hpp>
0016 #include <covfie/core/qualifiers.hpp>
0017 #include <covfie/core/utility/binary_io.hpp>
0018
0019 namespace covfie::backend {
0020 template <concepts::field_backend _backend_t>
0021 struct affine {
0022 using this_t = affine<_backend_t>;
0023 static constexpr bool is_initial = false;
0024
0025 using backend_t = _backend_t;
0026
0027 using contravariant_input_t = typename backend_t::contravariant_input_t;
0028 using contravariant_output_t = typename backend_t::contravariant_input_t;
0029 using covariant_input_t = typename backend_t::covariant_output_t;
0030 using covariant_output_t = typename backend_t::covariant_output_t;
0031
0032 using matrix_t = algebra::affine<
0033 contravariant_input_t::dimensions,
0034 typename contravariant_input_t::scalar_t>;
0035
0036 struct owning_data_t;
0037
0038 using configuration_t = matrix_t;
0039
0040 static constexpr uint32_t IO_MAGIC_HEADER = 0xAB020000;
0041
0042 struct owning_data_t {
0043 using parent_t = this_t;
0044
0045 owning_data_t() = default;
0046 owning_data_t(const owning_data_t &) = default;
0047 owning_data_t(owning_data_t &&) = default;
0048 owning_data_t & operator=(const owning_data_t &) = default;
0049 owning_data_t & operator=(owning_data_t &&) = default;
0050
0051 template <typename... Args>
0052 explicit owning_data_t(parameter_pack<configuration_t, Args...> && args)
0053 : m_transform(args.x)
0054 , m_backend(std::move(args.xs))
0055 {
0056 }
0057
0058 explicit owning_data_t(parameter_pack<owning_data_t> && conf)
0059 : owning_data_t(std::move(conf.x))
0060 {
0061 }
0062
0063 template <typename T>
0064 requires(std::same_as<
0065 typename T::parent_t::configuration_t,
0066 configuration_t>) explicit owning_data_t(const T & o)
0067 : m_transform(o.m_transform)
0068 , m_backend(o.m_backend)
0069 {
0070 }
0071
0072 explicit owning_data_t(
0073 const configuration_t & c, typename backend_t::owning_data_t && b
0074 )
0075 : m_transform(c)
0076 , m_backend(std::forward<typename backend_t::owning_data_t>(b))
0077 {
0078 }
0079
0080 typename backend_t::owning_data_t & get_backend(void)
0081 {
0082 return m_backend;
0083 }
0084
0085 const typename backend_t::owning_data_t & get_backend(void) const
0086 {
0087 return m_backend;
0088 }
0089
0090 configuration_t get_configuration(void) const
0091 {
0092 return m_transform;
0093 }
0094
0095 static owning_data_t read_binary(std::istream & fs)
0096 {
0097 utility::read_io_header(fs, IO_MAGIC_HEADER);
0098
0099 configuration_t trans = utility::read_binary<configuration_t>(fs);
0100 typename backend_t::owning_data_t be =
0101 backend_t::owning_data_t::read_binary(fs);
0102
0103 utility::read_io_footer(fs, IO_MAGIC_HEADER);
0104
0105 return owning_data_t(trans, std::move(be));
0106 }
0107
0108 static void write_binary(std::ostream & fs, const owning_data_t & o)
0109 {
0110 utility::write_io_header(fs, IO_MAGIC_HEADER);
0111
0112 fs.write(
0113 reinterpret_cast<const char *>(&o.m_transform),
0114 sizeof(decltype(o.m_transform))
0115 );
0116
0117 backend_t::owning_data_t::write_binary(fs, o.m_backend);
0118
0119 utility::write_io_footer(fs, IO_MAGIC_HEADER);
0120 }
0121
0122 matrix_t m_transform;
0123 typename backend_t::owning_data_t m_backend;
0124 };
0125
0126 struct non_owning_data_t {
0127 using parent_t = this_t;
0128
0129 non_owning_data_t(const owning_data_t & src)
0130 : m_transform(src.m_transform)
0131 , m_backend(src.m_backend)
0132 {
0133 }
0134
0135 COVFIE_HOST_DEVICE typename covariant_output_t::vector_t
0136 at(typename contravariant_input_t::vector_t c) const
0137 {
0138 covfie::algebra::vector<
0139 contravariant_input_t::dimensions,
0140 typename contravariant_input_t::scalar_t>
0141 v;
0142
0143 for (std::size_t i = 0; i < contravariant_output_t::dimensions; ++i)
0144 {
0145 v(i) = c[i];
0146 }
0147
0148 covfie::algebra::vector<
0149 contravariant_input_t::dimensions,
0150 typename contravariant_input_t::scalar_t>
0151 nv = m_transform * v;
0152
0153 typename contravariant_output_t::vector_t nc;
0154
0155 for (std::size_t i = 0; i < contravariant_output_t::dimensions; ++i)
0156 {
0157 nc[i] = nv(i);
0158 }
0159
0160 return m_backend.at(nc);
0161 }
0162
0163 typename backend_t::non_owning_data_t & get_backend(void)
0164 {
0165 return m_backend;
0166 }
0167
0168 const typename backend_t::non_owning_data_t & get_backend(void) const
0169 {
0170 return m_backend;
0171 }
0172
0173 matrix_t m_transform;
0174 typename backend_t::non_owning_data_t m_backend;
0175 };
0176 };
0177 }