Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
HPReal.h
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/* HPReal.h (C) 2000-2019 */
9/* */
10/* Réel haute-précision. */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_UTILS_HPREAL_H
13#define ARCANE_UTILS_HPREAL_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
17#include "arcane/utils/Numeric.h"
18
19#include <iosfwd>
20
21/*---------------------------------------------------------------------------*/
22/*---------------------------------------------------------------------------*/
23
24namespace Arcane
25{
26/*---------------------------------------------------------------------------*/
27/*---------------------------------------------------------------------------*/
160class ARCANE_UTILS_EXPORT HPReal
161{
162 public:
167
169 explicit HPReal(double avalue)
170 : m_value(avalue)
171 , m_correction(0.0)
172 {}
173
175 HPReal(double avalue, double acorrection)
176 : m_value(avalue)
177 , m_correction(acorrection)
178 {}
179
181 Real value() const { return m_value; }
182
184 Real correction() const { return m_correction; }
185
187 void operator+=(Real v)
188 {
189 *this = accumulate(v, *this);
190 }
191
193 inline void operator+=(HPReal v)
194 {
195 *this = reduce(*this, v);
196 }
197
199 inline Real toReal() const
200 {
201 return value() + correction();
202 }
203
206 {
207 return reduce(*this, b);
208 }
209
211 void operator*=(Real v)
212 {
213 *this = product(v, *this);
214 }
215
217 inline void operator*=(HPReal v)
218 {
219 *this = product(*this, v);
220 }
221
223 void operator/=(Real v)
224 {
225 *this = div2(v, *this);
226 }
227
229 inline void operator/=(HPReal v)
230 {
231 *this = div2(*this, v);
232 }
233
238 std::istream& assign(std::istream& i);
240 std::ostream& print(std::ostream& o) const;
242 std::ostream& printPretty(std::ostream& o) const;
243
244 public:
246 static HPReal zero() { return HPReal(0.0); }
247
248 public:
249 static HPReal accumulate(Real a, HPReal b)
250 {
251 HPReal x(_doTwoSum(a, b.value()));
252 Real c = x.correction() + b.correction();
253 return _doQuickTwoSum(x.value(), c);
254 }
255
256 // Mpi passe par la
257 static HPReal reduce(HPReal a, HPReal b)
258 {
259 HPReal x(_doTwoSum(a.value(), b.value()));
260 Real c = x.correction() + a.correction() + b.correction();
261 return _doQuickTwoSum(x.value(), c);
262 }
263
264 // algo 11 de AC_TWOPRODUCTS Ref 2
265 static HPReal product(HPReal a, HPReal b)
266 {
267 HPReal x(_doTwoProducts(a.value(), b.value()));
268 Real w = x.correction() + (a.value() * b.correction() + b.value() * a.correction());
269 return HPReal(x.value(), w);
270 }
271 // algo 11 de AC_TWOPRODUCTS Ref 2
272 static HPReal product(Real a, HPReal b)
273 {
274 HPReal x(_doTwoProducts(a, b.value()));
275 Real w = x.correction() + (a * b.correction());
276 return HPReal(x.value(), w);
277 }
278
279 // algo div2 Ref 6 div2 = a/b
280 // j'ai mis des parentheses dans l'evaluation de w pour forcer un ordre quelque soir les options de compil
281 // ATTENTION les 2 dernieres lignes de l'algo div2 ne sont pas mises (on ne renormalise pas)
282 // l'algo "mul2" les contient aussi et ne les a pas mises aussi pour "product" car l'algo 11 de la Ref 2 n'en n'a pas (a mon humble avis)
283 static HPReal div2(HPReal a, HPReal b)
284 {
285 Real c = a.value() / b.value();
286 HPReal u(_doTwoProducts(c, b.value()));
287 Real w = ((((a.value() - u.value()) + -u.correction()) + a.correction()) - c * b.correction()) / b.value();
288 return HPReal(c, w);
289 }
290 // algo div2 Ref 6 div2 = a/b
291 static HPReal div2(Real b, HPReal a)
292 {
293 Real c = a.value() / b;
294 HPReal u(_doTwoProducts(c, b));
295 Real w = (((a.value() - u.value()) + -u.correction()) + a.correction()) / b;
296 return HPReal(c, w);
297 }
298
299 private:
300 Real m_value;
301 Real m_correction;
302
303 private:
304 // correction des ()
305 static HPReal _doTwoSum(Real a, Real b)
306 {
307 Real value = a + b;
308 Real approx_b = value - a;
309 Real sum_error = (a - (value - approx_b)) + (b - approx_b);
310 return HPReal(value, sum_error);
311 }
312 // correction tests de la valeur de a et b et on mets des valeurs absolues
313 static HPReal _doQuickTwoSum(Real a1, Real b1)
314 {
315 Real a = a1;
316 Real b = b1;
317 if (std::abs(b1) > std::abs(a1)) {
318 a = b1;
319 b = a1;
320 }
321 Real value = a + b;
322 Real error_value = (b - (value - a));
323 return HPReal(value, error_value);
324 }
325 // algo 4 ref 2 ou algo 2.4 ref 3 ou algo 6 p.4
326 static HPReal _doTwoProducts(Real a, Real b)
327 {
328 Real x = a * b;
329 HPReal aw = SPLIT(a);
330 HPReal bw = SPLIT(b);
331 Real y = aw.correction() * bw.correction() - (((x - aw.value() * bw.value()) - aw.correction() * bw.value()) - aw.value() * bw.correction());
332 return HPReal(x, y);
333 }
334 static HPReal SPLIT(Real a)
335 {
336 const Real f = 134217729; // 1+ 2^ceil(52/2);
337 Real c = f * a;
338 Real x = c - (c - a);
339 Real y = a - x;
340 return HPReal(x, y);
341 }
342};
343
344/*---------------------------------------------------------------------------*/
345/*---------------------------------------------------------------------------*/
346
347inline bool
348operator<(const HPReal& a, const HPReal& b)
349{
350 return a.toReal() < b.toReal();
351}
352
353inline bool
354operator>(const HPReal& a, const HPReal& b)
355{
356 return a.toReal() > b.toReal();
357}
358
359inline bool
360operator==(const HPReal& a, const HPReal& b)
361{
362 return a.value() == b.value() && a.correction() == b.correction();
363}
364
365inline bool
366operator!=(const HPReal& a, const HPReal& b)
367{
368 return !operator==(a, b);
369}
370
371inline HPReal
372operator+(const HPReal& a, const HPReal& b)
373{
374 return HPReal::reduce(a, b);
375}
376
377/*---------------------------------------------------------------------------*/
378/*---------------------------------------------------------------------------*/
379
380inline std::ostream&
381operator<<(std::ostream& o, HPReal t)
382{
383 return t.printPretty(o);
384}
385
386inline std::istream&
387operator>>(std::istream& i, HPReal& t)
388{
389 return t.assign(i);
390}
391
392/*---------------------------------------------------------------------------*/
393/*---------------------------------------------------------------------------*/
394
395} // End namespace Arcane
396
397/*---------------------------------------------------------------------------*/
398/*---------------------------------------------------------------------------*/
399
400#endif
Classe implémentant un réel Haute Précision.
Definition HPReal.h:161
void operator*=(HPReal v)
multiplie un HPReal v en conservant l'erreur (réduction)
Definition HPReal.h:217
HPReal()
Constructeur par défaut sans initialisation.
Definition HPReal.h:166
static HPReal zero()
Valeur zéro.
Definition HPReal.h:246
HPReal reduce(HPReal b) const
Ajoute un HPReal v en conservant l'erreur (réduction)
Definition HPReal.h:205
Real toReal() const
Converti l'instance en un Real.
Definition HPReal.h:199
void operator+=(Real v)
Ajoute un Real en conservant l'erreur.
Definition HPReal.h:187
HPReal(double avalue)
Créé un réel HP avec la valeur value et la correction correction.
Definition HPReal.h:169
void operator/=(Real v)
multiplie un Real en conservant l'erreur.
Definition HPReal.h:223
void operator+=(HPReal v)
Ajoute un HPReal v en conservant l'erreur (réduction)
Definition HPReal.h:193
HPReal(double avalue, double acorrection)
Créé un réel HP avec la valeur value et la correction correction.
Definition HPReal.h:175
Real correction() const
Correction interne.
Definition HPReal.h:184
void operator*=(Real v)
multiplie un Real en conservant l'erreur.
Definition HPReal.h:211
void operator/=(HPReal v)
multiplie un HPReal v en conservant l'erreur (réduction)
Definition HPReal.h:229
Real value() const
Valeur interne. En général, il faut utiliser toReal()
Definition HPReal.h:181
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
std::ostream & operator<<(std::ostream &o, eExecutionPolicy exec_policy)
Affiche le nom de la politique d'exécution.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
bool operator<(const Item &item1, const Item &item2)
Compare deux entités.
Definition Item.h:533
std::istream & operator>>(std::istream &istr, eItemKind &item_kind)
Opérateur d'entrée depuis un flot.