Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
SimpleTableInternalComparator.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2022 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/* SimpleTableInternalComparator.cc (C) 2000-2022 */
9/* */
10/* Comparateur de SimpleTableInternal. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/std/SimpleTableInternalComparator.h"
15
16#include "arcane/utils/ITraceMng.h"
17#include "arcane/utils/Numeric.h"
18
19#include <optional>
20#include <regex>
21#include <string>
22
23/*---------------------------------------------------------------------------*/
24/*---------------------------------------------------------------------------*/
25
26namespace Arcane
27{
28
29/*---------------------------------------------------------------------------*/
30/*---------------------------------------------------------------------------*/
31
33compare(bool compare_dimension_too)
34{
35 const Integer dim1 = m_simple_table_internal_mng_reference.numberOfRows();
36 const Integer dim2 = m_simple_table_internal_mng_reference.numberOfColumns();
37
38 const Integer dim1_to_compare = m_simple_table_internal_mng_to_compare.numberOfRows();
39 const Integer dim2_to_compare = m_simple_table_internal_mng_to_compare.numberOfColumns();
40
41 if (compare_dimension_too && (dim1 != dim1_to_compare || dim2 != dim2_to_compare)) {
42 m_simple_table_internal_reference->m_parallel_mng->traceMng()->warning() << "Dimensions not equals -- Expected dimensions: "
43 << dim1 << "x" << dim2 << " -- Found dimensions: "
44 << dim1_to_compare << "x" << dim2_to_compare;
45 return false;
46 }
47
48 Integer error_count = 0;
49 const Integer max_error_print = 10;
50
51 for (Integer i = 0; i < dim1; i++) {
52 String row = m_simple_table_internal_mng_reference.rowName(i);
53 // On regarde si l'on doit comparer la ligne actuelle.
54 // On regarde si la ligne est présente dans le STI to_compare.
55 if (!_exploreRows(row) || m_simple_table_internal_mng_to_compare.rowPosition(row) == -1)
56 continue;
57
58 auto search_epsilons_row = m_epsilons_row.find(row);
59 Real epsilon_row = -1.0;
60 if (search_epsilons_row != m_epsilons_row.end()) {
61 epsilon_row = search_epsilons_row->second;
62 }
63
64 for (Integer j = 0; j < dim2; j++) {
65 String column = m_simple_table_internal_mng_reference.columnName(j);
66 // On regarde si l'on doit comparer la colonne actuelle.
67 // On regarde si la colonne est présente dans le STI to_compare.
68 if (!_exploreColumn(column) || m_simple_table_internal_mng_to_compare.columnPosition(column) == -1)
69 continue;
70
71 const Real val1 = m_simple_table_internal_mng_reference.element(column, row, false);
72 const Real val2 = m_simple_table_internal_mng_to_compare.element(column, row, false);
73
74 auto search_epsilons_column = m_epsilons_column.find(column);
75 Real epsilon_column = -1.0;
76 if (search_epsilons_column != m_epsilons_column.end()) {
77 epsilon_column = search_epsilons_column->second;
78 }
79
80 Real final_epsilon = math::max(epsilon_row, epsilon_column);
81
82 if ((final_epsilon < 0 && !math::isNearlyEqual(val1, val2)) || (final_epsilon >= 0 && !math::isNearlyEqualWithEpsilon(val1, val2, final_epsilon))) {
83
84 if (error_count < max_error_print) {
85 Real diff = math::abs((val1 - val2) / (math::abs(val1) + math::abs(val2)));
86
87 m_simple_table_internal_reference->m_parallel_mng->traceMng()->warning()
88 << std::scientific << std::setprecision(std::numeric_limits<Real>::digits10)
89 << "Values not equals -- Column name: \"" << column << "\" -- Row name: \"" << row
90 << "\" -- Expected value: " << val1 << " -- Found value: " << val2
91 << " -- Epsilon: " << final_epsilon << " -- Relative difference: " << diff;
92 }
93 error_count++;
94 }
95 }
96 }
97 if (error_count > 0) {
98 m_simple_table_internal_reference->m_parallel_mng->traceMng()->warning()
99 << "Number of errors: " << error_count;
100 return false;
101 }
102 return true;
103}
104
106compareElem(const String& column_name, const String& row_name)
107{
108 if (m_simple_table_internal_mng_to_compare.rowPosition(row_name) == -1 || m_simple_table_internal_mng_to_compare.columnPosition(column_name) == -1)
109 return false;
110
111 const Real val2 = m_simple_table_internal_mng_to_compare.element(column_name, row_name, false);
112
113 return compareElem(val2, column_name, row_name);
114}
115
117compareElem(Real elem, const String& column_name, const String& row_name)
118{
119 if (m_simple_table_internal_mng_reference.rowPosition(row_name) == -1 || m_simple_table_internal_mng_reference.columnPosition(column_name) == -1)
120 return false;
121
122 auto search_epsilons_row = m_epsilons_row.find(row_name);
123 Real epsilon_row = -1.0;
124 if (search_epsilons_row != m_epsilons_row.end()) {
125 epsilon_row = search_epsilons_row->second;
126 }
127
128 auto search_epsilons_column = m_epsilons_column.find(column_name);
129 Real epsilon_column = -1.0;
130 if (search_epsilons_column != m_epsilons_column.end()) {
131 epsilon_column = search_epsilons_column->second;
132 }
133
134 Real final_epsilon = math::max(epsilon_row, epsilon_column);
135
136 const Real val1 = m_simple_table_internal_mng_reference.element(column_name, row_name, false);
137
138 if ((final_epsilon < 0 && !math::isNearlyEqual(val1, elem)) || (final_epsilon >= 0 && !math::isNearlyEqualWithEpsilon(val1, elem, final_epsilon))) {
139 return false;
140 }
141 return true;
142}
143
146{
147 m_regex_rows = "";
148 m_is_excluding_regex_rows = false;
149
150 m_regex_columns = "";
151 m_is_excluding_regex_columns = false;
152
153 m_rows_to_compare.clear();
154 m_columns_to_compare.clear();
155
156 m_epsilons_column.clear();
157 m_epsilons_row.clear();
158}
159
161addColumnForComparing(const String& column_name)
162{
163 m_columns_to_compare.add(column_name);
164 return true;
165}
167addRowForComparing(const String& row_name)
168{
169 m_rows_to_compare.add(row_name);
170 return true;
171}
172
174isAnArrayExclusiveColumns(bool is_exclusive)
175{
176 m_is_excluding_array_columns = is_exclusive;
177}
179isAnArrayExclusiveRows(bool is_exclusive)
180{
181 m_is_excluding_array_rows = is_exclusive;
182}
183
185editRegexColumns(const String& regex_column)
186{
187 m_regex_columns = regex_column;
188}
190editRegexRows(const String& regex_row)
191{
192 m_regex_rows = regex_row;
193}
194
196isARegexExclusiveColumns(bool is_exclusive)
197{
198 m_is_excluding_regex_columns = is_exclusive;
199}
201isARegexExclusiveRows(bool is_exclusive)
202{
203 m_is_excluding_regex_rows = is_exclusive;
204}
205
206/*---------------------------------------------------------------------------*/
207/*---------------------------------------------------------------------------*/
208
210addEpsilonColumn(const String& column_name, Real epsilon)
211{
212 m_epsilons_column[column_name] = epsilon;
213 return true;
214}
215
217addEpsilonRow(const String& row_name, Real epsilon)
218{
219 m_epsilons_row[row_name] = epsilon;
220 return true;
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
228{
229 return m_simple_table_internal_reference;
230}
231
234{
235 if (sti_ref.isNull())
236 ARCANE_FATAL("La réference passée en paramètre est Null.");
237 m_simple_table_internal_reference = sti_ref;
238 m_simple_table_internal_mng_reference.setInternal(m_simple_table_internal_reference);
239}
240
243{
244 return m_simple_table_internal_to_compare;
245}
246
249{
250 if (sti_to_compare.isNull())
251 ARCANE_FATAL("La réference passée en paramètre est Null.");
252 m_simple_table_internal_to_compare = sti_to_compare;
253 m_simple_table_internal_mng_to_compare.setInternal(m_simple_table_internal_to_compare);
254}
255
256/*---------------------------------------------------------------------------*/
257/*---------------------------------------------------------------------------*/
258
268_exploreColumn(const String& column_name)
269{
270 // S'il n'y a pas de précisions, on compare toutes les colonnes.
271 if (m_columns_to_compare.empty() && m_regex_columns.empty()) {
272 return true;
273 }
274
275 if (m_columns_to_compare.contains(column_name)) {
276 return !m_is_excluding_array_columns;
277 }
278
279 // S'il n'est pas dans le tableau et qu'il n'a a pas de regex, on return false.
280 else if (m_regex_columns.empty()) {
281 return m_is_excluding_array_columns;
282 }
283
284 // Sinon, on regarde aussi la regex.
285 // TODO : Voir s'il y a un interet de faire des regex en mode JS.
286 std::regex self_regex(m_regex_columns.localstr(), std::regex_constants::ECMAScript | std::regex_constants::icase);
287
288 // Si quelque chose dans le nom correspond à la regex.
289 if (std::regex_search(column_name.localstr(), self_regex)) {
290 return !m_is_excluding_regex_columns;
291 }
292
293 // Sinon.
294 return m_is_excluding_regex_columns;
295}
296
306_exploreRows(const String& row_name)
307{
308 // S'il n'y a pas de précisions, on compare toutes les lignes.
309 if (m_rows_to_compare.empty() && m_regex_rows.empty()) {
310 return true;
311 }
312
313 // D'abord, on regarde si le nom de la ligne est dans le tableau.
314 if (m_rows_to_compare.contains(row_name)) {
315 return !m_is_excluding_array_rows;
316 }
317 // S'il n'est pas dans le tableau et qu'il n'a a pas de regex, on return false.
318 else if (m_regex_rows.empty()) {
319 return m_is_excluding_array_rows;
320 }
321
322 // Sinon, on regarde aussi la regex.
323 // TODO : Voir s'il y a un interet de faire des regex en mode JS.
324 std::regex self_regex(m_regex_rows.localstr(), std::regex_constants::ECMAScript | std::regex_constants::icase);
325 if (std::regex_search(row_name.localstr(), self_regex)) {
326 return !m_is_excluding_regex_rows;
327 }
328
329 return m_is_excluding_regex_rows;
330}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
335} // End namespace Arcane
336
337/*---------------------------------------------------------------------------*/
338/*---------------------------------------------------------------------------*/
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Référence à une instance.
bool isNull() const
Indique si le compteur référence une instance non nulle.
bool compare(bool compare_dimension_too) override
Méthode permettant de comparer les valeurs des deux STI.
Ref< SimpleTableInternal > internalRef() override
Méthode permettant de récupérer une référence vers l'objet SimpleTableInternal "de référence" utilisé...
bool _exploreColumn(const String &column_name)
Méthode permettant de savoir si la colonne avec le nom column_name doit être exploré ou non.
void setInternalToCompare(const Ref< SimpleTableInternal > &simple_table_internal) override
Méthode permettant de définir une référence vers SimpleTableInternal "à comparer".
void isAnArrayExclusiveRows(bool is_exclusive) override
Méthode permettant de définir si le tableau de lignes représente les lignes à inclure dans la compara...
void setInternalRef(const Ref< SimpleTableInternal > &simple_table_internal) override
Méthode permettant de définir une référence vers un SimpleTableInternal "de référence".
void isAnArrayExclusiveColumns(bool is_exclusive) override
Méthode permettant de définir si le tableau de colonnes représente les colonnes à inclure dans la com...
Ref< SimpleTableInternal > internalToCompare() override
Méthode permettant de récupérer une référence vers l'objet SimpleTableInternal "à comparer" utilisé.
bool addEpsilonRow(const String &row_name, Real epsilon) override
Méthode permettant de définir un epsilon pour une ligne donnée. Cet epsilon doit être positif pour êt...
bool addRowForComparing(const String &row_name) override
Méthode permettant d'ajouter une ligne dans la liste des lignes à comparer.
bool _exploreRows(const String &row_name)
Méthode permettant de savoir si la ligne avec le nom column_name doit être exploré ou non.
bool compareElem(const String &column_name, const String &row_name) override
Méthode permettant de comparer uniquement un élement. Les deux SimpleTableInternal sont représentés p...
void isARegexExclusiveRows(bool is_exclusive) override
Méthode permettant de demander à ce que l'expression régulière exclut des lignes au lieu d'en inclure...
bool addColumnForComparing(const String &column_name) override
Méthode permettant d'ajouter une colonne dans la liste des colonnes à comparer.
void editRegexColumns(const String &regex_column) override
Méthode permettant d'ajouter une expression régulière permettant de déterminer les colonnes à compare...
void editRegexRows(const String &regex_row) override
Méthode permettant d'ajouter une expression régulière permettant de déterminer les lignes à comparer.
void isARegexExclusiveColumns(bool is_exclusive) override
Méthode permettant de demander à ce que l'expression régulière exclut des colonnes au lieu d'en inclu...
void clearComparator() override
Méthode permettant de vider les tableaux de comparaison et les expressions régulières....
bool addEpsilonColumn(const String &column_name, Real epsilon) override
Méthode permettant de définir un epsilon pour une colonne donnée. Cet epsilon doit être positif pour ...
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
Definition String.cc:227
T max(const T &a, const T &b, const T &c)
Retourne le maximum de trois éléments.
Definition MathUtils.h:392
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:235
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Teste si deux valeurs sont à un peu près égales. Pour les types entiers, cette fonction est équivalen...
Definition Numeric.h:212
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
double Real
Type représentant un réel.