<commit_before>#ifndef MATRIX_ALGORITHM_HPP_
#define MATRIX_ALGORITHM_HPP_

#include "matrix_basic_math.hpp"


template<typename T, std::size_t I, std::size_t J>
void print(const Matrix<T, I, J>& A)
{
  for (std::size_t i = 0; i < I; i++)
  {
    for (std::size_t j = 0; j < J; j++)
    {
      std::cout << A[i][j] << " ";
    }
    std::cout << std::endl;
  }
}



/**
 * @brief LU decomposition
 * 
 * Usage: The result of function is pair of matrices where L matrix is first 
 *        element of pair, the second element is U matrix
 * @param [in] Square Matrix A
 * 
 * @return Two matrices L and U
 */
template<typename T, std::size_t n>
std::pair<Matrix<T,n,n>, Matrix<T,n,n>>lu(const Matrix<T,n,n>& A)
{
  auto L = eye<T, n>();
  auto U = zeros<T, n, n>();
  T sum;

  for(std::size_t j = 0; j < n; j++)
  {
    for(std::size_t i = 0; i <= j; i++)
    {
      sum = 0.0;
      for(std::size_t p = 0; p < i; p++)
      {
        sum += U[p][j] * L[i][p];
      }
      U[i][j] = A[i][j] - sum;
    }
    for(std::size_t i = j; i < n; i++)
    {
      sum = 0.0;
      for(std::size_t p = 0; p < i; p++)
      {
        sum += U[p][j] * L[i][p];
      }

      if(U[j][j] == 0)
        throw;
      else
        L[i][j] = (A[i][j] - sum) / U[j][j];
    }
  }
  return std::pair<Matrix<T,n,n>, Matrix<T,n,n>>{L, U};
}


/**
 * @brief Determinant of matrix 1x1
 *
 * @param [in] Square Matrix A with 1x1 size
 * 
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 1, 1>& A)
{
  return A[0][0];
}


/**
 * @brief Determinant of matrix 2x2
 *
 * @param [in] Square Matrix A with 2x2 size
 *
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 2, 2>& A)
{
  auto&& a = A[0][0]; auto&& b = A[0][1];
  auto&& c = A[1][0]; auto&& d = A[1][1];

  return a*d - b*c;
}


/**
 * @brief Determinant of matrix 3x3
 *
 * @param [in] Square Matrix A with 3x3 size
 * 
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 3, 3>& A)
{
  auto&& a = A[0][0]; auto&& b = A[0][1]; auto&& c = A[0][2];
  auto&& d = A[1][0]; auto&& e = A[1][1]; auto&& f = A[1][2];
  auto&& g = A[2][0]; auto&& h = A[2][1]; auto&& i = A[2][2];

  return a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h;
}


template<typename T, std::size_t n>
void swap_rows(Matrix<T, n, n>& data, size_t a, size_t b)
{
  if (a != b)
  {
    for (size_t k = 0; k < n; ++k)
    {
      std::swap(data[a], data[b]);
    }
  }
}


/**
 * @brief Determinant of matrix nxn
 *
 * @param [in] Square Matrix A with nxn size
 *
 * @return Determinant of matrix A
 */
template<typename T, std::size_t n>
T det(Matrix<T, n, n> data)
{
  auto tmp = data;

  T factor{1};
  std::size_t pivot{0};

  auto prod = [&]()
  {
    T prod{1};

    for (std::size_t i = 0; i < n; ++i)
    {
      prod *= tmp[i][i];
    }
    return prod / factor;
  };

  for (size_t r = 0; r < n; ++r)
  {
    if (n <= pivot)
    {
      return prod();
    }

    std::size_t i = r;

    while (tmp[i][pivot] == 0)
    {
      ++i;
      if (n == i)
      {
        i = r;
        ++pivot;
        if (n == pivot)
        {
          return prod();<commit_msg>update types<commit_after>#ifndef MATRIX_ALGORITHM_HPP_
#define MATRIX_ALGORITHM_HPP_

#include "matrix_basic_math.hpp"


template<typename T, std::size_t I, std::size_t J>
void print(const Matrix<T, I, J>& A)
{
  for (std::size_t i = 0; i < I; i++)
  {
    for (std::size_t j = 0; j < J; j++)
    {
      std::cout << A[i][j] << " ";
    }
    std::cout << std::endl;
  }
}



/**
 * @brief LU decomposition
 * 
 * Usage: The result of function is pair of matrices where L matrix is first 
 *        element of pair, the second element is U matrix
 * @param [in] Square Matrix A
 * 
 * @return Two matrices L and U
 */
template<typename T, std::size_t n>
std::pair<Matrix<T,n,n>, Matrix<T,n,n>>lu(const Matrix<T,n,n>& A)
{
  auto L = eye<T, n>();
  auto U = zeros<T, n, n>();
  T sum;

  for(std::size_t j = 0; j < n; j++)
  {
    for(std::size_t i = 0; i <= j; i++)
    {
      sum = 0.0;
      for(std::size_t p = 0; p < i; p++)
      {
        sum += U[p][j] * L[i][p];
      }
      U[i][j] = A[i][j] - sum;
    }
    for(std::size_t i = j; i < n; i++)
    {
      sum = 0.0;
      for(std::size_t p = 0; p < i; p++)
      {
        sum += U[p][j] * L[i][p];
      }

      if(U[j][j] == 0)
        throw;
      else
        L[i][j] = (A[i][j] - sum) / U[j][j];
    }
  }
  return std::pair<Matrix<T,n,n>, Matrix<T,n,n>>{L, U};
}


/**
 * @brief Determinant of matrix 1x1
 *
 * @param [in] Square Matrix A with 1x1 size
 * 
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 1, 1>& A)
{
  return A[0][0];
}


/**
 * @brief Determinant of matrix 2x2
 *
 * @param [in] Square Matrix A with 2x2 size
 *
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 2, 2>& A)
{
  auto&& a = A[0][0]; auto&& b = A[0][1];
  auto&& c = A[1][0]; auto&& d = A[1][1];

  return a*d - b*c;
}


/**
 * @brief Determinant of matrix 3x3
 *
 * @param [in] Square Matrix A with 3x3 size
 * 
 * @return Determinant of matrix A
 */
template<typename T>
T det(const Matrix<T, 3, 3>& A)
{
  auto&& a = A[0][0]; auto&& b = A[0][1]; auto&& c = A[0][2];
  auto&& d = A[1][0]; auto&& e = A[1][1]; auto&& f = A[1][2];
  auto&& g = A[2][0]; auto&& h = A[2][1]; auto&& i = A[2][2];

  return a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h;
}


template<typename T, std::size_t n>
void swap_rows(Matrix<T, n, n>& data, size_t a, size_t b)
{
  if (a != b)
  {
    for (size_t k = 0; k < n; ++k)
    {
      std::swap(data[a], data[b]);
    }
  }
}


/**
 * @brief Determinant of matrix nxn
 *
 * @param [in] Square Matrix A with nxn size
 *
 * @return Determinant of matrix A
 */
template<typename T, std::size_t n>
T det(Matrix<T, n, n> data)
{
  auto tmp = data;

  T factor{1};
  std::size_t pivot{0};

  auto prod = [&]()
  {
    T prod{1};

    for (std::size_t i = 0; i < n; ++i)
    {
      prod *= tmp[i][i];
    }
    return prod / factor;
  };

  for (std::size_t r = 0; r < n; ++r)
  {
    if (n <= pivot)
    {
      return prod();
    }

    std::size_t i = r;

    while (tmp[i][pivot] == 0)
    {
      ++i;
      if (n == i)
      {
        i = r;
        ++pivot;
        if (n == pivot)
        {
          return prod();
{'fraction_non_alphanumeric': 0.2061334176414796, 'fraction_numerical': 0.02023395510591211, 'mean_word_length': 2.3091004184100417, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 47, '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': '6578558', 'n_tokens_mistral': 2858, 'n_tokens_neox': 2725, 'n_words': 762}