|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Tpetra: Templated Linear Algebra Services Package 00005 // Copyright (2008) Sandia Corporation 00006 // 00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00008 // the U.S. Government retains certain rights in this software. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // ************************************************************************ 00040 // @HEADER 00041 00042 #ifndef __Teuchos_MatrixMarket_SetScientific_hpp 00043 #define __Teuchos_MatrixMarket_SetScientific_hpp 00044 00045 #include <Teuchos_ConfigDefs.hpp> 00046 #include <Teuchos_as.hpp> 00047 #include <Teuchos_ScalarTraits.hpp> 00048 #include <string> 00049 00050 00051 namespace Teuchos { 00052 namespace MatrixMarket { 00053 namespace details { 00064 template<class Scalar, const bool isFloatingPoint> 00065 class SetScientificImpl { 00066 public: 00068 typedef Scalar scalar_type; 00073 SetScientificImpl (std::ostream& out); 00079 ~SetScientificImpl (); 00080 }; 00081 00087 template<class Scalar> 00088 class SetScientificImpl<Scalar, true> { 00089 public: 00090 typedef Scalar scalar_type; 00091 00092 SetScientificImpl (std::ostream& out) : 00093 out_ (out), originalFlags_ (out.flags()) 00094 { 00095 typedef Teuchos::ScalarTraits<scalar_type> STS; 00096 typedef typename STS::magnitudeType magnitude_type; 00097 typedef Teuchos::ScalarTraits<magnitude_type> STM; 00098 00099 // Print floating-point values in scientific notation. 00100 out << std::scientific; 00101 00102 // We're writing decimal digits, so compute the number of 00103 // digits we need to get reasonable accuracy when reading 00104 // values back in. 00105 // 00106 // There is actually an algorithm, due to Guy Steele (yes, 00107 // Java's Guy Steele) et al., for idempotent printing of 00108 // finite-length floating-point values. We should actually 00109 // implement that algorithm, but I don't have time for that 00110 // now. Currently, I just print no more than (one decimal 00111 // digit more than (the number of decimal digits justified 00112 // by the precision of magnitude_type)). 00113 // 00114 // We need to use STM's log10() rather than (say) std::log10 00115 // here, because STM::base() returns a magnitude_type, not 00116 // one of C++'s standard integer types. 00117 const magnitude_type numDecDigits = STM::t() * STM::log10 (STM::base()); 00118 00119 // Round and add one. The cast to int should not overflow 00120 // unless STM::t() is _extremely_ large, so we don't need to 00121 // check for that case here. 00122 const magnitude_type one = STM::one(); 00123 const magnitude_type two = one + one; 00124 // Cast from magnitude_type to int, since std::ostream's 00125 // precision() method expects an int input. 00126 const int prec = 1 + Teuchos::as<int> (magnitude_type((two*numDecDigits + one) / two)); 00127 00128 // Set the number of (decimal) digits after the decimal 00129 // point to print. 00130 out.precision (prec); 00131 } 00132 00133 ~SetScientificImpl () { 00134 out_.flags (originalFlags_); 00135 } 00136 00137 private: 00139 std::ostream& out_; 00140 00142 std::ios_base::fmtflags originalFlags_; 00143 }; 00144 00146 template<class Scalar> 00147 class SetScientificImpl<Scalar, false> { 00148 public: 00149 typedef Scalar scalar_type; 00150 SetScientificImpl (std::ostream&) {} 00151 ~SetScientificImpl () {} 00152 }; 00153 00174 template<class Scalar> 00175 class SetScientific : 00176 public SetScientificImpl<Scalar, ! Teuchos::ScalarTraits<Scalar>::isOrdinal> { 00177 private: 00179 typedef SetScientificImpl<Scalar, ! Teuchos::ScalarTraits<Scalar>::isOrdinal> base_type; 00180 00181 public: 00183 typedef Scalar scalar_type; 00184 00189 SetScientific (std::ostream& out) : base_type (out) {} 00190 00196 ~SetScientific () { 00197 // Parent class' destructor will be called automatically. 00198 } 00199 }; 00200 00201 // // Specialization for Scalar=int. Specializations for built-in 00202 // // integer types let Tpetra::MatrixMarket::Reader or 00203 // // Tpetra::MatrixMarket::Writer work with a Tpetra::CrsMatrix 00204 // // whose Scalar template parameter is a built-in integer type. 00205 // // These specializations are trivial because there are no 00206 // // decimal digits to print. 00207 // template<> 00208 // class SetScientific<int> { 00209 // public: 00210 // typedef int scalar_type; 00211 // SetScientific (std::ostream& out) {} 00212 // ~SetScientific () {} 00213 // }; 00214 00215 // // Specialization for Scalar=unsigned int. 00216 // template<> 00217 // class SetScientific<unsigned int> { 00218 // public: 00219 // typedef unsigned int scalar_type; 00220 // SetScientific (std::ostream& out) {} 00221 // ~SetScientific () {} 00222 // }; 00223 00224 // // Specialization for Scalar=long. 00225 // template<> 00226 // class SetScientific<long> { 00227 // public: 00228 // typedef long scalar_type; 00229 // SetScientific (std::ostream& out) {} 00230 // ~SetScientific () {} 00231 // }; 00232 00233 // // Specialization for Scalar=unsigned long. 00234 // template<> 00235 // class SetScientific<unsigned long> { 00236 // public: 00237 // typedef unsigned long scalar_type; 00238 // SetScientific (std::ostream& out) {} 00239 // ~SetScientific () {} 00240 // }; 00241 00242 // #ifdef HAVE_TEUCHOS_LONG_LONG_INT 00243 00244 // // Specialization for Scalar=long long. 00245 // template<> 00246 // class SetScientific<long long> { 00247 // public: 00248 // typedef long long scalar_type; 00249 // SetScientific (std::ostream& out) {} 00250 // ~SetScientific () {} 00251 // }; 00252 00253 // // Specialization for Scalar=unsigned long long. 00254 // template<> 00255 // class SetScientific<unsigned long long> { 00256 // public: 00257 // typedef unsigned long long scalar_type; 00258 // SetScientific (std::ostream& out) {} 00259 // ~SetScientific () {} 00260 // }; 00261 00262 // #endif // HAVE_TEUCHOS_LONG_LONG_INT 00263 00264 00265 } // namespace details 00266 } // namespace MatrixMarket 00267 } // namespace Teuchos 00268 00269 #endif // __Teuchos_MatrixMarket_SetScientific_hpp
1.7.6.1