6#include <valkyrie/util/eigenunit/Common.h>
7#include <valkyrie/util/eigenunit/UnitVector.h>
21template <
typename OutputTagsTuple,
typename InputTagsTuple>
27template <
typename... OutTags,
typename... InTags>
31 using StorageType = Eigen::Matrix<double,
sizeof...(OutTags),
sizeof...(InTags)>;
37 static constexpr std::size_t RowCount =
sizeof...(OutTags);
38 static constexpr std::size_t ColCount =
sizeof...(InTags);
92 return UnitMatrix(StorageType::Constant(val.value()));
101 template <
typename... ColVecs>
106 ((d.col(i) = cols.Raw(), ++i), ...);
116 template <
typename... RowVecs>
121 ((d.row(i) = rows.Raw().transpose(), ++i), ...);
131 template <
typename... Args>
136 ((d(idx / ColCount, idx % ColCount) = args.value(), ++idx), ...);
140 template <
typename OutTuple,
typename InTuple,
typename... Args>
141 auto MakeMatrix(Args&&... args) {
157 template <
typename TL,
typename TR,
typename BL,
typename BR>
158 requires ValidBlockLayout<TL, TR, BL, BR, RowCount, ColCount>
161 d.template block<TL::RowCount, TL::ColCount>(0, 0) = tl.Raw();
162 d.template block<TR::RowCount, TR::ColCount>(0, TL::ColCount) = tr.Raw();
163 d.template block<BL::RowCount, BL::ColCount>(TL::RowCount, 0) = bl.Raw();
164 d.template block<BR::RowCount, BR::ColCount>(TL::RowCount, TL::ColCount) = br.Raw();
182 template <std::
size_t RowStart, std::
size_t ColStart, std::
size_t RowN, std::
size_t ColN>
189 using SubOutTuple =
typename Normalized::NormalizedOut;
190 using SubInTuple =
typename Normalized::NormalizedIn;
196 template <std::
size_t RowN, std::
size_t ColN>
202 template <std::
size_t RowN, std::
size_t ColN>
204 return Block<0, ColCount - ColN, RowN, ColN>();
208 template <std::
size_t RowN, std::
size_t ColN>
210 return Block<RowCount - RowN, 0, RowN, ColN>();
214 template <std::
size_t RowN, std::
size_t ColN>
216 return Block<RowCount - RowN, ColCount - ColN, RowN, ColN>();
226 using T = std::tuple_element_t<0, OutTuple>;
227 return units::unit_t<T>(data.trace());
231 template <
typename OtherOut,
typename OtherIn>
240 template <
typename OtherOut,
typename OtherIn>
253 template <
typename... VecTags>
258 return UnitVector<OutTags...>(data * vec.Raw());
267 template <
typename ScalarTag>
269 constexpr auto operator*(
const units::unit_t<ScalarTag>& scalar)
const {
270 using NewOutTuple = std::tuple<MultiplyResult<OutTags, ScalarTag>...>;
280 template <
typename ScalarTag>
282 constexpr auto operator/(
const units::unit_t<ScalarTag>& scalar)
const {
283 using NewOutTuple = std::tuple<DivideResult<OutTags, ScalarTag>...>;
308 template <
typename OtherOut,
typename OtherIn>
317 template <
typename OtherOut,
typename OtherIn>
326 template <
typename OtherOut,
typename OtherIn>
330 return data == other.Raw();
338 template <std::
size_t R>
340 constexpr auto Row()
const {
349 template <std::
size_t C>
351 constexpr auto Col()
const {
361 template <std::
size_t R, std::
size_t C>
364 using RowT = std::tuple_element_t<R, OutTuple>;
365 using ColT = std::tuple_element_t<C, InTuple>;
366 using ElemUnit = DivideResult<RowT, ColT>;
367 return units::unit_t<ElemUnit>(data(R, C));
376 template <std::
size_t R, std::
size_t C>
378 void Set(units::unit_t<DivideResult<std::tuple_element_t<R, OutTuple>, std::tuple_element_t<C, InTuple>>> val) {
379 data(R, C) = val.value();
411 return data.eigenvalues();
422 template <
typename... VecTags>
427 return UnitVector<InTags...>(data.partialPivLu().solve(b.Raw()));
438 template <
typename... B_InTags>
443 return UnitMatrix<
InTuple, std::tuple<B_InTags...>>(data.partialPivLu().solve(B.Raw()));
453 template <
typename... VecTags>
458 return UnitVector<InTags...>(data.colPivHouseholderQr().solve(b.Raw()));
467 template <
typename... B_InTags>
472 return UnitMatrix<
InTuple, std::tuple<B_InTags...>>(data.colPivHouseholderQr().solve(B.Raw()));
482 template <
typename... OtherOutTags,
typename... OtherInTags>
483 requires((
sizeof...(OtherOutTags) == RowCount) && (
sizeof...(OtherInTags) == ColCount))
486 using ResultOut = std::tuple<MultiplyResult<OutTags, OtherOutTags>...>;
487 using ResultIn = std::tuple<MultiplyResult<InTags, OtherInTags>...>;
500 return data.isApprox(other.Raw(), tol);
509 bool IsApprox(
const UnitMatrix& other, units::dimensionless::scalar_t tol = units::dimensionless::scalar_t{1e-9})
const
512 return data.IsApprox(other.Raw(), tol.value());
522 os <<
"UnitMatrix (\n";
523 mat.print_all_rows(os, std::make_index_sequence<RowCount>{});
529 template <std::size_t... Rows>
530 void print_all_rows(std::ostream& os, std::index_sequence<Rows...>)
const {
531 ((os <<
" [", print_row<Rows>(os, std::make_index_sequence<ColCount>{}), os <<
"]\n"), ...);
534 template <std::size_t Row, std::size_t... Cols>
535 void print_row(std::ostream& os, std::index_sequence<Cols...>)
const {
536 ((os << units::unit_t<DivideResult<std::tuple_element_t<Row, OutTuple>, std::tuple_element_t<Cols, InTuple>>>(data(Row, Cols))
537 << (Cols == ColCount - 1 ?
"" :
", ")),
554template <
typename... OutA,
typename... InA,
typename... OutB,
typename... InB>
556constexpr auto operator*(
const UnitMatrix<std::tuple<OutA...>, std::tuple<InA...>>& A,
557 const UnitMatrix<std::tuple<OutB...>, std::tuple<InB...>>& B)
558 requires UnitEquality<std::tuple<InA...>, std::tuple<OutB...>>
560 return UnitMatrix<std::tuple<OutA...>, std::tuple<InB...>>(A.Raw() * B.Raw());
568template <
typename... OutTags,
typename... InTags,
typename... VecTags>
571 requires std::is_same_v<std::tuple<OutTags...>,
typename ScalarTuple_Builder<
sizeof...(OutTags)>::type> &&
572 std::is_same_v<std::tuple<InTags...>,
typename ScalarTuple_Builder<
sizeof...(InTags)>::type> &&
573 (
sizeof...(InTags) ==
sizeof...(VecTags))
575 return UnitVector<VecTags...>(mat.Raw() * vec.Raw());
578template <
typename ScalarTag,
typename OutTuple,
typename InTuple>
584template <
typename OutTuple,
typename InTuple>
595template <
typename VecOut,
typename VecIn>
598template <
typename Derived,
typename Base>
599struct NamedPhysicalMatrix : Base {
602 NamedPhysicalMatrix(
const Base& base) : Base(base.Raw()) {}
604 Derived Inverse()
const {
return Derived(Base::Inverse()); }
606 template <std::
size_t RowStart, std::
size_t ColStart, std::
size_t RowN, std::
size_t ColN>
608 return Base::template Block<RowStart, ColStart, RowN, ColN>();
613template <
typename... UnitTags>
615 using Dimensionless = units::dimensionless::scalar_t;
A matrix wrapper representing a linear map between two UnitVectors.
Definition UnitMatrix.h:22
A vector wrapper that enforces units for each element.
Definition UnitVector.h:21
auto AsDiagonal() const
Converts the vector to a diagonal matrix.
Definition UnitMatrix.h:614
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