NumCpp  2.9.0
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
42 {
43  namespace linalg
44  {
45  namespace detail
46  {
47  //============================================================================
48  // Method Description:
55  template<typename dtype>
56  auto det(const NdArray<dtype>& inArray, uint32 order)
57  -> std::conditional_t<is_integral_v<dtype>, int64, double>
58  {
60 
61  using ReturnType = std::conditional_t<is_integral_v<dtype>, int64, double>;
62 
63  if (order == 1)
64  {
65  return static_cast<ReturnType>(inArray.front());
66  }
67 
68  if (order == 2)
69  {
70  return static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 1)) -
71  static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 0));
72  }
73 
74  if (order == 3)
75  {
76  const auto aei = static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 1)) *
77  static_cast<ReturnType>(inArray(2, 2));
78  const auto bfg = static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 2)) *
79  static_cast<ReturnType>(inArray(2, 0));
80  const auto cdh = static_cast<ReturnType>(inArray(0, 2)) * static_cast<ReturnType>(inArray(1, 0)) *
81  static_cast<ReturnType>(inArray(2, 1));
82  const auto ceg = static_cast<ReturnType>(inArray(0, 2)) * static_cast<ReturnType>(inArray(1, 1)) *
83  static_cast<ReturnType>(inArray(2, 0));
84  const auto bdi = static_cast<ReturnType>(inArray(0, 1)) * static_cast<ReturnType>(inArray(1, 0)) *
85  static_cast<ReturnType>(inArray(2, 2));
86  const auto afh = static_cast<ReturnType>(inArray(0, 0)) * static_cast<ReturnType>(inArray(1, 2)) *
87  static_cast<ReturnType>(inArray(2, 1));
88 
89  return aei + bfg + cdh - ceg - bdi - afh;
90  }
91 
92  ReturnType determinant = 0;
93  ReturnType sign = 1;
94  NdArray<dtype> submat(order - 1);
95 
96  for (uint32 c = 0; c < order; ++c)
97  {
98  uint32 subi = 0;
99  for (uint32 i = 1; i < order; ++i)
100  {
101  uint32 subj = 0;
102  for (uint32 j = 0; j < order; ++j)
103  {
104  if (j == c)
105  {
106  continue;
107  }
108 
109  submat(subi, subj++) = inArray(i, j);
110  }
111  ++subi;
112  }
113 
114  determinant += (sign * static_cast<ReturnType>(inArray(0, c)) * det(submat, order - 1));
115  sign *= -1;
116  }
117 
118  return determinant;
119  }
120  } // namespace detail
121 
122  //============================================================================
123  // Method Description:
132  template<typename dtype>
133  auto det(const NdArray<dtype>& inArray)
134  {
136 
137  const Shape inShape = inArray.shape();
138  if (!inShape.issquare())
139  {
140  THROW_INVALID_ARGUMENT_ERROR("input array must be square.");
141  }
142 
143  return detail::det(inArray, inShape.rows);
144  }
145  } // namespace linalg
146 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:37
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:72
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4092
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:45
constexpr double c
speed of light
Definition: Constants.hpp:40
auto det(const NdArray< dtype > &inArray, uint32 order) -> std::conditional_t< is_integral_v< dtype >, int64, double >
Definition: det.hpp:56
auto det(const NdArray< dtype > &inArray)
Definition: det.hpp:133
Definition: Coordinate.hpp:45
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