00001
00029 #ifndef LOG_EXP_H
00030 #define LOG_EXP_H
00031
00032 #include <itpp/base/itcompat.h>
00033 #include <itpp/base/help_functions.h>
00034
00035
00036 namespace itpp
00037 {
00038
00041
00042
00043
00044
00045
00047 inline double logb(double b, double x)
00048 {
00049 return (std::log(x) / std::log(b));
00050 }
00051
00053 inline int pow2i(int x) { return ((x < 0) ? 0 : (1 << x)); }
00055 inline double pow2(double x) { return pow(2.0, x); }
00056
00058 inline double pow10(double x) { return pow(10.0, x); }
00059
00061 inline double dB(double x) { return 10.0 * log10(x); }
00063 inline double inv_dB(double x) { return pow(10.0, 0.1 * x); }
00064
00066 inline int int2bits(int n)
00067 {
00068 it_assert(n >= 0, "int2bits(): Improper argument value");
00069
00070 if (n == 0)
00071 return 1;
00072
00073 int b = 0;
00074 while (n) {
00075 n >>= 1;
00076 ++b;
00077 }
00078 return b;
00079 }
00080
00082 inline int levels2bits(int n)
00083 {
00084 it_assert(n > 0, "levels2bits(): Improper argument value");
00085 return int2bits(--n);
00086 }
00087
00089 const double log_double_max = std::log(std::numeric_limits<double>::max());
00091 const double log_double_min = std::log(std::numeric_limits<double>::min());
00092
00105 inline double trunc_log(double x)
00106 {
00107 if (std::numeric_limits<double>::is_iec559) {
00108 if (x == std::numeric_limits<double>::infinity())
00109 return log_double_max;
00110 if (x <= 0)
00111 return log_double_min;
00112 }
00113 return std::log(x);
00114 }
00115
00127 inline double trunc_exp(double x)
00128 {
00129 if (std::numeric_limits<double>::is_iec559
00130 && (x >= log_double_max))
00131 return std::numeric_limits<double>::max();
00132 return std::exp(x);
00133 }
00134
00135
00137 inline double log_add(double log_a, double log_b)
00138 {
00139 if (log_a < log_b) {
00140 double tmp = log_a;
00141 log_a = log_b;
00142 log_b = tmp;
00143 }
00144 double negdelta = log_b - log_a;
00145 if ((negdelta < log_double_min) || std::isnan(negdelta))
00146 return log_a;
00147 else
00148 return (log_a + log1p(std::exp(negdelta)));
00149 }
00150
00151
00152
00153
00154
00155
00157 inline vec exp(const vec &x)
00158 {
00159 return apply_function<double>(std::exp, x);
00160 }
00162 inline cvec exp(const cvec &x)
00163 {
00164 return apply_function<std::complex<double> >(std::exp, x);
00165 }
00167 inline mat exp(const mat &m)
00168 {
00169 return apply_function<double>(std::exp, m);
00170 }
00172 inline cmat exp(const cmat &m)
00173 {
00174 return apply_function<std::complex<double> >(std::exp, m);
00175 }
00176
00178 inline vec pow(const double x, const vec &y)
00179 {
00180 return apply_function<double>(std::pow, x, y);
00181 }
00183 inline mat pow(const double x, const mat &y)
00184 {
00185 return apply_function<double>(std::pow, x, y);
00186 }
00188 inline vec pow(const vec &x, const double y)
00189 {
00190 return apply_function<double>(std::pow, x, y);
00191 }
00193 inline mat pow(const mat &x, const double y)
00194 {
00195 return apply_function<double>(std::pow, x, y);
00196 }
00197
00199 inline vec pow2(const vec &x)
00200 {
00201 return apply_function<double>(pow2, x);
00202 }
00204 inline mat pow2(const mat &x)
00205 {
00206 return apply_function<double>(pow2, x);
00207 }
00208
00210 inline vec pow10(const vec &x)
00211 {
00212 return apply_function<double>(pow10, x);
00213 }
00215 inline mat pow10(const mat &x)
00216 {
00217 return apply_function<double>(pow10, x);
00218 }
00219
00221 inline vec log(const vec &x)
00222 {
00223 return apply_function<double>(std::log, x);
00224 }
00226 inline mat log(const mat &x)
00227 {
00228 return apply_function<double>(std::log, x);
00229 }
00231 inline cvec log(const cvec &x)
00232 {
00233 return apply_function<std::complex<double> >(std::log, x);
00234 }
00236 inline cmat log(const cmat &x)
00237 {
00238 return apply_function<std::complex<double> >(std::log, x);
00239 }
00240
00242 inline vec log2(const vec &x)
00243 {
00244 return apply_function<double>(::log2, x);
00245 }
00247 inline mat log2(const mat &x)
00248 {
00249 return apply_function<double>(::log2, x);
00250 }
00251
00253 inline vec log10(const vec &x)
00254 {
00255 return apply_function<double>(std::log10, x);
00256 }
00258 inline mat log10(const mat &x)
00259 {
00260 return apply_function<double>(std::log10, x);
00261 }
00262
00264 inline vec logb(double b, const vec &x)
00265 {
00266 return apply_function<double>(itpp::logb, b, x);
00267 }
00269 inline mat logb(double b, const mat &x)
00270 {
00271 return apply_function<double>(itpp::logb, b, x);
00272 }
00273
00275 inline vec dB(const vec &x)
00276 {
00277 return apply_function<double>(dB, x);
00278 }
00280 inline mat dB(const mat &x)
00281 {
00282 return apply_function<double>(dB, x);
00283 }
00284
00286 inline vec inv_dB(const vec &x)
00287 {
00288 return apply_function<double>(inv_dB, x);
00289 }
00291 inline mat inv_dB(const mat &x)
00292 {
00293 return apply_function<double>(inv_dB, x);
00294 }
00295
00297 inline ivec int2bits(const ivec& v)
00298 {
00299 return apply_function<int>(int2bits, v);
00300 }
00301
00303 inline ivec levels2bits(const ivec& v)
00304 {
00305 return apply_function<int>(levels2bits, v);
00306 }
00307
00309
00310 }
00311
00312 #endif // #ifndef LOG_EXP_H
00313
00314
00315
00316