Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

base/Math

Go to the documentation of this file.
00001 /* **-*-c++-*-**************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: Math 1029 2004-02-11 20:45:54Z jungd $
00019   $Revision: 1.11 $
00020   $Date: 2004-02-11 15:45:54 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022  
00023 ****************************************************************************/
00024 
00025 #ifndef _BASE_MATH_
00026 #define _BASE_MATH_
00027 
00028 #include <base/base>
00029 #include <base/consts>
00030 
00031 #include <base/Object>
00032 #include <base/Vector>
00033 #include <base/Matrix>
00034 
00035 
00036 namespace base {
00037 
00038 
00039 /// class of useful math utilities
00040 /** 
00041  * NB: see also functions in Consts
00042  *  \todo consider using a Singelton policy template class for this
00043  *        (and perhaps also Application) 
00044  */ 
00045 class Math : public Object
00046 {
00047 public:
00048   virtual String className() const { return String("Math"); }
00049 
00050   /// convert degrees to radians
00051   inline static Real degToRad(Real d) { return (d*consts::TwoPi)/360.0; }
00052   /// convert radians to degrees
00053   inline static Real radToDeg(Real r) { return (r*360.0)/consts::TwoPi; }
00054 
00055   /// square (i.e. n*n)
00056   inline static Real sqr(Real n) { return n*n; }
00057   /// squate root (i.e. n^.5)
00058   inline static Real sqrt(Real n) { Assert(n>=0); return ::sqrt(n); }
00059   /// cube (i.e. n*n*n)
00060   inline static Real cube(Real n) { return n*n*n; }
00061   /// absolute value (i.e. |s|)
00062   inline static Real abs(Real s) { return fabs(s); }
00063   /// sign (i.e. -1 if n<0, 0 if n=0, 1 if n>0)
00064   inline static Real sign(Real n) { return (n<0)?-1:((n>0)?1:0); }
00065   /// x raised to the power y
00066   inline static Real pow(Real x, Real y) { return ::pow(x,y); }
00067   /// random number [0..1]
00068   inline static Real random() 
00069     { return Real(::random())/Real(/*2^31*/2147483648U-1); }
00070 
00071   /// true if n is Not-A-Number
00072   inline static bool isNAN(Real n)
00073     { return isnan(n); }
00074 
00075   // usual trig functions (just make them available so the Math:: notation can be used consistiently)
00076   inline static Real sin(Real a) { return ::sin(a); }
00077   inline static Real cos(Real a) { return ::cos(a); }
00078   inline static Real tan(Real a) { return ::tan(a); }
00079   inline static Real asin(Real a) { return ::asin(a); }
00080   inline static Real acos(Real a) { return ::acos(a); }
00081   inline static Real atan(Real a) { return ::atan(a); }
00082   inline static Real atan2(Real a, Real b) { return ::atan2(a,b); }
00083   
00084 
00085   /// equals within eps (i.e. true if |r1-r2| < eps)
00086   inline static bool equals(const Real r1, const Real r2, Real eps = consts::epsilon)
00087   { return ::fabs(r1-r2) < eps; }
00088 
00089   /// 0 if in neighbourhood of 0 (i.e. 0 if |n| < neighbourhoodRadius, n otherwise)
00090   inline static Real zeroIfNeighbour(Real n, Real neighbourhoodRadius = consts::epsilon)
00091   { return (::fabs(n) < neighbourhoodRadius)?0:n; }
00092 
00093 
00094   /// minimum (i.e. t1 if t1<t2, t2 otherwise)
00095   template<typename T> static inline T minimum(const T& t1, const T& t2) { return (t1<t2)?t1:t2; }
00096   /// minimum (i.e. minimum(t1,t2) if minimum(t1,t2) < minimum(t2,t3), minimum(t2,t3) otherwise)
00097   template<typename T> static inline T minimum(const T& t1, const T& t2, const T& t3) { return (t1<t2)?((t1<t3)?t1:t3):((t2<t3)?t2:t3); }
00098   /// maximum (i.e. t1 if t1>t2, t2 otherwise)
00099   template<typename T> static inline T maximum(const T& t1, const T& t2) { return (t1>t2)?t1:t2; }
00100   /// maximum (i.e. maximum(t1,t2) if maximum(t1,t2) > maximum(t2,t3), maximum(t2,t3) otherwise)
00101   template<typename T> static inline T maximum(const T& t1, const T& t2, const T& t3) { return (t1>t2)?((t1>t3)?t1:t3):((t2>t3)?t2:t3); }
00102 
00103 
00104   /// bound a value to the specified range
00105   template<typename T> static void bound(T& v, const T& lower, const T& upper)
00106   { if (v<lower) v=lower; else { if (v>upper) v=upper; } }
00107 
00108 
00109   /// normalize angles (in radians) to the range (-pi..pi]
00110   static inline Real normalizeAngle(Real angle) 
00111   {
00112     while (angle > consts::Pi) angle-=consts::TwoPi;
00113     while (angle <= -consts::Pi) angle+=consts::TwoPi;
00114     return angle;
00115   }
00116 
00117   /// normalize angles (in radians) to the range [0..2pi)
00118   static inline Real normalizeAngle2PI(Real angle)
00119   {
00120     while (angle >= consts::TwoPi) angle-=consts::TwoPi;
00121     while (angle < 0) angle+=consts::TwoPi;
00122     return angle;
00123   }
00124 
00125   /// difference between two angles (e.g. -160deg - 170deg = 30deg) 
00126   /// Return is normalized (-pi..pi]
00127   static Real angleDifference(Real angle1, Real angle2);
00128 
00129   
00130   /// Find LUP decomposition of Matrix.
00131   /** P is represented by the vector Pi, where the element
00132    *  values represent the column of P containing a 1. i.e. Pi[i]=j => P[i][j]=1
00133    */
00134   static void decomposeLUP(const Matrix& A, Matrix& L, Matrix& U, Vector& Pi, Real epsilon = consts::epsilon2);
00135 
00136   /// Solve for Ax = b, given LUP decomposition of A as L, U and Pi, and given b, returns x
00137   static Vector solveLUP(const Matrix& L, const Matrix& U, const Vector& Pi, const Vector& b);
00138 
00139 
00140   /// inverse of A (using LUP decomposition)
00141   static Matrix inverse(const Matrix& A, Real epsilon = consts::epsilon2);
00142 
00143 
00144   /// null-space of Matrix A (using Singular Value Decomposition - SVD)
00145   /**
00146    *   @param      A             input matrix for which the null-space is calculated (MxN, where M<=N)
00147    *   @param      nullSpaceRank output rank of the null space returned
00148    *   @param      k2            output matrix condition number
00149    *   @return                   null-space vectors
00150    */
00151   static Matrix nullSpace(const Matrix& A, Int& nullSpaceRank, Real& k2);
00152 
00153   
00154   /// the Moore-Penrose pseudo-inverse of A (using SVD)
00155   static Matrix pseudoInverse(const Matrix& A);
00156 
00157 
00158 
00159   
00160 protected:
00161   // can't instantiate it
00162   Math() {}
00163   Math(const Math&) {}
00164   virtual ~Math() {}
00165 };
00166 
00167 
00168 } // base
00169 
00170 #endif

Generated on Thu Jul 29 15:56:06 2004 for OpenSim by doxygen 1.3.6