00001
00005 #include <assert.h>
00006 #include <math.h>
00007 #include "quickfun.h"
00008
00009 #define round(x) ((UINT)(x+0.5))
00010
00011 #define TANH_RANGE0 1.84
00012 #define TANH_RANGE1 4.5
00013 #define TANH_STEP0 0.001
00014 #define TANH_STEP1 0.005
00015
00016 #define TANH_FACTOR0 (1/TANH_STEP0)
00017 #define TANH_FACTOR1 (1/TANH_STEP1)
00018 #define TANH_SIZE0 (round(TANH_FACTOR0*TANH_RANGE0)+1)
00019 #define TANH_SIZE1 (round(TANH_FACTOR1*(TANH_RANGE1-TANH_RANGE0))+1)
00020
00021
00022 static int tanh_table_ready = 0;
00023 static REAL tanh_table0[TANH_SIZE0], tanh_table1[TANH_SIZE1];
00024
00025 void quick_tanh_setup (void) {
00026 UINT i;
00027 if (tanh_table_ready) return;
00028
00029 for (i = 0; i < TANH_SIZE0; ++i)
00030 tanh_table0[i] = tanh(i * TANH_STEP0);
00031 for (i = 0; i < TANH_SIZE1; ++i)
00032 tanh_table1[i] = tanh(i * TANH_STEP1 + TANH_RANGE0);
00033 tanh_table_ready = 1;
00034 }
00035
00036 static REAL quick_tanh_p (REAL x) {
00037 if (x <= TANH_RANGE0)
00038 return tanh_table0[round(x * TANH_FACTOR0)];
00039 else if (x <= TANH_RANGE1)
00040 return tanh_table1[round((x - TANH_RANGE0) * TANH_FACTOR1)];
00041 return 0.9998;
00042 }
00043
00044 REAL quick_tanh (REAL x) {
00045 assert(tanh_table_ready);
00046
00047 if (x < 0)
00048 return -quick_tanh_p(-x);
00049 return quick_tanh_p(x);
00050 }