00001
00002
00003
00004
00005
00006
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