1#ifndef PHYTH_MATRIX_HPP
2#define PHYTH_MATRIX_HPP
14 template<std::
size_t Row, std::
size_t Col,
typename T>
17 static_assert(
Row > 0 &&
Col > 0,
"Matrix dimensions must be positive");
24 template<
typename...
Args,
26 sizeof...(Args) ==
Col &&
31 template<
typename...
Args,
33 sizeof...(Args) ==
Row *
Col &&
34 std::conjunction_v<std::is_convertible<Args, T>...>,
37 :
Matrix(std::array<T, Row * Col>{
static_cast<T>(
elems)...},
38 std::make_index_sequence<Col>{}) {}
41 static_assert(
Row ==
Col,
"Identity matrix requires a square matrix");
47 std::make_index_sequence<Col>{});
51 static_assert(
Row ==
Col,
"Trace requires a square matrix");
52 return TraceImpl(std::make_index_sequence<Row>{});
65 throw std::out_of_range(
"Matrix::At: index out of range");
70 T &
At(
const std::size_t
i,
const std::size_t
j) {
72 throw std::out_of_range(
"Matrix::At: index out of range");
96 return NegImpl(std::make_index_sequence<Col>{});
108 for (std::size_t c = 1; c <
Col; ++c) {
114 template<
typename U, std::
size_t OtherCol>
118 for (std::size_t c = 0; c <
OtherCol; ++c) {
126 for (std::size_t c = 0; c <
Col; ++c) {
134 for (std::size_t c = 0; c <
Col; ++c) {
142 for (std::size_t c = 0; c <
Col; ++c) {
150 for (std::size_t c = 0; c <
Col; ++c) {
151 if (!(
datas[c] ==
other.datas[c]))
return false;
158 return !(*
this ==
other);
161 template<
typename UnitT>
168 for (std::size_t
r = 0;
r <
Row; ++
r) {
169 os << (
r == 0 ?
"" :
"\n ");
170 for (std::size_t c = 0; c <
Col; ++c) {
171 if (c != 0)
os <<
" ";
180 template<std::size_t...
Cs>
185 template<std::size_t...
Rs>
190 template<std::size_t...
Cs>
195 template<std::size_t
C, std::size_t...
Rs>
200 template<std::size_t...
Cs>
202 std::index_sequence<Cs...>)
205 template<std::size_t
C, std::size_t...
Rs>
207 MakeCol(
const std::array<T, Row * Col> &
flat, std::index_sequence<Rs...>) {
211 template<std::size_t...
Rs, std::size_t...
Cs>
213 std::index_sequence<Cs...>)
const {
218 template<std::size_t
R, std::size_t...
Cs>
223 template<std::size_t...
Rs>
225 return (datas[
Rs][
Rs] + ...);
228 template<
typename U, std::size_t...
Cs>
230 std::index_sequence<Cs...>)
const {
235 template<
typename U, std::size_t...
Cs>
237 std::index_sequence<Cs...>)
const {
242 template<std::size_t...
Cs>
243 constexpr auto NegImpl(std::index_sequence<Cs...>)
const {
247 template<
typename U, std::size_t...
Cs>
253 template<
typename UnitT, std::size_t...
Cs>
255 AsImpl(std::index_sequence<Cs...>)
const {
261 template<
typename T,
typename U, std::
size_t Row, std::
size_t Col>
constexpr auto operator*(Quantity< U1 > a, Quantity< U2 > b)
Multiply two quantities.
constexpr Matrix(const std::array< T, Row *Col > &flat, std::index_sequence< Cs... >)
constexpr auto operator*(U scalar) const
constexpr T TraceImpl(std::index_sequence< Rs... >) const
constexpr auto AddImpl(const Matrix< Row, Col, U > &other, std::index_sequence< Cs... >) const
constexpr auto operator-() const
constexpr auto Antisymmetric() const
T & At(const std::size_t i, const std::size_t j)
constexpr Vector< Col, T > MakeTransposeCol(std::index_sequence< Cs... >) const
constexpr auto SubImpl(const Matrix< Row, Col, U > &other, std::index_sequence< Cs... >) const
constexpr auto operator+(const Matrix< Row, Col, U > &other) const
constexpr auto TransposeImpl(std::index_sequence< Rs... >, std::index_sequence< Cs... >) const
std::array< Vector< Row, T >, Col > datas
constexpr Matrix(Args... elems)
constexpr Matrix(Args... basics)
static constexpr Matrix IdentityImpl(std::index_sequence< Cs... >)
constexpr Matrix< Row, Col, Quantity< UnitT > > AsImpl(std::index_sequence< Cs... >) const
static constexpr Vector< Row, T > MakeZeroCol(std::index_sequence< Rs... >)
static constexpr Vector< Row, T > MakeIdentityCol(std::index_sequence< Rs... >)
friend std::ostream & operator<<(std::ostream &os, const Matrix &m)
static constexpr Matrix MakeZero(std::index_sequence< Cs... >)
constexpr T & operator()(const std::size_t i, const std::size_t j)
constexpr const T & operator()(const std::size_t i, const std::size_t j) const
constexpr auto operator*(const Vector< Row, U > &v) const
constexpr auto Symmetric() const
static constexpr Matrix Identity()
constexpr auto ScaleImpl(U scalar, std::index_sequence< Cs... >) const
constexpr T Trace() const
constexpr auto operator-(const Matrix< Row, Col, U > &other) const
Matrix< Row, Col, Quantity< UnitT > > As() const
constexpr bool operator!=(const Matrix< Row, Col, U > &other) const
constexpr auto NegImpl(std::index_sequence< Cs... >) const
constexpr Matrix & operator-=(const Matrix< Row, Col, U > &other)
constexpr bool operator==(const Matrix< Row, Col, U > &other) const
static constexpr Vector< Row, T > MakeCol(const std::array< T, Row *Col > &flat, std::index_sequence< Rs... >)
constexpr auto Transpose() const
constexpr Matrix & operator+=(const Matrix< Row, Col, U > &other)
constexpr auto operator*(const Matrix< Col, OtherCol, U > &other) const
constexpr Matrix & operator*=(U scalar)
const T & At(const std::size_t i, const std::size_t j) const