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 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 
44 #include "Teuchos_ScalarTraits.hpp"
49 #include "Teuchos_TypeTraits.hpp"
50 #include "Teuchos_Version.hpp"
51 
53 
54 namespace {
55 
56 //
57 // Output of the ordinal that will avoid printing non-asci chars.
58 //
59 // The issue is that if you just print a raw char then if it prints non-asci
60 // character, it can not be printed in some cases and causes trouble with
61 // CTest/CDash.
62 //
63 
64 // For general types, just print the type
65 template <class T>
66 T outputOrdinal(const T &t)
67 {
68  return t;
69 }
70 
71 // For char, print the int value (avoid non-ansi chars)
72 int outputOrdinal(const char& t)
73 {
74  return t;
75 }
76 
77 
78 //
79 // Type outputting
80 //
81 
82 template <class T>
83 void TYPE_CHAIN_A(Teuchos::FancyOStream &out) {
85  typedef typename Teuchos::ScalarTraits<T>::doublePrecision double_type;
86 
87  T b;
88  // double_type d; // unused
89  out << Teuchos::typeName (b);
90  if (! is_same<T, double_type>::value) {
91  out << " -> ";
92  TYPE_CHAIN_A<double_type>(out);
93  }
94 }
95 
96 template <class T>
97 void TYPE_CHAIN_D(Teuchos::FancyOStream &out) {
99  typedef typename Teuchos::ScalarTraits<T>::halfPrecision half_type;
100 
101  T b;
102  // half_type d; // unused
103  out << Teuchos::typeName (b);
104 
105  if (! is_same<T, half_type>::value) {
106  out << " -> ";
107  TYPE_CHAIN_D<half_type>(out);
108  }
109 }
110 
111 
112 inline std::string passfail(bool result)
113 {
114  return ( result ? "passed" : "failed" );
115 }
116 
117 
118 template<class Scalar>
119 bool testScalarTraits(
121  )
122 {
123 
125 
126  bool success = true;
127 
128  out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";
129 
130  Teuchos::OSTab tab(out);
131 
132  const Scalar nan = ST::nan();
133 
134  out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
135  out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";
136 
137  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(ST::one()), false, out, success);
138 
139  out << "\nTesting that squareroot(NaN) == NaN! ...\n";
140  {
141  const Scalar sqrtNan = ST::squareroot(nan);
142  out << "squareroot("<<nan<<") = " << sqrtNan << "\n";
143  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
144  }
145 
146  out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
147  {
148  const Scalar negNan = -nan;
149  const Scalar sqrtNegNan = ST::squareroot(negNan);
150  out << "squareroot("<<negNan<<") = " << sqrtNegNan << "\n";
151  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegNan), true, out, success);
152  }
153 
154  if (ST::isComplex == false)
155  {
156  out << "\nTesting that squareroot(-1) == NaN! ...\n";
157  {
158  const Scalar negOne = -ST::one();
159  const Scalar sqrtNegOne = ST::squareroot(negOne);
160  out << "squareroot("<<negOne<<") = " << sqrtNegOne << "\n";
161  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegOne), true, out, success);
162  }
163  }
164 
165 #ifdef HAVE_NUMERIC_LIMITS
166 
167  out << "\nTesting that squareroot(quiet_NaN) == NaN! ...\n";
168  {
169  const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
170  const Scalar sqrtNan = ST::squareroot(nan);
171  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
172  }
173 
174  out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
175  {
176  const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
177  const Scalar sqrtNan = ST::squareroot(nan);
178  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
179  }
180 
181  out << "\nTesting that squareroot(inf) == NaN! ...\n";
182  {
183  const Scalar inf = std::numeric_limits<Scalar>::infinity();
184  const Scalar sqrtInf = ST::squareroot(inf);
185  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtInf), true, out, success);
186  }
187 
188 #endif // HAVE_NUMERIC_LIMITS
189 
190  return success;
191 
192 }
193 
194 
195 template<class Ordinal>
196 bool testOrdinalTraits(
198  )
199 {
200 
202 
203  bool success = true;
204  bool result;
205 
206  out << "\nTesting: " << Teuchos::TypeNameTraits<OT>::name() << " ...\n";
207 
208  Teuchos::OSTab tab(out);
209 
210  const Ordinal zero = OT::zero();
211  const Ordinal one = OT::one();
212  const Ordinal max = OT::max();
213  const Ordinal invalid = OT::invalid();
214  out << "\nmax() == " << outputOrdinal(max) << "\n";
215  out << "\ninvalid() == " << outputOrdinal(invalid) << "\n";
216 
217  out << "\nTesting that zero() * one() == zero() ...\n";
218  {
219  const Ordinal zto = zero*one;
220  result = (zto == zero);
221  if (!result) success = false;
222  out
223  << "zero*one = " << outputOrdinal(zto) << " == " << outputOrdinal(zero) << " : "
224  << passfail(result) << "\n";
225  }
226 
227  out << "\nTesting that one() * one() == one() ...\n";
228  {
229  const Ordinal oto = one*one;
230  result = (oto == one);
231  if (!result) success = false;
232  out
233  << "one*one = " << outputOrdinal(oto) << " == " << outputOrdinal(one) << " : "
234  << passfail(result) << "\n";
235  }
236 
237  out << "\nTesting that one() + zero() == zero() + one() == one() ...\n";
238  {
239  const Ordinal opz = one+zero;
240  const Ordinal zpo = zero+one;
241  result = (opz == one) && (zpo == one);
242  if (!result) success = false;
243  out
244  << "one+zero = " << outputOrdinal(opz) << " == zero+one = "
245  << outputOrdinal(zpo) << " == " << outputOrdinal(one) << " : "
246  << passfail(result) << "\n";
247  }
248 
249  out << "\nTesting that one() - one() == zero() ...\n";
250  {
251  const Ordinal omo = one-one;
252  result = (omo == zero);
253  if (!result) success = false;
254  out
255  << "one-one = " << outputOrdinal(omo) << " == " << outputOrdinal(zero) << " : "
256  << passfail(result) << "\n";
257  }
258 
259  out << "\nTesting that zero() < one() <= max() ...\n";
260  {
261  result = (zero < one) && (one <= max) && (zero < max);
262  if (!result) success = false;
263  out
264  << "(zero < one) = " << (zero < one) << " == "
265  << "(one <= max) = " << (one <= max) << " == "
266  << "(zero < max) = " << (zero < max) << " == "
267  << true << " : "
268  << passfail(result) << "\n";
269  }
270 
271  out << "\nTesting that invalid() not in [zero(),max()]...\n";
272  {
273  result = !( (invalid > zero || invalid==zero) && (invalid <= max) );
274  if (!result) success = false;
275  out
276  << "invalid in [zero,max] == false : " << passfail(result) << "\n";
277  }
278 
279  return success;
280 
281 }
282 
283 
284 } // namespace
285 
286 
287 int main( int argc, char* argv[] ) {
288 
290 
291  bool success = true;
292  bool result;
293 
294  Teuchos::GlobalMPISession mpiSession(&argc,&argv);
295  //const int procRank = Teuchos::GlobalMPISession::getRank();
296 
299 
300  try {
301 
302  // Read options from the commandline
303  CommandLineProcessor clp(false); // Don't throw exceptions
304  CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
305  if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
306  *out << "\nEnd Result: TEST FAILED" << std::endl;
307  return parse_return;
308  }
309 
310  result = testScalarTraits<float>(*out);
311  if(!result) success = false;
312 
313  result = testScalarTraits<double>(*out);
314  if(!result) success = false;
315 
316  result = testOrdinalTraits<char>(*out);
317  if(!result) success = false;
318 
319  result = testOrdinalTraits<short int>(*out);
320  if(!result) success = false;
321 
322  result = testOrdinalTraits<int>(*out);
323  if(!result) success = false;
324 
325  result = testOrdinalTraits<long int>(*out);
326  if(!result) success = false;
327 
328  result = testOrdinalTraits<size_t>(*out);
329  if(!result) success = false;
330 
331  result = testOrdinalTraits<long long int>(*out);
332  if(!result) success = false;
333 
334 #ifdef HAVE_TEUCHOS___INT64
335  result = testOrdinalTraits<__int64>(*out);
336  if(!result) success = false;
337 
338  result = testOrdinalTraits<unsigned __int64>(*out);
339  if(!result) success = false;
340 #endif
341 
342 #ifdef HAVE_TEUCHOS_COMPLEX
343  result = testScalarTraits<std::complex<double> >(*out);
344  if(!result) success = false;
345 
346  result = testScalarTraits<std::complex<float> >(*out);
347  if(!result) success = false;
348 #endif // HAVE_TEUCHOS_COMPLEX
349 
350 #ifdef HAVE_TEUCHOSCORE_KOKKOSCORE
351  result = testScalarTraits<Kokkos::complex<double> >(*out);
352  if(!result) success = false;
353 
354  result = testScalarTraits<Kokkos::complex<float> >(*out);
355  if(!result) success = false;
356 #endif // HAVE_TEUCHOSCORE_KOKKOSCORE
357 
358 #ifdef HAVE_TEUCHOSCORE_QUADMATH
359  result = testScalarTraits<__float128>(*out);
360  if(!result) success = false;
361 #endif // HAVE_TEUCHOSCORE_QUADMATH
362 
363 #ifdef HAVE_TEUCHOS_QD
364  result = testScalarTraits<dd_real>(*out);
365  if(!result) success = false;
366  result = testScalarTraits<qd_real>(*out);
367  if(!result) success = false;
368 #endif
369 
370  }
371  TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
372 
373  if(success)
374  *out << "\nEnd Result: TEST PASSED\n" << std::endl;
375  else
376  *out << "\nEnd Result: TEST FAILED\n" << std::endl;
377 
378  return ( success ? 0 : 1 );
379 
380 }
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 ...
Default is_equal traits class has value equal to false, indicating that T1 and T2 are not equal...
#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...
Defines basic traits allowing evaluation of type equality.
Class that helps parse command line input arguments from (argc,argv[]) and set options.