<commit_before>#ifndef _ETL_MATH_MATRIX_H_INCLUDED
#define _ETL_MATH_MATRIX_H_INCLUDED

/*
 * Matrix templates.
 *
 * A matrix is an `n` row by `m` column grid of scalar of type `T`.  We
 * represent this as the type `Matrix<n, m, T>`, a collection of `n` row
 * vectors, each with `m` elements.
 *
 * The discussion below will refer to some abstract matrix type `M` where
 * something more specific isn't necessary.
 *
 * Constructing
 * ============
 *
 * In addition to the normal copy and move constructors, matrices can be
 * constructed in the following ways:
 *
 * - Default: `M{}` default-constructs the scalar elements.  This is implicit
 *   and can often be written `{}`.
 * - Literal: specifying each element: `M{ {a, b, c...}, {d, e, f...} }`.
 * - Identity: if `M` is a square matrix type, `M::identity()`.
 *
 * Operations on matrices
 * ======================
 *
 * Matrices support multiplication by column vectors: `m * v`.
 *
 * Multiplication by row vectors (`v * m`) and multiplication by scalars are
 * not currently supported because I haven't needed it.
 *
 * Matrix transposition is written `transpose(m)`.
 */

#include <type_traits>

#include "etl/functor.h"
#include "etl/type_list.h"
#include "etl/math/vector.h"

namespace etl {
namespace math {

/*******************************************************************************
 * Fundamental Matrix types.
 */
  
// Common parent of all matrices.
struct MatrixTag {};

/*
 * Base class of matrices of a given size and type.  Defines storage, type
 * aliases, and constructors so that we don't have to repeat them in the
 * specializations below.
 *
 * This base class is doing something slightly odd: it requires a TypeList
 * consisting of `rows` repetitions of its `Row` type, so that it can generate
 * a precise constructor.  To supply this, the specializations below inherit
 * indirectly through the `MatrixBaseHelper` template alias (below).
 */
template <
  std::size_t rows,
  std::size_t cols,
  typename T,
  typename TL>
struct MatrixBase;

// Slight specialization to capture the contents of the TypeList
template <
  std::size_t rows,
  std::size_t cols,
  typename T,
  typename... Rs>
struct MatrixBase<rows, cols, T, TypeList<Rs...>> : public MatrixTag {
  using Row = Vector<cols, T, Orient::row>;

  Row row[rows];

  // Default ctor
  constexpr MatrixBase() = default;

  // Literal ctor
  constexpr MatrixBase(Rs const & ...args) : row{args...} {}
};

/*
 * Helpful template alias for choosing the right `MatrixBase` parent for a
 * matrix of a given size and type.  This takes care of generating the
 * TypeList used as constructor arguments.
 */
template <
  std::size_t rows,
  std::size_t cols,
  typename T
>
using MatrixBaseHelper = MatrixBase<rows, cols, T,
      Repeat<Vector<cols, T, Orient::row>, rows>>;

/*
 * General Matrix template; used for rectangular matrices.
 */
template <std::size_t _rows, std::size_t _cols, typename T>
struct Matrix : public MatrixBaseHelper<_rows, _cols, T> {
  using Base = MatrixBaseHelper<_rows, _cols, T>;

  using Base::Base;

  static constexpr std::size_t rows = _rows;
  static constexpr std::size_t cols = _cols;
  static constexpr bool square = false;
  using Element = T;
  using typename Base::Row;
};

/*
 * Specialization for square matrices.
 */
template <std::size_t _side, typename T>
struct Matrix<_side, _side, T> : public MatrixBaseHelper<_side, _side, T> {
  using Base = MatrixBaseHelper<_side, _side, T>;

  using Base::Base;

  static constexpr std::size_t rows = _side;
  static constexpr std::size_t cols = _side;
  static constexpr bool square = true;
  using Element = T;
  using typename Base::Row;

  /*
   * Returns the identity matrix for this type.
   */
  static constexpr Matrix identity() {
    return identity_(MakeIndexSequence<_side>{});
  }

private:
  template <std::size_t... R>
  static constexpr Matrix identity_(IndexSequence<R...>) {
    return { identity_row<R>(MakeIndexSequence<_side>{})... };
  }

  template <std::size_t row, std::size_t... C>
  static constexpr Row identity_row(IndexSequence<C...>) {
    return { (row == C ? T{1} : T{0})... };
  }
};

/*
 * Aliases for common square matrices.
 */

template <typename T>
using Mat3 = Matrix<3, 3, T>;

template <typename T>
using Mat4 = Matrix<4, 4, T>;

using Mat3f = Mat3<float>;
using Mat4f = Mat4<float>;



/*******************************************************************************
 * Basic matrix operations.
 */

namespace _matrix {

  template <
    std::size_t r,
    std::size_t c,
    typename T,<commit_msg>math/matrix: 2x2 matrix aliases.<commit_after>#ifndef _ETL_MATH_MATRIX_H_INCLUDED
#define _ETL_MATH_MATRIX_H_INCLUDED

/*
 * Matrix templates.
 *
 * A matrix is an `n` row by `m` column grid of scalar of type `T`.  We
 * represent this as the type `Matrix<n, m, T>`, a collection of `n` row
 * vectors, each with `m` elements.
 *
 * The discussion below will refer to some abstract matrix type `M` where
 * something more specific isn't necessary.
 *
 * Constructing
 * ============
 *
 * In addition to the normal copy and move constructors, matrices can be
 * constructed in the following ways:
 *
 * - Default: `M{}` default-constructs the scalar elements.  This is implicit
 *   and can often be written `{}`.
 * - Literal: specifying each element: `M{ {a, b, c...}, {d, e, f...} }`.
 * - Identity: if `M` is a square matrix type, `M::identity()`.
 *
 * Operations on matrices
 * ======================
 *
 * Matrices support multiplication by column vectors: `m * v`.
 *
 * Multiplication by row vectors (`v * m`) and multiplication by scalars are
 * not currently supported because I haven't needed it.
 *
 * Matrix transposition is written `transpose(m)`.
 */

#include <type_traits>

#include "etl/functor.h"
#include "etl/type_list.h"
#include "etl/math/vector.h"

namespace etl {
namespace math {

/*******************************************************************************
 * Fundamental Matrix types.
 */
  
// Common parent of all matrices.
struct MatrixTag {};

/*
 * Base class of matrices of a given size and type.  Defines storage, type
 * aliases, and constructors so that we don't have to repeat them in the
 * specializations below.
 *
 * This base class is doing something slightly odd: it requires a TypeList
 * consisting of `rows` repetitions of its `Row` type, so that it can generate
 * a precise constructor.  To supply this, the specializations below inherit
 * indirectly through the `MatrixBaseHelper` template alias (below).
 */
template <
  std::size_t rows,
  std::size_t cols,
  typename T,
  typename TL>
struct MatrixBase;

// Slight specialization to capture the contents of the TypeList
template <
  std::size_t rows,
  std::size_t cols,
  typename T,
  typename... Rs>
struct MatrixBase<rows, cols, T, TypeList<Rs...>> : public MatrixTag {
  using Row = Vector<cols, T, Orient::row>;

  Row row[rows];

  // Default ctor
  constexpr MatrixBase() = default;

  // Literal ctor
  constexpr MatrixBase(Rs const & ...args) : row{args...} {}
};

/*
 * Helpful template alias for choosing the right `MatrixBase` parent for a
 * matrix of a given size and type.  This takes care of generating the
 * TypeList used as constructor arguments.
 */
template <
  std::size_t rows,
  std::size_t cols,
  typename T
>
using MatrixBaseHelper = MatrixBase<rows, cols, T,
      Repeat<Vector<cols, T, Orient::row>, rows>>;

/*
 * General Matrix template; used for rectangular matrices.
 */
template <std::size_t _rows, std::size_t _cols, typename T>
struct Matrix : public MatrixBaseHelper<_rows, _cols, T> {
  using Base = MatrixBaseHelper<_rows, _cols, T>;

  using Base::Base;

  static constexpr std::size_t rows = _rows;
  static constexpr std::size_t cols = _cols;
  static constexpr bool square = false;
  using Element = T;
  using typename Base::Row;
};

/*
 * Specialization for square matrices.
 */
template <std::size_t _side, typename T>
struct Matrix<_side, _side, T> : public MatrixBaseHelper<_side, _side, T> {
  using Base = MatrixBaseHelper<_side, _side, T>;

  using Base::Base;

  static constexpr std::size_t rows = _side;
  static constexpr std::size_t cols = _side;
  static constexpr bool square = true;
  using Element = T;
  using typename Base::Row;

  /*
   * Returns the identity matrix for this type.
   */
  static constexpr Matrix identity() {
    return identity_(MakeIndexSequence<_side>{});
  }

private:
  template <std::size_t... R>
  static constexpr Matrix identity_(IndexSequence<R...>) {
    return { identity_row<R>(MakeIndexSequence<_side>{})... };
  }

  template <std::size_t row, std::size_t... C>
  static constexpr Row identity_row(IndexSequence<C...>) {
    return { (row == C ? T{1} : T{0})... };
  }
};

/*
 * Aliases for common square matrices.
 */

template <typename T>
using Mat2 = Matrix<2, 2, T>;

template <typename T>
using Mat3 = Matrix<3, 3, T>;

template <typename T>
using Mat4 = Matrix<4, 4, T>;

using Mat2f = Mat2<float>;
using Mat3f = Mat3<float>;
using Mat4f = Mat4<float>;



/*******************************************************************************
 * Basic matrix operations.
 */

namespace _matrix {

  template <
    std::size_t r,
    std::size_t c,
    typename T,
{'fraction_non_alphanumeric': 0.1554353704705246, 'fraction_numerical': 0.00335316387236344, 'mean_word_length': 3.871443624868282, 'pattern_counts': {'":': 0, '<': 70, '<?xml version=': 0, '>': 68, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6365113', 'n_tokens_mistral': 2915, 'n_tokens_neox': 2774, 'n_words': 1023}