Arcane  v4.1.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
StaticMatrix.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* ValueTypeInterface.h (C) 2000-2026 */
9/* */
10/* Enable statically sized matrices as value types. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCCORE_ALINA_STATICMATRIX_H
13#define ARCCORE_ALINA_STATICMATRIX_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16/*
17 * This file is based on the work on AMGCL library (version march 2026)
18 * which can be found at https://github.com/ddemidov/amgcl.
19 *
20 * Copyright (c) 2012-2022 Denis Demidov <dennis.demidov@gmail.com>
21 * SPDX-License-Identifier: MIT
22 */
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26#include <array>
27#include <type_traits>
28
29#include "arccore/alina/BuiltinBackend.h"
30#include "arccore/alina/ValueTypeInterface.h"
31#include "arccore/alina/DenseMatrixInverseImpl.h"
32
33/*---------------------------------------------------------------------------*/
34/*---------------------------------------------------------------------------*/
35
36namespace Arcane::Alina
37{
38
39/*---------------------------------------------------------------------------*/
40/*---------------------------------------------------------------------------*/
41
42template <typename T, int N, int M>
44{
45 std::array<T, N * M> buf;
46
47 T operator()(int i, int j) const
48 {
49 return buf[i * M + j];
50 }
51
52 T& operator()(int i, int j)
53 {
54 return buf[i * M + j];
55 }
56
57 T operator()(int i) const
58 {
59 return buf[i];
60 }
61
62 T& operator()(int i)
63 {
64 return buf[i];
65 }
66
67 const T* data() const
68 {
69 return buf.data();
70 }
71
72 T* data()
73 {
74 return buf.data();
75 }
76
77 template <typename U>
78 const StaticMatrix& operator=(const StaticMatrix<U, N, M>& y)
79 {
80 for (int i = 0; i < N * M; ++i)
81 buf[i] = y.buf[i];
82 return *this;
83 }
84
85 template <typename U>
86 const StaticMatrix& operator+=(const StaticMatrix<U, N, M>& y)
87 {
88 for (int i = 0; i < N * M; ++i)
89 buf[i] += y.buf[i];
90 return *this;
91 }
92
93 template <typename U>
94 const StaticMatrix& operator-=(const StaticMatrix<U, N, M>& y)
95 {
96 for (int i = 0; i < N * M; ++i)
97 buf[i] -= y.buf[i];
98 return *this;
99 }
100
101 const StaticMatrix& operator*=(T c)
102 {
103 for (int i = 0; i < N * M; ++i)
104 buf[i] *= c;
105 return *this;
106 }
107
108 friend StaticMatrix operator*(T a, StaticMatrix x)
109 {
110 return x *= a;
111 }
112
113 friend StaticMatrix operator-(StaticMatrix x)
114 {
115 for (int i = 0; i < N * M; ++i)
116 x.buf[i] = -x.buf[i];
117 return x;
118 }
119
120 friend bool operator<(const StaticMatrix& x, const StaticMatrix& y)
121 {
122 T xtrace = math::zero<T>();
123 T ytrace = math::zero<T>();
124
125 const int K = N < M ? N : M;
126
127 for (int i = 0; i < K; ++i) {
128 xtrace += x(i, i);
129 ytrace += y(i, i);
130 }
131
132 return xtrace < ytrace;
133 }
134
135 friend std::ostream& operator<<(std::ostream& os, const StaticMatrix& a)
136 {
137 for (int i = 0; i < N; ++i) {
138 for (int j = 0; j < M; ++j) {
139 os << " " << a(i, j);
140 }
141 os << std::endl;
142 }
143 return os;
144 }
145};
146
147template <typename T, typename U, int N, int M>
149{
150 return a += b;
151}
152
153template <typename T, typename U, int N, int M>
154StaticMatrix<T, N, M> operator-(StaticMatrix<T, N, M> a, const StaticMatrix<U, N, M>& b)
155{
156 return a -= b;
157}
158
159template <typename T, typename U, int N, int K, int M>
160StaticMatrix<T, N, M> operator*(const StaticMatrix<T, N, K>& a, const StaticMatrix<U, K, M>& b)
161{
162 StaticMatrix<T, N, M> c;
163 for (int i = 0; i < N; ++i) {
164 for (int j = 0; j < M; ++j)
165 c(i, j) = math::zero<T>();
166 for (int k = 0; k < K; ++k) {
167 T aik = a(i, k);
168 for (int j = 0; j < M; ++j)
169 c(i, j) += aik * b(k, j);
170 }
171 }
172 return c;
173}
174
175template <class T> struct is_static_matrix : std::false_type
176{};
177
178template <class T, int N, int M>
179struct is_static_matrix<StaticMatrix<T, N, M>> : std::true_type
180{};
181
182} // namespace Arcane::Alina
183
184namespace Arcane::Alina::backend
185{
186
188template <typename T, int N, int M>
189struct is_builtin_vector<std::vector<StaticMatrix<T, N, M>>> : std::true_type
190{};
191
192} // namespace Arcane::Alina::backend
193
194namespace Arcane::Alina::math
195{
196
198template <class T, int N, int M>
199struct scalar_of<StaticMatrix<T, N, M>>
200{
201 typedef typename scalar_of<T>::type type;
202};
203
205template <class T, int N, int M, class S>
206struct replace_scalar<StaticMatrix<T, N, M>, S>
207{
208 typedef StaticMatrix<S, N, M> type;
209};
210
212template <class T, int N>
213struct rhs_of<StaticMatrix<T, N, N>>
214{
215 typedef StaticMatrix<T, N, 1> type;
216};
217
219template <class T, int N, int M>
220struct element_of<StaticMatrix<T, N, M>>
221{
222 typedef T type;
223};
224
226template <class T, int N, int M>
227struct is_static_matrix<StaticMatrix<T, N, M>> : std::true_type
228{};
229
231template <class T, int N, int M>
232struct static_rows<StaticMatrix<T, N, M>> : std::integral_constant<int, N>
233{};
234
236template <class T, int N, int M>
237struct static_cols<StaticMatrix<T, N, M>> : std::integral_constant<int, M>
238{};
239
241template <typename T, int N, int M>
243{
244 typedef StaticMatrix<T, M, N> return_type;
245
247 {
249 for (int i = 0; i < N; ++i)
250 for (int j = 0; j < M; ++j)
251 y(j, i) = math::adjoint(x(i, j));
252 return y;
253 }
254};
255
257template <class T, int N>
259{
260 typedef T return_type;
261 static T get(const StaticMatrix<T, N, 1>& x, const StaticMatrix<T, N, 1>& y)
262 {
263 T sum = math::zero<T>();
264 for (int i = 0; i < N; ++i)
265 sum += x(i) * math::adjoint(y(i));
266 return sum;
267 }
268};
269
271template <class T, int N, int M>
273{
274 typedef StaticMatrix<T, M, M> return_type;
275
276 static return_type get(const StaticMatrix<T, N, M>& x, const StaticMatrix<T, N, M>& y)
277 {
279 for (int i = 0; i < M; ++i) {
280 for (int j = 0; j < M; ++j) {
281 T sum = math::zero<T>();
282 for (int k = 0; k < N; ++k)
283 sum += x(k, i) * math::adjoint(y(k, j));
284 p(i, j) = sum;
285 }
286 }
287 return p;
288 }
289};
290
292template <typename T, int N, int M>
293struct norm_impl<StaticMatrix<T, N, M>>
294{
295 static typename math::scalar_of<T>::type get(const StaticMatrix<T, N, M>& x)
296 {
297 T s = math::zero<T>();
298 for (int i = 0; i < N * M; ++i)
299 s += x(i) * math::adjoint(x(i));
300 return sqrt(math::norm(s));
301 }
302};
303
305template <typename T, int N, int M>
306struct zero_impl<StaticMatrix<T, N, M>>
307{
308 static StaticMatrix<T, N, M> get()
309 {
311 for (int i = 0; i < N * M; ++i)
312 z(i) = math::zero<T>();
313 return z;
314 }
315};
316
318template <typename T, int N, int M>
320{
321 static bool get(const StaticMatrix<T, N, M>& x)
322 {
323 for (int i = 0; i < N * M; ++i)
324 if (!math::is_zero(x(i)))
325 return false;
326 return true;
327 }
328};
329
331template <typename T, int N>
333{
334 static StaticMatrix<T, N, N> get()
335 {
337 for (int i = 0; i < N; ++i)
338 for (int j = 0; j < N; ++j)
339 I(i, j) = static_cast<T>(i == j);
340 return I;
341 }
342};
343
345template <typename T, int N, int M>
347{
348 static StaticMatrix<T, N, M> get(T c)
349 {
351 for (int i = 0; i < N * M; ++i)
352 C(i) = c;
353 return C;
354 }
355};
356
358template <typename T, int N>
360{
362 {
363 std::array<T, N * N> buf;
364 std::array<int, N> p;
365 detail::inverse(N, A.data(), buf.data(), p.data());
366 return A;
367 }
368};
369
370/*---------------------------------------------------------------------------*/
371/*---------------------------------------------------------------------------*/
372
373} // namespace Arcane::Alina::math
374
375/*---------------------------------------------------------------------------*/
376/*---------------------------------------------------------------------------*/
377
378#endif
Default implementation for conjugate transpose.
Default implementation for the constant element.
Element type of a non-scalar type.
Default implementation for the identity element.
Default implementation for inner product.
Default implementation of inversion operation.
Whether the value type is a statically sized matrix.
Default implementation for zero check.
Default implementation for element norm.
Replace scalar type in the static matrix.
RHS type corresponding to a non-scalar type.
Scalar type of a non-scalar type.
Number of columns for statically sized matrix types.
Number of rows for statically sized matrix types.
Default implementation for the zero element.