_math.h

Go to the documentation of this file.
00001 /*  _________________________________________________________________________
00002  *
00003  *  UTILIB: A utility library for developing portable C++ codes.
00004  *  Copyright (c) 2001, Sandia National Laboratories.
00005  *  This software is distributed under the GNU Lesser General Public License.
00006  *  For more information, see the README file in the top UTILIB directory.
00007  *  _________________________________________________________________________
00008  */
00009 
00016 #ifndef ___math_h
00017 #define ___math_h
00018 
00019 #if defined(__cplusplus) && defined(ANSI_HDRS)
00020 #include <cmath>
00021 #else
00022 #include <math.h>
00023 #endif
00024 #include "utilib_dll.h"
00025 #include "_generic.h"
00026 
00032 #ifndef _MSC_VER
00033 
00034 #include <values.h>
00035 
00036 #else
00037 
00038 #if defined(__cplusplus) && defined(ANSI_HDRS)
00039 #include <climits>
00040 #include <cfloat>
00041 #else
00042 #include <limits.h>
00043 #include <float.h>
00044 #endif
00045 #define MAXINT INT_MAX
00046 #define MAXDOUBLE DBL_MAX
00047 
00048 #endif
00049 
00050 #ifdef SOLARIS
00051 #include <sunmath.h>
00052 #endif
00053 
00054 
00055 #ifdef _MSC_VER                                 
00056 
00057 #define M_PI 3.14159265358979323846 
00058 
00059 #define M_E exp(1.0)
00060 #endif
00061 
00063 #ifndef PI
00064 #define PI M_PI
00065 #endif
00066 
00073 #ifndef MAXINT
00074 #define MAXINT (int)(~((int)0) ^ (1 << (sizeof(int)*8-1)))
00075 #endif
00076 
00082 
00083 #ifndef USING_STL
00084 #ifdef min
00085 #undef min
00086 #endif
00087 
00088 template <class T, class V>
00089 inline UTILIB_API T min(T x, V y)
00090 {return ((x)<(y)? (x) : (y));}
00091 
00092 
00093 #ifdef max
00094 #undef max
00095 #endif
00096 
00097 template <class T, class V>
00098 inline UTILIB_API T max(T x, V y)
00099 {return ((x)>(y)? (x) : (y));}
00100 
00101 
00103 template <class T>
00104 inline UTILIB_API void swap(T& i, T& j)
00105 { T tmp = i; i = j; j = tmp;}
00106 #else
00107 #include <algorithm>
00108 #endif
00109 
00110 
00116 
00117 #ifdef __cplusplus
00118 extern "C" {
00119 #endif
00120 
00122 UTILIB_API int calc_filesize(char* filename);
00123 
00129 UTILIB_API int round _((double x));
00130 
00132 UTILIB_API void setup_bufexp _((int tabsz, double xmin, double xmax));
00134 UTILIB_API double bufexp _((double x));
00135 
00136 #if defined(PARAGON) | defined(nCUBE2) | defined(RS6K) | defined(SGI) | defined(COUGAR) 
00137 
00138 int isinf(double x);
00140 int isnan(double x);
00142 double exp2(double x);
00143 #endif
00144 #if defined(PARAGON) | defined(nCUBE2) | defined(COUGAR)
00145 
00146 void bzero(char* b, int length);
00147 #endif
00148 
00149 #ifdef __cplusplus
00150 };
00151 #endif
00152 
00159 #ifdef BUFFERED_EXP
00160 #define Exp(x)  bufexp(x)
00161 #else
00162 #define Exp(x)  exp(x)
00163 #endif
00164 
00165 
00166 #if defined(__BasicArray_h) && !defined(BasicArray_DEFN)
00167 #define __math_h_NO_ARRAYS
00168 #else
00169 #ifndef __math_h_NO_ARRAYS
00170 #include "DUniform.h"
00171 #include "Uniform.h"
00172 #include "Basic2DArray.h"
00173 #include "IntVector.h"
00174 #include "DoubleVector.h"
00175 #include "BasicArray.h"
00176 #include "default_rng.h"
00177 
00178 class BitArray;
00179 #endif
00180 #endif
00181 
00182 
00183 
00184 #ifndef __math_h_NO_ARRAYS
00190 
00191 
00192 template <class T>
00193 UTILIB_API T sum(const BasicArray<T>& vec)
00194 {
00195 T ans=0;
00196 
00197 for (size_type i=0; i<vec.size(); i++)
00198   ans += vec[i];
00199 return(ans);
00200 }
00201 
00202 
00211 template <class T>
00212 UTILIB_API void shuffle(BasicArray<T>& vec, RNG* rng, size_type num)
00213 {
00214 Uniform urnd(rng);
00215 T temp;
00216 
00217 for (size_type i = 0; i<num; i++) {
00218   size_type j = Discretize(urnd(), i, vec.size()-1);
00219   temp = vec[j];
00220   vec[j] = vec[i];
00221   vec[i] = temp;
00222   }
00223 }
00224 
00225 
00227 UTILIB_API void shuffle(BitArray& vec, RNG* rng=&default_rng);
00228 
00229 
00231 template <class T>
00232 inline UTILIB_API void shuffle(BasicArray<T>& vec, RNG* rng=&default_rng)
00233 {shuffle(vec,rng,vec.size());}
00234 
00235 
00241 template <class T>
00242 UTILIB_API void subshuffle(BasicArray<T>& vec, RNG* rng, size_type start, 
00243                 size_type end)
00244 {
00245 DUniform urnd(rng);
00246 T temp;
00247 
00248 for (size_type i = start; i<end; i++) {
00249   size_type j = urnd(i,end-1);
00250   temp = vec[j];
00251   vec[j] = vec[i];
00252   vec[i] = temp;
00253   }
00254 }
00255 
00256 
00258 template <class T>
00259 UTILIB_API double length(const BasicArray<T>& a)
00260 {
00261 double ans=0.0;
00262 
00263 for (size_type i=0; i<a.size(); i++)
00264   ans += a[i]*a[i];
00265 
00266 return sqrt(ans);
00267 }
00268 
00269 
00271 template <class T>
00272 UTILIB_API double dist(const BasicArray<T>& a, const BasicArray<T>& b)
00273 {
00274 double ans=0.0;
00275 
00276 for (size_type i=0; i<a.size(); i++)
00277   ans += (a[i]-b[i])*(a[i]-b[i]);
00278 
00279 return sqrt(ans);
00280 }
00281 
00282 
00284 template <class T>
00285 UTILIB_API size_type argmin(const BasicArray<T>& vector)
00286 {
00287 size_type i, temp=0;
00288 
00289 if (vector.size() == 1)
00290    return(0);
00291 
00292 for (i=1; i<vector.size(); i++)
00293   if (vector[i] < vector[temp])  temp=i;
00294 
00295 return(temp);
00296 }
00297 
00298 
00300 template <class T>
00301 UTILIB_API size_type argmax(const BasicArray<T>& vector)
00302 {
00303 size_type i, temp=0;
00304 
00305 if (vector.size() == 1)
00306    return(0);
00307 
00308 for (i=1; i<vector.size(); i++)
00309   if (vector[i] > vector[temp])  temp=i;
00310 
00311 return(temp);
00312 }
00313 
00314 
00316 size_type argmedian(double* x, size_type n, int* ws, RNG* rng);
00317 
00318                
00320 template <class T>
00321 UTILIB_API size_type argmedian(const BasicArray<T>& vector, RNG* rng=&default_rng)
00322 {
00323 T* tmp_array = (T*)&(vector[0]);
00324 return argmedian( tmp_array, vector.size(), 0, rng );
00325 }
00326 
00327 
00329 template <class T>
00330 UTILIB_API size_type argmedian(const BasicArray<T>& vec, BasicArray<int>& ws, 
00331                         RNG* rng=NULL)
00332 { return argmedian(vec.data(), vec.size(), ws.data(), rng); }
00333 
00334 
00336 template <class T>
00337 inline UTILIB_API T min(const BasicArray<T>& vec) 
00338 { return vec[argmin(vec)]; }
00339 
00340 
00342 template <class T>
00343 inline UTILIB_API T max(const BasicArray<T>& vec) 
00344 { return vec[argmax(vec)]; }
00345 
00346 
00348 template <class T>
00349 inline UTILIB_API T median(const BasicArray<T>& vec) 
00350 { return vec[argmedian(vec)]; }
00351 
00352 
00354 template <class T>
00355 UTILIB_API BasicArray<T> concat(const BasicArray<T>& a, const BasicArray<T>& b)
00356 {
00357 BasicArray<T> ans(a.size() + b.size());
00358 
00359 for (size_type i=0; i<a.size(); i++)
00360   ans[i] = a[i];
00361 for (size_type j=a.size(); j<(a.size()+b.size()); j++)
00362   ans[j] = b[j-a.size()];
00363 
00364 return(ans);
00365 }
00366 
00367 
00369 template <class T>
00370 double mean(const BasicArray<T>& array)
00371 {
00372 double temp=0.0;
00373 
00374 for (size_type i=0; i<array.size(); i++)
00375   temp += array[i];
00376 
00377 return( temp/array.size() );
00378 }
00379 
00380 
00382 template <class T>
00383 double trimmed_mean(BasicArray<T>& array, const double percent)
00384 {
00385 double temp=0.0;
00386 
00387 sort(array);
00388 
00389 size_type boundary = (size_type) floor(array.size() * percent);
00390 
00391 for (size_type i=boundary; i<(array.size()-boundary); i++)
00392   temp += array[i];
00393 
00394 return( temp/(array.size() - 2.0*boundary) );
00395 }
00396 
00397 
00399 template <class T>
00400 double var(const BasicArray<T>& array, const int sampleflag=TRUE)
00401 {
00402 double array_mean = mean(array);
00403 
00404 double temp=0.0;
00405 for (size_type i=0; i<array.size(); i++)
00406   temp += (array[i] - array_mean) * (array[i] - array_mean);
00407 
00408 if ((sampleflag == FALSE) || (array.size() == 1))
00409    return( temp / array.size() );
00410 else
00411    return( temp / (array.size() - 1) );
00412 }
00413 
00414 
00416 template <class T>
00417 double mad(BasicArray<T>& array, BasicArray<double>& work)
00418 {
00419 double meanval = mean(array);
00420 
00421 for (size_type i=0; i<work.size(); i++)
00422   work[i] = fabs(array[i] - meanval);
00423 
00424 return median(work);
00425 }
00426 
00427 
00429 template <class T>
00430 double mad(BasicArray<T>& array)
00431 {
00432 BasicArray<double> tmparray(array.size());
00433 return mad(array,tmparray);
00434 }
00435 
00436 
00438 template <class T>
00439 UTILIB_API void lapply(BasicArray<T>& vec, double (*func)(T val))
00440 {
00441 for (size_type i=0; i<vec.size(); i++)
00442   vec[i] = (*func)(vec[i]);
00443 }
00444 
00445 
00447 template <class T>
00448 UTILIB_API double inner_product(const BasicArray<T>& v1,
00449                                 const BasicArray<T>& v2)
00450 {
00451 double ans = 0.0;
00452 
00453 for (size_type i=0; i<v1.size(); i++)
00454   ans += v1[i]*v2[i];
00455 
00456 return ans;
00457 }
00458 
00459 
00465 #include "DoubleMatrix.h"
00466 
00468 template <class T>
00469 NumArray<double> mean(const Basic2DArray<T>& matrix, const int stats_flag)
00470 {
00471 NumArray<double> temp(matrix.ncols());
00472 
00473 temp = 0.0;
00474 
00475 for (size_type j=0; j<matrix.nrows(); j++)
00476   for (size_type i=0; i<matrix.ncols(); i++)
00477     temp[i] += matrix[j][i];
00478 
00479 if (stats_flag == TRUE)
00480      temp /= ((double) (matrix.nrows() - 1));
00481 else
00482      temp /= ((double) matrix.nrows());
00483 
00484 return( temp );
00485 }
00486 
00487 
00489 template <class T>
00490 DoubleVector var(const Basic2DArray<T>& mat, const int sampleflag=TRUE)
00491 {
00492 DoubleVector array_mean;
00493 return( var(mat, array_mean, sampleflag) );
00494 }
00495 
00496 
00498 template <class T>
00499 DoubleVector var(const Basic2DArray<T>& mat, BasicArray<double>& array_mean, 
00500                                                         const int sampleflag=TRUE)
00501 {
00502 DoubleVector ans(mat.ncols());
00503 array_mean &= mean(mat);
00504 
00505 ans = 0.0;
00506 for (size_type i=0; i<mat.nrows(); i++)
00507   for (size_type j=0; j<ans.size(); j++)
00508     ans[j] += ((mat[i][j] - array_mean[j]) * (mat[i][j] - array_mean[j]));
00509 
00510 if ((sampleflag == FALSE) || (mat.nrows() == 1))
00511    ans /= (double) (mat.nrows());
00512 else
00513    ans /= (double)(mat.nrows()-1);
00514 return ans;
00515 }
00516 
00517 
00519 template <class T>
00520 UTILIB_API int min(const Basic2DArray<T>& mat)
00521 {
00522 T ans,tmp;
00523 
00524 ans = mat[0][0];
00525 for (size_type i=0; i<mat.nrows(); i++)
00526   for (size_type j=0; j<mat.ncols(); j++) {
00527     tmp = mat[i][j];
00528     if (tmp < ans) ans=tmp;
00529     }
00530 
00531 return ans;
00532 }
00533 
00534 
00536 template <class T>
00537 UTILIB_API T max(const Basic2DArray<T>& mat)
00538 {
00539 T ans,tmp;
00540 
00541 ans = mat[0][0];
00542 for (size_type i=0; i<mat.nrows(); i++)
00543   for (size_type j=0; j<mat.ncols(); j++) {
00544     tmp = mat[i][j];
00545     if (tmp > ans) ans=tmp;
00546     }
00547 
00548 return ans;
00549 }
00550 
00551 
00553 template <class T>
00554 UTILIB_API T sum(const Basic2DArray<T>& mat)
00555 {
00556 T ans;
00557 
00558 ans = 0;
00559 for (size_type i=0; i<mat.nrows(); i++)
00560   for (size_type j=0; j<mat.ncols(); j++)
00561     ans += mat[i][j];
00562 
00563 return ans;
00564 }
00565 
00566 
00568 template <class T>
00569 void rowscale(Basic2DArray<T>& a)
00570 {
00571 double tmp;
00572 size_type j,i;
00573 
00574 for (i=0; i<a.nrows(); i++) {
00575   tmp = 0.0;
00576   for (j=0; j<a.ncols(); j++)
00577     tmp += a[i][j];
00578   if (tmp != 0.0)
00579      for (j=0; j<a.ncols(); j++)
00580        a[i][j] /= tmp;
00581   }
00582 }
00583 
00591 UTILIB_API int cholesky (DoubleMatrix& A, DoubleMatrix& G, int n);
00592 
00593 #endif // __math_h_NO_ARRAYS
00594 
00595 
00596 #endif