Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScalarTraits_test.cpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
11 #include "Teuchos_ScalarTraits.hpp"
16 #include "Teuchos_Version.hpp"
17 
19 
20 namespace {
21 
22 //
23 // Output of the ordinal that will avoid printing non-asci chars.
24 //
25 // The issue is that if you just print a raw char then if it prints non-asci
26 // character, it can not be printed in some cases and causes trouble with
27 // CTest/CDash.
28 //
29 
30 // For general types, just print the type
31 template <class T>
32 T outputOrdinal(const T &t)
33 {
34  return t;
35 }
36 
37 // For char, print the int value (avoid non-ansi chars)
38 int outputOrdinal(const char& t)
39 {
40  return t;
41 }
42 
43 
44 //
45 // Type outputting
46 //
47 
48 template <class T>
49 void TYPE_CHAIN_A(Teuchos::FancyOStream &out) {
50  typedef typename Teuchos::ScalarTraits<T>::doublePrecision double_type;
51 
52  T b;
53  // double_type d; // unused
54  out << Teuchos::typeName (b);
55  if (! std::is_same_v<T, double_type>) {
56  out << " -> ";
57  TYPE_CHAIN_A<double_type>(out);
58  }
59 }
60 
61 template <class T>
62 void TYPE_CHAIN_D(Teuchos::FancyOStream &out) {
63  typedef typename Teuchos::ScalarTraits<T>::halfPrecision half_type;
64 
65  T b;
66  // half_type d; // unused
67  out << Teuchos::typeName (b);
68 
69  if (! std::is_same_v<T, half_type>) {
70  out << " -> ";
71  TYPE_CHAIN_D<half_type>(out);
72  }
73 }
74 
75 
76 inline std::string passfail(bool result)
77 {
78  return ( result ? "passed" : "failed" );
79 }
80 
81 
82 template<class Scalar>
83 bool testScalarTraits(
85  )
86 {
87 
89 
90  bool success = true;
91 
92  out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";
93 
94  Teuchos::OSTab tab(out);
95 
96  const Scalar nan = ST::nan();
97 
98  out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
99  out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";
100 
101  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(ST::one()), false, out, success);
102 
103  out << "\nTesting that squareroot(NaN) == NaN! ...\n";
104  {
105  const Scalar sqrtNan = ST::squareroot(nan);
106  out << "squareroot("<<nan<<") = " << sqrtNan << "\n";
107  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
108  }
109 
110  out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
111  {
112  const Scalar negNan = -nan;
113  const Scalar sqrtNegNan = ST::squareroot(negNan);
114  out << "squareroot("<<negNan<<") = " << sqrtNegNan << "\n";
115  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegNan), true, out, success);
116  }
117 
118  if (ST::isComplex == false)
119  {
120  out << "\nTesting that squareroot(-1) == NaN! ...\n";
121  {
122  const Scalar negOne = -ST::one();
123  const Scalar sqrtNegOne = ST::squareroot(negOne);
124  out << "squareroot("<<negOne<<") = " << sqrtNegOne << "\n";
125  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegOne), true, out, success);
126  }
127  }
128 
129 #ifdef HAVE_NUMERIC_LIMITS
130 
131  out << "\nTesting that squareroot(quiet_NaN) == NaN! ...\n";
132  {
133  const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
134  const Scalar sqrtNan = ST::squareroot(nan);
135  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
136  }
137 
138  out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
139  {
140  const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
141  const Scalar sqrtNan = ST::squareroot(nan);
142  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
143  }
144 
145  out << "\nTesting that squareroot(inf) == NaN! ...\n";
146  {
147  const Scalar inf = std::numeric_limits<Scalar>::infinity();
148  const Scalar sqrtInf = ST::squareroot(inf);
149  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtInf), true, out, success);
150  }
151 
152 #endif // HAVE_NUMERIC_LIMITS
153 
154  return success;
155 
156 }
157 
158 
159 template<class Ordinal>
160 bool testOrdinalTraits(
162  )
163 {
164 
166 
167  bool success = true;
168  bool result;
169 
170  out << "\nTesting: " << Teuchos::TypeNameTraits<OT>::name() << " ...\n";
171 
172  Teuchos::OSTab tab(out);
173 
174  const Ordinal zero = OT::zero();
175  const Ordinal one = OT::one();
176  const Ordinal max = OT::max();
177  const Ordinal invalid = OT::invalid();
178  out << "\nmax() == " << outputOrdinal(max) << "\n";
179  out << "\ninvalid() == " << outputOrdinal(invalid) << "\n";
180 
181  out << "\nTesting that zero() * one() == zero() ...\n";
182  {
183  const Ordinal zto = zero*one;
184  result = (zto == zero);
185  if (!result) success = false;
186  out
187  << "zero*one = " << outputOrdinal(zto) << " == " << outputOrdinal(zero) << " : "
188  << passfail(result) << "\n";
189  }
190 
191  out << "\nTesting that one() * one() == one() ...\n";
192  {
193  const Ordinal oto = one*one;
194  result = (oto == one);
195  if (!result) success = false;
196  out
197  << "one*one = " << outputOrdinal(oto) << " == " << outputOrdinal(one) << " : "
198  << passfail(result) << "\n";
199  }
200 
201  out << "\nTesting that one() + zero() == zero() + one() == one() ...\n";
202  {
203  const Ordinal opz = one+zero;
204  const Ordinal zpo = zero+one;
205  result = (opz == one) && (zpo == one);
206  if (!result) success = false;
207  out
208  << "one+zero = " << outputOrdinal(opz) << " == zero+one = "
209  << outputOrdinal(zpo) << " == " << outputOrdinal(one) << " : "
210  << passfail(result) << "\n";
211  }
212 
213  out << "\nTesting that one() - one() == zero() ...\n";
214  {
215  const Ordinal omo = one-one;
216  result = (omo == zero);
217  if (!result) success = false;
218  out
219  << "one-one = " << outputOrdinal(omo) << " == " << outputOrdinal(zero) << " : "
220  << passfail(result) << "\n";
221  }
222 
223  out << "\nTesting that zero() < one() <= max() ...\n";
224  {
225  result = (zero < one) && (one <= max) && (zero < max);
226  if (!result) success = false;
227  out
228  << "(zero < one) = " << (zero < one) << " == "
229  << "(one <= max) = " << (one <= max) << " == "
230  << "(zero < max) = " << (zero < max) << " == "
231  << true << " : "
232  << passfail(result) << "\n";
233  }
234 
235  out << "\nTesting that invalid() not in [zero(),max()]...\n";
236  {
237  result = !( (invalid > zero || invalid==zero) && (invalid <= max) );
238  if (!result) success = false;
239  out
240  << "invalid in [zero,max] == false : " << passfail(result) << "\n";
241  }
242 
243  return success;
244 
245 }
246 
247 
248 } // namespace
249 
250 
251 int main( int argc, char* argv[] ) {
252 
254 
255  bool success = true;
256  bool result;
257 
258  Teuchos::GlobalMPISession mpiSession(&argc,&argv);
259  //const int procRank = Teuchos::GlobalMPISession::getRank();
260 
263 
264  try {
265 
266  // Read options from the commandline
267  CommandLineProcessor clp(false); // Don't throw exceptions
268  CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
269  if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
270  *out << "\nEnd Result: TEST FAILED" << std::endl;
271  return parse_return;
272  }
273 
274  result = testScalarTraits<float>(*out);
275  if(!result) success = false;
276 
277  result = testScalarTraits<double>(*out);
278  if(!result) success = false;
279 
280  result = testOrdinalTraits<char>(*out);
281  if(!result) success = false;
282 
283  result = testOrdinalTraits<short int>(*out);
284  if(!result) success = false;
285 
286  result = testOrdinalTraits<int>(*out);
287  if(!result) success = false;
288 
289  result = testOrdinalTraits<long int>(*out);
290  if(!result) success = false;
291 
292  result = testOrdinalTraits<size_t>(*out);
293  if(!result) success = false;
294 
295  result = testOrdinalTraits<long long int>(*out);
296  if(!result) success = false;
297 
298 #ifdef HAVE_TEUCHOS___INT64
299  result = testOrdinalTraits<__int64>(*out);
300  if(!result) success = false;
301 
302  result = testOrdinalTraits<unsigned __int64>(*out);
303  if(!result) success = false;
304 #endif
305 
306 #ifdef HAVE_TEUCHOS_COMPLEX
307  result = testScalarTraits<std::complex<double> >(*out);
308  if(!result) success = false;
309 
310  result = testScalarTraits<std::complex<float> >(*out);
311  if(!result) success = false;
312 #endif // HAVE_TEUCHOS_COMPLEX
313 
314 #ifdef HAVE_TEUCHOSCORE_KOKKOS
315  result = testScalarTraits<Kokkos::complex<double> >(*out);
316  if(!result) success = false;
317 
318  result = testScalarTraits<Kokkos::complex<float> >(*out);
319  if(!result) success = false;
320 #endif // HAVE_TEUCHOSCORE_KOKKOS
321 
322 #ifdef HAVE_TEUCHOSCORE_QUADMATH
323  result = testScalarTraits<__float128>(*out);
324  if(!result) success = false;
325 #endif // HAVE_TEUCHOSCORE_QUADMATH
326 
327 #ifdef HAVE_TEUCHOS_QD
328  result = testScalarTraits<dd_real>(*out);
329  if(!result) success = false;
330  result = testScalarTraits<qd_real>(*out);
331  if(!result) success = false;
332 #endif
333 
334  }
335  TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
336 
337  if(success)
338  *out << "\nEnd Result: TEST PASSED\n" << std::endl;
339  else
340  *out << "\nEnd Result: TEST FAILED\n" << std::endl;
341 
342  return ( success ? 0 : 1 );
343 
344 }
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
#define TEUCHOS_TEST_EQUALITY_CONST(v1, v2, out, success)
Test that an object is equal to a given constant.
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object...
Initialize, finalize, and query the global MPI session.
const std::string passfail(const bool result)
Return &quot;passed&quot; or &quot;failed&quot;.
This structure defines some basic traits for a scalar field type.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
This structure defines some basic traits for the ordinal field type.
T doublePrecision
Typedef for double precision.
int main(int argc, char *argv[])
Utilities to make writing tests easier.
Defines basic traits for the ordinal field type.
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
Defines basic traits for the scalar field type.
Smart reference counting pointer class for automatic garbage collection.
T halfPrecision
Typedef for half precision.
RCP< basic_FancyOStream< CharT, Traits > > tab(const RCP< basic_FancyOStream< CharT, Traits > > &out, const int tabs=1, const std::basic_string< CharT, Traits > linePrefix="")
Create a tab for an RCP-wrapped basic_FancyOStream object to cause the indentation of all output auto...
Class that helps parse command line input arguments from (argc,argv[]) and set options.