7#include "valkyrie/util/eigenunit/Common.h"
8#include "valkyrie/util/eigenunit/UnitVector.h"
22template <
typename OutputTagsTuple,
typename InputTagsTuple>
28template <
typename... OutTags,
typename... InTags>
32 using StorageType = Eigen::Matrix<double,
sizeof...(OutTags),
sizeof...(InTags)>;
38 static constexpr std::size_t RowCount =
sizeof...(OutTags);
39 static constexpr std::size_t ColCount =
sizeof...(InTags);
93 return UnitMatrix(StorageType::Constant(val.value()));
102 template <
typename... ColVecs>
107 ((d.col(i) = cols.Raw(), ++i), ...);
117 template <
typename... RowVecs>
122 ((d.row(i) = rows.Raw().transpose(), ++i), ...);
132 template <
typename... Args>
137 ((d(idx / ColCount, idx % ColCount) = args.value(), ++idx), ...);
141 template <
typename OutTuple,
typename InTuple,
typename... Args>
142 auto MakeMatrix(Args&&... args) {
158 template <
typename TL,
typename TR,
typename BL,
typename BR>
159 requires ValidBlockLayout<TL, TR, BL, BR, RowCount, ColCount>
162 d.template block<TL::RowCount, TL::ColCount>(0, 0) = tl.Raw();
163 d.template block<TR::RowCount, TR::ColCount>(0, TL::ColCount) = tr.Raw();
164 d.template block<BL::RowCount, BL::ColCount>(TL::RowCount, 0) = bl.Raw();
165 d.template block<BR::RowCount, BR::ColCount>(TL::RowCount, TL::ColCount) = br.Raw();
183 template <std::
size_t RowStart, std::
size_t ColStart, std::
size_t RowN, std::
size_t ColN>
190 using SubOutTuple =
typename Normalized::NormalizedOut;
191 using SubInTuple =
typename Normalized::NormalizedIn;
197 template <std::
size_t RowN, std::
size_t ColN>
203 template <std::
size_t RowN, std::
size_t ColN>
205 return Block<0, ColCount - ColN, RowN, ColN>();
209 template <std::
size_t RowN, std::
size_t ColN>
211 return Block<RowCount - RowN, 0, RowN, ColN>();
215 template <std::
size_t RowN, std::
size_t ColN>
217 return Block<RowCount - RowN, ColCount - ColN, RowN, ColN>();
227 using T = std::tuple_element_t<0, OutTuple>;
228 return units::unit_t<T>(data.trace());
232 template <
typename OtherOut,
typename OtherIn>
241 template <
typename OtherOut,
typename OtherIn>
254 template <
typename... VecTags>
259 return UnitVector<OutTags...>(data * vec.Raw());
268 template <
typename ScalarTag>
270 constexpr auto operator*(
const units::unit_t<ScalarTag>& scalar)
const {
271 using NewOutTuple = std::tuple<MultiplyResult<OutTags, ScalarTag>...>;
281 template <
typename ScalarTag>
283 constexpr auto operator/(
const units::unit_t<ScalarTag>& scalar)
const {
284 using NewOutTuple = std::tuple<DivideResult<OutTags, ScalarTag>...>;
309 template <
typename OtherOut,
typename OtherIn>
318 template <
typename OtherOut,
typename OtherIn>
327 template <
typename OtherOut,
typename OtherIn>
331 return data == other.Raw();
339 template <std::
size_t R>
341 constexpr auto Row()
const {
350 template <std::
size_t C>
352 constexpr auto Col()
const {
362 template <std::
size_t R, std::
size_t C>
365 using RowT = std::tuple_element_t<R, OutTuple>;
366 using ColT = std::tuple_element_t<C, InTuple>;
367 using ElemUnit = DivideResult<RowT, ColT>;
368 return units::unit_t<ElemUnit>(data(R, C));
377 template <std::
size_t R, std::
size_t C>
379 void Set(units::unit_t<DivideResult<std::tuple_element_t<R, OutTuple>, std::tuple_element_t<C, InTuple>>> val) {
380 data(R, C) = val.value();
412 return data.eigenvalues();
423 template <
typename... VecTags>
428 return UnitVector<InTags...>(data.partialPivLu().solve(b.Raw()));
439 template <
typename... B_InTags>
444 return UnitMatrix<
InTuple, std::tuple<B_InTags...>>(data.partialPivLu().solve(B.Raw()));
454 template <
typename... VecTags>
459 return UnitVector<InTags...>(data.colPivHouseholderQr().solve(b.Raw()));
468 template <
typename... B_InTags>
473 return UnitMatrix<
InTuple, std::tuple<B_InTags...>>(data.colPivHouseholderQr().solve(B.Raw()));
483 template <
typename... OtherOutTags,
typename... OtherInTags>
484 requires((
sizeof...(OtherOutTags) == RowCount) && (
sizeof...(OtherInTags) == ColCount))
487 using ResultOut = std::tuple<MultiplyResult<OutTags, OtherOutTags>...>;
488 using ResultIn = std::tuple<MultiplyResult<InTags, OtherInTags>...>;
501 return data.isApprox(other.Raw(), tol);
510 bool IsApprox(
const UnitMatrix& other, units::dimensionless::scalar_t tol = units::dimensionless::scalar_t{1e-9})
const
513 return data.IsApprox(other.Raw(), tol.value());
523 os <<
"UnitMatrix (\n";
524 mat.print_all_rows(os, std::make_index_sequence<RowCount>{});
530 template <std::size_t... Rows>
531 void print_all_rows(std::ostream& os, std::index_sequence<Rows...>)
const {
532 ((os <<
" [", print_row<Rows>(os, std::make_index_sequence<ColCount>{}), os <<
"]\n"), ...);
535 template <std::size_t Row, std::size_t... Cols>
536 void print_row(std::ostream& os, std::index_sequence<Cols...>)
const {
537 ((os << units::unit_t<DivideResult<std::tuple_element_t<Row, OutTuple>, std::tuple_element_t<Cols, InTuple>>>(data(Row, Cols))
538 << (Cols == ColCount - 1 ?
"" :
", ")),
555template <
typename... OutA,
typename... InA,
typename... OutB,
typename... InB>
557constexpr auto operator*(
const UnitMatrix<std::tuple<OutA...>, std::tuple<InA...>>& A,
558 const UnitMatrix<std::tuple<OutB...>, std::tuple<InB...>>& B)
559 requires UnitEquality<std::tuple<InA...>, std::tuple<OutB...>>
561 return UnitMatrix<std::tuple<OutA...>, std::tuple<InB...>>(A.Raw() * B.Raw());
569template <
typename... OutTags,
typename... InTags,
typename... VecTags>
572 requires std::is_same_v<std::tuple<OutTags...>,
typename ScalarTuple_Builder<
sizeof...(OutTags)>::type> &&
573 std::is_same_v<std::tuple<InTags...>,
typename ScalarTuple_Builder<
sizeof...(InTags)>::type> &&
574 (
sizeof...(InTags) ==
sizeof...(VecTags))
576 return UnitVector<VecTags...>(mat.Raw() * vec.Raw());
579template <
typename ScalarTag,
typename OutTuple,
typename InTuple>
585template <
typename OutTuple,
typename InTuple>
596template <
typename VecOut,
typename VecIn>
599template <
typename Derived,
typename Base>
600struct NamedPhysicalMatrix : Base {
603 NamedPhysicalMatrix(
const Base& base) : Base(base.Raw()) {}
605 Derived Inverse()
const {
return Derived(Base::Inverse()); }
607 template <std::
size_t RowStart, std::
size_t ColStart, std::
size_t RowN, std::
size_t ColN>
609 return Base::template Block<RowStart, ColStart, RowN, ColN>();
614template <
typename... UnitTags>
616 using Dimensionless = units::dimensionless::scalar_t;
A matrix wrapper representing a linear map between two UnitVectors.
Definition UnitMatrix.h:23
A vector wrapper that enforces units for each element.
Definition UnitVector.h:22
auto AsDiagonal() const
Converts the vector to a diagonal matrix.
Definition UnitMatrix.h:615
Checks that a pack of column vectors all match the output tuple.
Definition Common.h:275
Concept verifying that a UnitMatrix is square AND has matching units for rows and columns.
Definition Common.h:237
Concept verifying that a UnitMatrix is square.
Definition Common.h:228
Concept verifying that two tuple-based unit types match exactly.
Definition Common.h:216
Concept verifying that a pack of arguments matches the required units for a UnitMatrix.
Definition Common.h:315
Concept verifying that index N is within the bounds of a pack.
Definition Common.h:192
Template specializations for std::tuple_size and std::tuple_element to support UnitVector.
Definition Formatters.h:8
typename impl< std::make_index_sequence< Length > >::type type
The resulting sliced tuple type.
Definition Common.h:45
Builder for N-dimensional UnitVectors with uniform units.
Definition Common.h:126