Sacado_Fad_ScalarTraitsImp.hpp

Go to the documentation of this file.
00001 // $Id$ 
00002 // $Source$ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 // @HEADER
00031 
00032 #ifndef SACADO_FAD_SCALARTRAITSIMP_HPP
00033 #define SACADO_FAD_SCALARTRAITSIMP_HPP
00034 
00035 #ifdef HAVE_SACADO_TEUCHOS
00036 
00037 #include "Teuchos_ScalarTraits.hpp"
00038 #include "Teuchos_TestForException.hpp"
00039 #include "Sacado_mpl_apply.hpp"
00040 
00041 namespace Sacado {
00042 
00043   namespace Fad {
00044 
00046     template <typename FadType>
00047     struct ScalarTraitsImp {
00048       typedef typename Sacado::ValueType<FadType>::type ValueT;
00049 
00050       typedef typename mpl::apply<FadType,typename Teuchos::ScalarTraits<ValueT>::magnitudeType>::type magnitudeType;
00051       typedef typename mpl::apply<FadType,typename Teuchos::ScalarTraits<ValueT>::halfPrecision>::type halfPrecision;
00052       typedef typename mpl::apply<FadType,typename Teuchos::ScalarTraits<ValueT>::doublePrecision>::type doublePrecision;
00053 
00054       static const bool isComplex = Teuchos::ScalarTraits<ValueT>::isComplex;
00055       static const bool isOrdinal = Teuchos::ScalarTraits<ValueT>::isOrdinal;
00056       static const bool isComparable = 
00057   Teuchos::ScalarTraits<ValueT>::isComparable;
00058       static const bool hasMachineParameters = 
00059   Teuchos::ScalarTraits<ValueT>::hasMachineParameters;
00060       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType eps() {
00061   return Teuchos::ScalarTraits<ValueT>::eps();
00062       }
00063       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType sfmin() {
00064   return Teuchos::ScalarTraits<ValueT>::sfmin();
00065       }
00066       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType base()  {
00067   return Teuchos::ScalarTraits<ValueT>::base();
00068       }
00069       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType prec()  {
00070   return Teuchos::ScalarTraits<ValueT>::prec();
00071       }
00072       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType t()     {
00073   return Teuchos::ScalarTraits<ValueT>::t();
00074       }
00075       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType rnd()   {
00076   return Teuchos::ScalarTraits<ValueT>::rnd();
00077       }
00078       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType emin()  {
00079   return Teuchos::ScalarTraits<ValueT>::emin();
00080       }
00081       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType rmin()  {
00082   return Teuchos::ScalarTraits<ValueT>::rmin();
00083       }
00084       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType emax()  {
00085   return Teuchos::ScalarTraits<ValueT>::emax();
00086       }
00087       static typename Teuchos::ScalarTraits<ValueT>::magnitudeType rmax()  {
00088   return Teuchos::ScalarTraits<ValueT>::rmax();
00089       }
00090       static magnitudeType magnitude(const FadType& a) {
00091 #ifdef TEUCHOS_DEBUG
00092   TEUCHOS_SCALAR_TRAITS_NAN_INF_ERR(
00093     a, "Error, the input value to magnitude(...) a = " << a << 
00094     " can not be NaN!" );
00095   TEST_FOR_EXCEPTION(is_fad_real(a) == false, std::runtime_error,
00096          "Complex magnitude is not a differentiable "
00097          "function of complex inputs.");
00098 #endif
00099   //return std::fabs(a); 
00100   magnitudeType b(a.size(), 
00101       Teuchos::ScalarTraits<ValueT>::magnitude(a.val()));
00102   if (Teuchos::ScalarTraits<ValueT>::real(a.val()) >= 0)
00103     for (int i=0; i<a.size(); i++)
00104       b.fastAccessDx(i) = 
00105         Teuchos::ScalarTraits<ValueT>::magnitude(a.fastAccessDx(i));
00106   else
00107     for (int i=0; i<a.size(); i++)
00108       b.fastAccessDx(i) = 
00109         -Teuchos::ScalarTraits<ValueT>::magnitude(a.fastAccessDx(i));
00110   return b;
00111       }
00112       static ValueT zero()  { 
00113   return ValueT(0.0); 
00114       }
00115       static ValueT one()   { 
00116   return ValueT(1.0); 
00117       }
00118       
00119       // Conjugate is only defined for real derivative components
00120       static FadType conjugate(const FadType& x) {
00121 #ifdef TEUCHOS_DEBUG
00122   TEST_FOR_EXCEPTION(is_fad_real(x) == false, std::runtime_error,
00123          "Complex conjugate is not a differentiable "
00124          "function of complex inputs.");
00125 #endif
00126   FadType y = x;
00127   y.val() = Teuchos::ScalarTraits<ValueT>::conjugate(x.val());
00128   return y;
00129       }   
00130 
00131       // Real part is only defined for real derivative components
00132       static FadType real(const FadType& x) { 
00133 #ifdef TEUCHOS_DEBUG
00134   TEST_FOR_EXCEPTION(is_fad_real(x) == false, std::runtime_error,
00135          "Real component is not a differentiable "
00136          "function of complex inputs.");
00137 #endif
00138   FadType y = x;
00139   y.val() = Teuchos::ScalarTraits<ValueT>::real(x.val());
00140   return y;
00141       }
00142 
00143       // Imaginary part is only defined for real derivative components
00144       static FadType imag(const FadType& x) { 
00145 #ifdef TEUCHOS_DEBUG
00146   TEST_FOR_EXCEPTION(is_fad_real(x) == false, std::runtime_error,
00147          "Imaginary component is not a differentiable "
00148          "function of complex inputs.");
00149 #endif
00150   return FadType(Teuchos::ScalarTraits<ValueT>::imag(x.val()));
00151       }
00152 
00153       static ValueT nan() {
00154   return Teuchos::ScalarTraits<ValueT>::nan(); 
00155       }
00156       static bool isnaninf(const FadType& x) { 
00157   if (Teuchos::ScalarTraits<ValueT>::isnaninf(x.val()))
00158     return true;
00159   for (int i=0; i<x.size(); i++)
00160     if (Teuchos::ScalarTraits<ValueT>::isnaninf(x.dx(i)))
00161       return true;
00162   return false;
00163       }
00164       static void seedrandom(unsigned int s) { 
00165   Teuchos::ScalarTraits<ValueT>::seedrandom(s); 
00166       }
00167       static ValueT random() { 
00168   return Teuchos::ScalarTraits<ValueT>::random(); 
00169       }
00170       static std::string name() { 
00171   return Sacado::StringName<FadType>::eval(); 
00172       }
00173       static FadType squareroot(const FadType& x) {
00174 #ifdef TEUCHOS_DEBUG
00175   TEUCHOS_SCALAR_TRAITS_NAN_INF_ERR(
00176     x, "Error, the input value to squareroot(...) a = " << x << 
00177     " can not be NaN!" );
00178 #endif
00179   return std::sqrt(x); 
00180       }
00181       static FadType pow(const FadType& x, const FadType& y) { 
00182   return std::pow(x,y); 
00183       }
00184 
00185       // Helper function to determine whether a complex value is real
00186       static bool is_complex_real(const ValueT& x) {
00187   return 
00188     Teuchos::ScalarTraits<ValueT>::magnitude(x-Teuchos::ScalarTraits<ValueT>::real(x)) == 0;
00189       }
00190 
00191       // Helper function to determine whether a Fad type is real
00192       static bool is_fad_real(const FadType& x) {
00193   if (x.size() == 0)
00194     return true;
00195   if (Teuchos::ScalarTraits<ValueT>::isComplex) {
00196     if (!is_complex_real(x.val()))
00197       return false;
00198     for (int i=0; i<x.size(); i++)
00199       if (!is_complex_real(x.fastAccessDx(i)))
00200         return false;
00201   }
00202   return true;
00203       }
00204 
00205     }; // class ScalarTraitsImp
00206 
00207   } // namespace Fad
00208 
00209 } // namespace Sacado
00210 
00211 #endif // HAVE_SACADO_TEUCHOS
00212 
00213 #endif // SACADO_FAD_SCALARTRAITSIMP_HPP

Generated on Wed May 12 21:39:34 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7