00001
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef RCSC_MATH_UTIL_H
00033 #define RCSC_MATH_UTIL_H
00034
00035 #include <algorithm>
00036 #include <cmath>
00037
00038 namespace rcsc {
00039
00041 static const double EPS = 1.0e-10;
00042
00043
00051 template < typename T >
00052 const T &
00053 bound( const T & low, const T & x, const T & high )
00054 {
00055 return std::min( std::max( low, x ), high );
00056 }
00057
00058
00066 template < typename T >
00067 const T &
00068 min_max( const T & low, const T & x, const T & high )
00069 {
00070 return std::min( std::max( low, x ), high );
00071 }
00072
00073
00078 template < typename T >
00079 T
00080 square( const T & x )
00081 {
00082 return x * x;
00083 }
00084
00085
00092 inline
00093 double
00094 sign( const double & x )
00095 {
00096 return x > 0.0 ? 1.0 : -1.0;
00097 }
00098
00099
00109 inline
00110 int
00111 quadratic_formula( const double & a,
00112 const double & b,
00113 const double & c,
00114 double * sol1,
00115 double * sol2 )
00116 {
00117 double d = b * b - 4.0 * a * c;
00118
00119
00120 if ( std::fabs( d ) < 0.001 )
00121 {
00122 if ( sol1 ) *sol1 = -b / ( 2.0 * a );
00123 return 1;
00124 }
00125
00126 if ( d < 0.0 )
00127 {
00128 return 0;
00129 }
00130
00131 d = std::sqrt( d );
00132 if ( sol1 ) *sol1 = (-b + d) / (2.0 * a);
00133 if ( sol2 ) *sol2 = (-b - d) / (2.0 * a);
00134 return 2;
00135 }
00136
00137
00148 inline
00149 double
00150 calc_sum_geom_series( const double & first_term,
00151 const double & r,
00152 const int len )
00153 {
00154
00155
00156
00157
00158 return first_term * ( ( std::pow( r, len ) - 1.0 ) / ( r - 1.0 ) );
00159 }
00160
00161
00162
00172 inline
00173 double
00174 calc_sum_inf_geom_series( const double & first_term,
00175 const double & r )
00176 {
00177 if ( r < 0.0 || 1.0 <= r )
00178 {
00179 return 0.0;
00180 }
00181
00182
00183 return first_term / ( 1.0 - r );
00184 }
00185
00186
00196 inline
00197 double
00198 calc_first_term_geom_series( const double & sum,
00199 const double & r,
00200 const int len )
00201 {
00202
00203
00204 return sum * ( 1.0 - r ) / ( 1.0 - std::pow( r, len ) );
00205 }
00206
00207
00218 inline
00219 double
00220 calc_first_term_inf_geom_series( const double & sum,
00221 const double & r )
00222 {
00223
00224 return sum * ( 1.0 - r );
00225 }
00226
00227
00239 inline
00240 double
00241 calc_first_term_geom_series_last( const double & last_term,
00242 const double & sum,
00243 const double & r )
00244 {
00245 if ( std::fabs( last_term ) < 0.001 )
00246 {
00247 return sum * ( 1.0 - r );
00248 }
00249
00250
00251
00252
00253
00254 double inverse = 1.0 / r;
00255 double tmp = 1.0 + sum * (inverse - 1.0) / last_term;
00256 if ( tmp < 0.001 )
00257 {
00258 return last_term;
00259 }
00260
00261
00262
00263 return last_term * std::pow( inverse, std::log( tmp ) / std::log( inverse ) );
00264 }
00265
00266
00276 inline
00277 double
00278 calc_length_geom_series( const double & first_term,
00279 const double & sum,
00280 const double & r )
00281 {
00282 if ( first_term <= EPS
00283 || sum < 0.0
00284 || r <= EPS )
00285 {
00286
00287
00288
00289 return -1.0;
00290 }
00291
00292 if ( sum <= EPS )
00293 {
00294
00295 return 0.0;
00296 }
00297
00298
00299
00300
00301
00302
00303 double tmp = 1.0 + sum * ( r - 1.0 ) / first_term;
00304 if ( tmp <= EPS )
00305 {
00306 return -1.0;
00307 }
00308 return std::log( tmp ) / std::log( r );
00309 }
00310
00311 }
00312
00313 #endif