Determinant.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines function for taking the determinant of a rank-2 tensor
6 
7 #pragma once
8 
10 
11 namespace detail {
12 template <typename Symm, typename Index, typename = std::nullptr_t>
13 struct DeterminantImpl;
14 
15 template <typename Symm, typename Index>
16 struct DeterminantImpl<Symm, Index, Requires<Index::dim == 1>> {
17  template <typename T>
18  static typename T::type apply(const T& tensor) {
19  return get<0, 0>(tensor);
20  }
21 };
22 
23 template <typename Symm, typename Index>
24 struct DeterminantImpl<Symm, Index, Requires<Index::dim == 2>> {
25  template <typename T>
26  static typename T::type apply(const T& tensor) {
27  const auto& t00 = get<0, 0>(tensor);
28  const auto& t01 = get<0, 1>(tensor);
29  const auto& t10 = get<1, 0>(tensor);
30  const auto& t11 = get<1, 1>(tensor);
31  return t00 * t11 - t01 * t10;
32  }
33 };
34 
35 template <typename Index>
36 struct DeterminantImpl<Symmetry<2, 1>, Index, Requires<Index::dim == 3>> {
37  template <typename T>
38  static typename T::type apply(const T& tensor) {
39  const auto& t00 = get<0, 0>(tensor);
40  const auto& t01 = get<0, 1>(tensor);
41  const auto& t02 = get<0, 2>(tensor);
42  const auto& t10 = get<1, 0>(tensor);
43  const auto& t11 = get<1, 1>(tensor);
44  const auto& t12 = get<1, 2>(tensor);
45  const auto& t20 = get<2, 0>(tensor);
46  const auto& t21 = get<2, 1>(tensor);
47  const auto& t22 = get<2, 2>(tensor);
48  return t00 * (t11 * t22 - t12 * t21) - t01 * (t10 * t22 - t12 * t20) +
49  t02 * (t10 * t21 - t11 * t20);
50  }
51 };
52 
53 template <typename Index>
54 struct DeterminantImpl<Symmetry<1, 1>, Index, Requires<Index::dim == 3>> {
55  template <typename T>
56  static typename T::type apply(const T& tensor) {
57  const auto& t00 = get<0, 0>(tensor);
58  const auto& t01 = get<0, 1>(tensor);
59  const auto& t02 = get<0, 2>(tensor);
60  const auto& t11 = get<1, 1>(tensor);
61  const auto& t12 = get<1, 2>(tensor);
62  const auto& t22 = get<2, 2>(tensor);
63  return t00 * (t11 * t22 - t12 * t12) - t01 * (t01 * t22 - t12 * t02) +
64  t02 * (t01 * t12 - t11 * t02);
65  }
66 };
67 
68 template <typename Index>
69 struct DeterminantImpl<Symmetry<2, 1>, Index, Requires<Index::dim == 4>> {
70  template <typename T>
71  static typename T::type apply(const T& tensor) {
72  const auto& t00 = get<0, 0>(tensor);
73  const auto& t01 = get<0, 1>(tensor);
74  const auto& t02 = get<0, 2>(tensor);
75  const auto& t03 = get<0, 3>(tensor);
76  const auto& t10 = get<1, 0>(tensor);
77  const auto& t11 = get<1, 1>(tensor);
78  const auto& t12 = get<1, 2>(tensor);
79  const auto& t13 = get<1, 3>(tensor);
80  const auto& t20 = get<2, 0>(tensor);
81  const auto& t21 = get<2, 1>(tensor);
82  const auto& t22 = get<2, 2>(tensor);
83  const auto& t23 = get<2, 3>(tensor);
84  const auto& t30 = get<3, 0>(tensor);
85  const auto& t31 = get<3, 1>(tensor);
86  const auto& t32 = get<3, 2>(tensor);
87  const auto& t33 = get<3, 3>(tensor);
88  const auto minor1 = t22 * t33 - t23 * t32;
89  const auto minor2 = t21 * t33 - t23 * t31;
90  const auto minor3 = t20 * t33 - t23 * t30;
91  const auto minor4 = t21 * t32 - t22 * t31;
92  const auto minor5 = t20 * t32 - t22 * t30;
93  const auto minor6 = t20 * t31 - t21 * t30;
94  return t00 * (t11 * minor1 - t12 * minor2 + t13 * minor4) -
95  t01 * (t10 * minor1 - t12 * minor3 + t13 * minor5) +
96  t02 * (t10 * minor2 - t11 * minor3 + t13 * minor6) -
97  t03 * (t10 * minor4 - t11 * minor5 + t12 * minor6);
98  }
99 };
100 
101 template <typename Index>
102 struct DeterminantImpl<Symmetry<1, 1>, Index, Requires<Index::dim == 4>> {
103  template <typename T>
104  static typename T::type apply(const T& tensor) {
105  const auto& t00 = get<0, 0>(tensor);
106  const auto& t01 = get<0, 1>(tensor);
107  const auto& t02 = get<0, 2>(tensor);
108  const auto& t03 = get<0, 3>(tensor);
109  const auto& t11 = get<1, 1>(tensor);
110  const auto& t12 = get<1, 2>(tensor);
111  const auto& t13 = get<1, 3>(tensor);
112  const auto& t22 = get<2, 2>(tensor);
113  const auto& t23 = get<2, 3>(tensor);
114  const auto& t33 = get<3, 3>(tensor);
115  const auto minor1 = t22 * t33 - t23 * t23;
116  const auto minor2 = t12 * t33 - t23 * t13;
117  const auto minor3 = t02 * t33 - t23 * t03;
118  const auto minor4 = t12 * t23 - t22 * t13;
119  const auto minor5 = t02 * t23 - t22 * t03;
120  const auto minor6 = t02 * t13 - t12 * t03;
121  return t00 * (t11 * minor1 - t12 * minor2 + t13 * minor4) -
122  t01 * (t01 * minor1 - t12 * minor3 + t13 * minor5) +
123  t02 * (t01 * minor2 - t11 * minor3 + t13 * minor6) -
124  t03 * (t01 * minor4 - t11 * minor5 + t12 * minor6);
125  }
126 };
127 } // namespace detail
128 
129 /*!
130  * \ingroup TensorGroup
131  * \brief Computes the determinant of a rank-2 Tensor `tensor`.
132  *
133  * \returns The determinant of `tensor`.
134  * \requires That `tensor` be a rank-2 Tensor, with both indices sharing the
135  * same dimension and type.
136  */
137 template <typename T, typename Symm, typename Index0, typename Index1>
139  const Tensor<T, Symm, index_list<Index0, Index1>>& tensor) {
140  static_assert(Index0::dim == Index1::dim,
141  "Cannot take the determinant of a Tensor whose Indices are not "
142  "of the same dimensionality.");
143  static_assert(Index0::index_type == Index1::index_type,
144  "Taking the determinant of a mixed Spatial and Spacetime index "
145  "Tensor is not allowed since it's not clear what that means.");
147 }
Scalar< T > determinant(const Tensor< T, Symm, index_list< Index0, Index1 >> &tensor)
Computes the determinant of a rank-2 Tensor tensor.
Definition: Determinant.hpp:138
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args)
Apply the function f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1595
Definition: Determinant.hpp:11
typename detail::SymmetryImpl< std::make_index_sequence< sizeof...(T)>, tmpl::integral_list< std::int32_t, T... > >::type Symmetry
Computes the canonical symmetry from the integers T
Definition: Symmetry.hpp:81
Defines classes for Tensor.
An integer multi-index.
Definition: Index.hpp:28
typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters Requires
Express requirements on the template parameters of a function or class, replaces std::enable_if_t ...
Definition: Requires.hpp:67
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21