5 #include <eigen3/Eigen/Geometry> 9 #include <vnix/units.hpp> 15 using std::index_sequence;
16 using std::make_index_sequence;
24 template <
typename T,
typename OT, size_t N>
25 constexpr T
cnv_el(array<OT, N>
const &a, size_t i) {
30 template <
typename T,
typename OT, size_t... i>
31 constexpr auto _cnv(array<OT,
sizeof...(i)>
const &a, index_sequence<i...>) {
32 return array<T,
sizeof...(i)>{{cnv_el<T>(a, i)...}};
36 template <
typename T,
typename OT, size_t N>
37 constexpr auto cnv_ar(array<OT, N>
const &a) {
38 return _cnv<T>(a, make_index_sequence<N>{});
43 template <
typename T, size_t S, size_t N>
class mref {
48 constexpr static size_t
size() {
return N; }
53 constexpr T *
end() {
return beg_ + S * N; }
57 auto i = list.begin();
61 while (i != ie && j != je) {
69 constexpr static size_t
stride() {
return S; }
72 constexpr T &
operator()(size_t off)
const {
return beg_[S * off]; }
76 template <
typename T1,
typename T2, size_t S1, size_t S2, size_t N>
77 constexpr auto dot(
mref<T1, S1, N>
const &mr1,
mref<T2, S2, N>
const &mr2) {
78 auto sum = 0 * mr1(0) * mr2(0);
79 for (size_t i = 0; i < N; ++i) { sum += mr1(i) * mr2(i); }
85 template <
typename T, size_t NR, size_t NC>
struct mat {
94 template <
typename... X>
constexpr mat(X... xs) :
a({T(xs)...}) {}
97 template <
typename OT>
98 constexpr mat(mat<OT, NR, NC>
const &m) :
a(cnv_ar<T>(m.a)) {}
101 constexpr auto col(size_t off)
const {
102 return mref<T
const, NC, NR>(
a.data() + off);
106 constexpr auto col(size_t off) {
107 using RT =
typename std::remove_const<T>::type;
108 return mref<RT, NC, NR>(
a.data() + off);
112 constexpr auto row(size_t off)
const {
113 return mref<T
const, 1, NC>(
a.data() + NC * off);
117 constexpr auto row(size_t off) {
118 using RT =
typename std::remove_const<T>::type;
119 return mref<RT, 1, NC>(
a.data() + NC * off);
124 template <
typename T, size_t NR>
using col = mat<T, NR, 1>;
127 template <
typename T, size_t NC>
using row = mat<T, 1, NC>;
130 template <
typename T1,
typename T2, size_t NR1, size_t NC2, size_t N>
131 constexpr auto operator*(mat<T1, NR1, N>
const &m1,
132 mat<T2, N, NC2>
const &m2) {
133 using TT =
decltype(dot(m1.row(0), m2.col(0)));
134 using TP =
typename std::remove_const<TT>::type;
135 mat<TP, NR1, NC2> pr;
136 for (size_t i = 0; i < NR1; ++i) {
137 auto const m1_rowi = m1.row(i);
138 auto pr_rowi = pr.row(i);
139 for (size_t j = 0; j < NC2; ++j) { pr_rowi(j) = dot(m1_rowi, m2.col(j)); }
145 template <
typename T1,
typename T2, size_t NR2, size_t NC2>
146 constexpr auto operator*(T1
const &s1, mat<T2, NR2, NC2>
const &m2) {
147 mat<
decltype(s1 * m2.row(0)(0)), NR2, NC2> pr;
148 for (size_t i = 0; i < NR2; ++i) {
149 auto const m2_rowi = m2.row(i);
150 auto pr_rowi = pr.row(i);
151 for (size_t j = 0; j < NC2; ++j) { pr_rowi(j) = s1 * m2_rowi(j); }
157 template <
typename T, size_t NR, size_t NC>
158 ostream &operator<<(ostream &os, mat<T, NR, NC>
const &m) {
159 for (size_t i = 0; i < NR; ++i) {
160 auto const rowi = m.row(i);
162 for (size_t j = 0; j < NC; ++j) { os << rowi(j) <<
" "; }
178 col<
double, 3> v({0.3, 0.2, 0.1});
181 cout << (f * d) << endl;
182 }
catch (
char const *e) { cerr << e << endl; }
191 f2
.row(0
) = {1.0_N, 2.0_N, 3.0_N};
192 f2
.row(1
) = {4.0_N, 5.0_N, 6.0_N};
193 f2
.row(2
) = {7.0_N, 8.0_N, 9.0_N};
194 col<length, 3> d2({0.3_km, 0.2_km, 0.1_km});
195 cout << (f2
* d2) << endl;
196 }
catch (
char const *e) { cerr << e << endl; }
201 using namespace Eigen;
204 AngleAxisf r(M_PI / 6, Vector3f(0, 0, 1));
205 auto f = newtons(Vector3f(1, 0, 0));
206 auto d = meters(Vector3f(0, 1, 0));
207 auto v = d / (2.5_s);
209 cout << (r.toRotationMatrix() * f).cross(d + v * t) << endl;
210 }
catch (
char const *e) { cerr << e << endl; }
constexpr auto operator*(mat< T1, NR1, N > const &m1, mat< T2, N, NC2 > const &m2)
Multiply two matrices.
constexpr auto row(size_t off)
Reference to mutable row.
array< T, NR *NC > a
Array in which quantities are stored.
constexpr mat(X...xs)
Initialize from list.
constexpr auto kilometers(T v)
Produce dimensioned quantity from number of kilometers.
constexpr T cnv_el(array< OT, N > const &a, size_t i)
Convert element i of array a from type OT to type T.
constexpr auto col(size_t off) const
Reference to immutable column.
Single-precision dimensions and units.
T * beg_
Pointer to first element.
constexpr auto operator*(T1 const &s1, mat< T2, NR2, NC2 > const &m2)
Multiply matrix on left by scalar.
constexpr mat(mat< OT, NR, NC > const &m)
Copy from same-size matrix of other element-type OT.
constexpr auto row(size_t off) const
Reference to immutable row.
constexpr T & operator()(size_t off) const
Access element at offset off.
friend std::ostream & operator<<(std::ostream &s, basic_dim d)
Print to to output stream.
constexpr auto _cnv(array< OT, sizeof...(i)> const &a, index_sequence< i... >)
Convert array of elements of type OT to array of elements of type T.
constexpr mref(T *b)
Initialize aggregate.
constexpr T * end()
Pointer to element that is S elements past last element identified by mref.
constexpr mref & operator=(std::initializer_list< T > list)
Assign from list.
constexpr auto dot(mref< T1, S1, N > const &mr1, mref< T2, S2, N > const &mr2)
Dot-product of two mrefs.
Reference to column or row in matrix.
constexpr auto cnv_ar(array< OT, N > const &a)
Convert array of elements of type OT to array of elements of type T.
constexpr auto col(size_t off)
Reference to mutable column.
static constexpr size_t size()
Number of elements.
static constexpr size_t stride()
Distance in memory between successive elements.
Thomas E. Vaughan's public software.
Classes and functions supporting a model of physically dimensioned quantities.
constexpr auto newtons(T v)
Produce dimensioned quantity from number of newtons.
constexpr T * begin()
First element.