NumCpp  2.10.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
det.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <cmath>
31 #include <string>
32 #include <type_traits>
33 
37 #include "NumCpp/Core/Shape.hpp"
38 #include "NumCpp/Core/Types.hpp"
39 #include "NumCpp/NdArray.hpp"
40 
41 namespace nc::linalg
42 {
43  namespace detail
44  {
45  //============================================================================
46  // Method Description:
53  template<typename dtype>
54  auto det(const NdArray<dtype>& inArray, uint32 order)
55  -> std::conditional_t<std::is_integral_v<dtype>, int64, double>
56  {
58 
59  using ReturnType = std::conditional_t<std::is_integral_v<dtype>, int64, double>;
60 
61  if (order == 1)
62  {
63  return static_cast<ReturnType>(inArray.front());
64  }
65 
66  if (order == 2)
67  {
68  return static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 1)) -
69  static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 0));
70  }
71 
72  if (order == 3)
73  {
74  const auto aei = static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 1)) *
75  static_cast<ReturnType>(inArray(2, 2));
76  const auto bfg = static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 2)) *
77  static_cast<ReturnType>(inArray(2, 0));
78  const auto cdh = static_cast<ReturnType>(inArray(0, 2)) * static_cast<ReturnType>(inArray(1, 0)) *
79  static_cast<ReturnType>(inArray(2, 1));
80  const auto ceg = static_cast<ReturnType>(inArray(0, 2)) * static_cast<ReturnType>(inArray(1, 1)) *
81  static_cast<ReturnType>(inArray(2, 0));
82  const auto bdi = static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 0)) *
83  static_cast<ReturnType>(inArray(2, 2));
84  const auto afh = static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 2)) *
85  static_cast<ReturnType>(inArray(2, 1));
86 
87  return aei + bfg + cdh - ceg - bdi - afh;
88  }
89 
90  ReturnType determinant = 0;
91  ReturnType sign = 1;
92  NdArray<dtype> submat(order - 1);
93 
94  for (uint32 c = 0; c < order; ++c)
95  {
96  uint32 subi = 0;
97  for (uint32 i = 1; i < order; ++i)
98  {
99  uint32 subj = 0;
100  for (uint32 j = 0; j < order; ++j)
101  {
102  if (j == c)
103  {
104  continue;
105  }
106 
107  submat(subi, subj++) = inArray(i, j);
108  }
109  ++subi;
110  }
111 
112  determinant += (sign * static_cast<ReturnType>(inArray(0, c)) * det(submat, order - 1));
113  sign *= -1;
114  }
115 
116  return determinant;
117  }
118  } // namespace detail
119 
120  //============================================================================
121  // Method Description:
130  template<typename dtype>
131  auto det(const NdArray<dtype>& inArray)
132  {
134 
135  const Shape inShape = inArray.shape();
136  if (!inShape.issquare())
137  {
138  THROW_INVALID_ARGUMENT_ERROR("input array must be square.");
139  }
140 
141  return detail::det(inArray, inShape.rows);
142  }
143 } // namespace nc::linalg
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:39
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:138
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4402
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:41
uint32 rows
Definition: Core/Shape.hpp:44
bool issquare() const noexcept
Definition: Core/Shape.hpp:125
constexpr auto j
Definition: Constants.hpp:41
constexpr double c
speed of light
Definition: Constants.hpp:36
auto det(const NdArray< dtype > &inArray, uint32 order) -> std::conditional_t< std::is_integral_v< dtype >, int64, double >
Definition: det.hpp:54
Definition: cholesky.hpp:41
auto det(const NdArray< dtype > &inArray)
Definition: det.hpp:131
int8 sign(dtype inValue) noexcept
Definition: sign.hpp:52
std::int64_t int64
Definition: Types.hpp:35
std::uint32_t uint32
Definition: Types.hpp:40