Clipper
clipper_util.h
00001 
00004 //C Copyright (C) 2000-2006 Kevin Cowtan and University of York
00005 //L
00006 //L  This library is free software and is distributed under the terms
00007 //L  and conditions of version 2.1 of the GNU Lesser General Public
00008 //L  Licence (LGPL) with the following additional clause:
00009 //L
00010 //L     `You may also combine or link a "work that uses the Library" to
00011 //L     produce a work containing portions of the Library, and distribute
00012 //L     that work under terms of your choice, provided that you give
00013 //L     prominent notice with each copy of the work that the specified
00014 //L     version of the Library is used in it, and that you include or
00015 //L     provide public access to the complete corresponding
00016 //L     machine-readable source code for the Library including whatever
00017 //L     changes were used in the work. (i.e. If you make changes to the
00018 //L     Library you must distribute those, but you do not need to
00019 //L     distribute source or object code to those portions of the work
00020 //L     not covered by this licence.)'
00021 //L
00022 //L  Note that this clause grants an additional right and does not impose
00023 //L  any additional restriction, and so does not affect compatibility
00024 //L  with the GNU General Public Licence (GPL). If you wish to negotiate
00025 //L  other terms, please contact the maintainer.
00026 //L
00027 //L  You can redistribute it and/or modify the library under the terms of
00028 //L  the GNU Lesser General Public License as published by the Free Software
00029 //L  Foundation; either version 2.1 of the License, or (at your option) any
00030 //L  later version.
00031 //L
00032 //L  This library is distributed in the hope that it will be useful, but
00033 //L  WITHOUT ANY WARRANTY; without even the implied warranty of
00034 //L  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00035 //L  Lesser General Public License for more details.
00036 //L
00037 //L  You should have received a copy of the CCP4 licence and/or GNU
00038 //L  Lesser General Public License along with this library; if not, write
00039 //L  to the CCP4 Secretary, Daresbury Laboratory, Warrington WA4 4AD, UK.
00040 //L  The GNU Lesser General Public can also be obtained by writing to the
00041 //L  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00042 //L  MA 02111-1307 USA
00043 
00044 
00045 #ifndef CLIPPER_UTIL
00046 #define CLIPPER_UTIL
00047 
00048 
00049 #include "clipper_precision.h"
00050 
00051 
00052 namespace clipper
00053 {
00054 
00056 
00059   class Util
00060   {
00061   private:
00062     typedef union { uitype32 i; ftype32 f; } U32;
00063     typedef union { uitype64 i; ftype64 f; } U64;
00064   public:
00065     Util();   
00066 
00067     static const ftype& nan() { return nan_; }
00069     static const float& nanf() { return nanf_; }
00071     static const double& nand() { return nand_; }
00073     inline static void set_null( ftype32& f ) { U32* const u1=(U32* const)&f; const U32* const u2=(const U32* const)&nanf_; u1->i = u2->i; }
00075     inline static void set_null( ftype64& f ) { U64* const u1=(U64* const)&f; const U64* const u2=(const U64* const)&nand_; u1->i = u2->i; }
00077     inline static bool is_null( const ftype32& f ) { U32 u1,u2; u1.f = f; u2.f = nanf_; return ( u1.i == u2.i ); }
00079     inline static bool is_null( const ftype64& f ) { U64 u1,u2; u1.f = f; u2.f = nand_; return ( u1.i == u2.i ); }
00081 
00082     inline static bool is_nan( const ftype32 f ) { U32 u; u.f = f; return ((u.i&CLIPPER_NAN_MASK_A_32)==CLIPPER_NAN_MASK_A_32); }
00084 
00085     inline static bool is_nan( const ftype64 f ) { U64 u; u.f = f; return ((u.i&CLIPPER_NAN_MASK_A_64)==CLIPPER_NAN_MASK_A_64); }
00087 
00088     inline static bool isnan(const ftype32 f) { U32 u; u.f = f; return ((u.i&CLIPPER_NAN_MASK_A_32)==CLIPPER_NAN_MASK_A_32)&&((u.i&CLIPPER_NAN_MASK_B_32)!=0U); }
00090 
00091     inline static bool isnan(const ftype64 f) { U64 u; u.f = f; return ((u.i&CLIPPER_NAN_MASK_A_64)==CLIPPER_NAN_MASK_A_64)&&((u.i&CLIPPER_NAN_MASK_B_64)!=0U); }
00093     static ftype sim( const ftype& x );
00095     static ftype invsim( const ftype& x );
00097     static ftype sim_integ( const ftype& x );
00099     static ftype sim_deriv( const ftype& x );
00101     static ftype sim_deriv_recur( const ftype& x );
00103     static ftype atanh( const ftype& x ) { return log((1.0+x)/(1.0-x))/2.0; }
00105     static ftype bessel_i0( const ftype& x );
00107     static ftype u2b( const ftype& x ) { return x * eightpi2_; }
00109     static ftype b2u( const ftype& x ) { return x / eightpi2_; }
00111     template<class T> inline static T mean( const T& pl, const T& mi )
00112       {
00113         if ( Util::is_nan(pl) ) return mi;
00114         else if (Util::is_nan(mi) ) return pl;
00115         else return 0.5*(pl+mi);
00116       }
00118     template<class T> inline static T sig_mean( const T& pl, const T& mi, const T& cov )
00119       {
00120         if ( Util::is_nan(pl) ) return mi;
00121         else if (Util::is_nan(mi) ) return pl;
00122         else if (Util::is_nan(cov) ) return 0.5*sqrt(pl*pl+mi*mi);
00123         else return 0.5*sqrt(pl*pl+mi*mi+2*cov);
00124       }
00125 
00127     inline static int intf( const ftype& a ) { return int( floor( a ) ); }
00129     inline static int intc( const ftype& a ) { return int( ceil( a ) ); }
00131     inline static int intr( const ftype& a ) { return int( rint( a ) ); }
00132 
00134     inline static ftype mod( const ftype& a, const ftype& b )
00135       { ftype c = fmod(a, b); if (c < 0) c+=b; return c;}
00137     inline static int mod( const int& a, const int& b )
00138       { int c = a%b; if (c < 0) c+=b; return c; }
00140     template<class T> inline static T max(const T& a, const T& b)
00141       { return (a > b) ? a : b; }
00143     template<class T> inline static T min(const T& a, const T& b)
00144       { return (a < b) ? a : b; }
00146     template<class T> inline static T bound( const T& min, const T& val, const T& max ) { return ( (val < max) ? ( (val > min ) ? val : min ) : max ); }
00148     template<class T> inline static void swap( T& a, T& b )
00149       { T c = a; a = b; b = c; }
00151     template<class T> inline static void swap( T& a, T& b, T& c )
00152       { c = a; a = b; b = c; }
00154     template<class T> inline static T sqr( const T& a ) { return a*a; }
00156     template<class T> inline static T isqrt( const T& n )
00157       { return T(floor(sqrt(ftype(n)))); }
00158 
00160     inline static const ftype& pi() { return onepi_; }
00162     inline static const ftype& twopi() { return twopi_; }
00164     inline static const ftype& twopi2() { return twopi2_; }
00166     inline static const ftype& eightpi2() { return eightpi2_; }
00168     static ftype d2rad( const ftype& x );
00170     static ftype rad2d( const ftype& x );
00171 
00172   private:
00173     static float  nanf_;  
00174     static double nand_;  
00175     static ftype  nan_;   
00176     static ftype onepi_;  
00177     static ftype twopi_;  
00178     static ftype twopi2_; 
00179     static ftype eightpi2_; 
00180     static ftype d2rad_;  
00181     static ftype sim_a;   
00182     static ftype sim_b;   
00183     static ftype sim_c;   
00184     static ftype sim_d;   
00185     static ftype sim_e;   
00186     static ftype sim_A;   
00187     static ftype sim_B;   
00188     static ftype sim_C;   
00189     static ftype sim_g;   
00190     static ftype sim_p;   
00191     static ftype sim_q;   
00192     static ftype sim_r;   
00193   };
00194 
00195 } // namespace clipper
00196 
00197 #endif