NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
det.hpp
Go to the documentation of this file.
1
28#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
41namespace 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:139
const Shape & shape() const noexcept
Definition: NdArrayCore.hpp:4511
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: Core/Constants.hpp:42
constexpr double c
speed of light
Definition: Core/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