Arcane  4.1.12.0
Developer documentation
Loading...
Searching...
No Matches
SimpleTableInternalComparator.cc
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/* SimpleTableInternalComparator.cc (C) 2000-2022 */
9/* */
10/* Comparator for 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 // We check if we should compare the current row.
54 // We check if the row is present in the 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 // We check if we should compare the current column.
67 // We check if the column is present in the 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("The reference passed as parameter is 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("The reference passed as parameter is 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 // If there are no specifications, all columns are compared.
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 // If it is not in the table and there is no regex, we return false.
280 else if (m_regex_columns.empty()) {
281 return m_is_excluding_array_columns;
282 }
283
284 // Otherwise, we also check the regex.
285 // TODO: See if there is any benefit to using JS mode regex.
286 std::regex self_regex(m_regex_columns.localstr(), std::regex_constants::ECMAScript | std::regex_constants::icase);
287
288 // If something in the name matches the regex.
289 if (std::regex_search(column_name.localstr(), self_regex)) {
290 return !m_is_excluding_regex_columns;
291 }
292
293 // Otherwise.
294 return m_is_excluding_regex_columns;
295}
296
306_exploreRows(const String& row_name)
307{
308 // If there are no specifications, all rows are compared.
309 if (m_rows_to_compare.empty() && m_regex_rows.empty()) {
310 return true;
311 }
312
313 // First, we check if the row name is in the table.
314 if (m_rows_to_compare.contains(row_name)) {
315 return !m_is_excluding_array_rows;
316 }
317 // If it is not in the table and there is no regex, we return false.
318 else if (m_regex_rows.empty()) {
319 return m_is_excluding_array_rows;
320 }
321
322 // Otherwise, we also check the regex.
323 // TODO: See if there is any benefit to using JS mode regex.
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 throwing a FatalErrorException.
bool isNull() const
Indicates if the counter references a non-null instance.
Reference to an instance.
bool compare(bool compare_dimension_too) override
Method allowing comparison of the values of the two STIs.
Ref< SimpleTableInternal > internalRef() override
Method allowing retrieval of a reference to the used "reference" SimpleTableInternal object.
bool _exploreColumn(const String &column_name)
Method to determine whether the column named column_name should be explored or not.
void setInternalToCompare(const Ref< SimpleTableInternal > &simple_table_internal) override
Method allowing definition of a reference to the "to compare" SimpleTableInternal.
void isAnArrayExclusiveRows(bool is_exclusive) override
Method allowing definition of whether the row array represents rows to include in the comparison (fal...
void setInternalRef(const Ref< SimpleTableInternal > &simple_table_internal) override
Method allowing definition of a reference to a "reference" SimpleTableInternal.
void isAnArrayExclusiveColumns(bool is_exclusive) override
Method allowing definition of whether the column array represents columns to include in the compariso...
Ref< SimpleTableInternal > internalToCompare() override
Method allowing retrieval of a reference to the used "to compare" SimpleTableInternal object.
bool addEpsilonRow(const String &row_name, Real epsilon) override
Method allowing the definition of an epsilon for a given row. This epsilon must be positive to be con...
bool addRowForComparing(const String &row_name) override
Method allowing the addition of a row to the list of rows to compare.
bool _exploreRows(const String &row_name)
Method to determine whether the row named column_name should be explored or not.
bool compareElem(const String &column_name, const String &row_name) override
Method allowing comparison of a single element. Both SimpleTableInternals are represented by Refs,...
void isARegexExclusiveRows(bool is_exclusive) override
Method allowing specification that the regular expression excludes rows instead of including them.
bool addColumnForComparing(const String &column_name) override
Method allowing the addition of a column to the list of columns to compare.
void editRegexColumns(const String &regex_column) override
Method allowing the addition of a regular expression to determine the columns to compare.
void editRegexRows(const String &regex_row) override
Method allowing the addition of a regular expression to determine the rows to compare.
void isARegexExclusiveColumns(bool is_exclusive) override
Method allowing specification that the regular expression excludes columns instead of including them.
void clearComparator() override
Method allowing the clearing of comparison arrays and regular expressions. Does not affect the STIs.
bool addEpsilonColumn(const String &column_name, Real epsilon) override
Method allowing the definition of an epsilon for a given column. This epsilon must be positive to be ...
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
Definition String.cc:229
T max(const T &a, const T &b, const T &c)
Returns the maximum of three elements.
Definition MathUtils.h:407
constexpr __host__ __device__ bool isNearlyEqualWithEpsilon(const _Type &a, const _Type &b, const _Type &epsilon)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
Definition Numeric.h:242
constexpr __host__ __device__ bool isNearlyEqual(const _Type &a, const _Type &b)
Tests if two values are approximately equal. For integer types, this function is equivalent to IsEqua...
Definition Numeric.h:219
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.