Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

kira_approx.C

Go to the documentation of this file.
00001 
00002        //=======================================================//    _\|/_
00003       //  __  _____           ___                    ___       //      /|\ ~
00004      //  /      |      ^     |   \  |         ^     |   \     //          _\|/_
00005     //   \__    |     / \    |___/  |        / \    |___/    //            /|\ ~
00006    //       \   |    /___\   |  \   |       /___\   |   \   // _\|/_
00007   //     ___/   |   /     \  |   \  |____  /     \  |___/  //   /|\ ~
00008  //                                                       //            _\|/_
00009 //=======================================================//              /|\ ~
00010 
00011 // Steve's replacement for the pow function (in limited circumstances).
00012 
00013 //#include "hdyn.h"
00014 #include "stdinc.h"
00015 
00016 #define POW -0.125              // approximations work best for POW close to 0
00017 
00018 #ifndef TOOLBOX
00019 
00020 #define X0      1.0
00021 #define X1      1.5
00022 #define X2      2.0
00023 
00024 static real x[3] = {X0, X1, X2};
00025 static real p[3] = {pow(X0, POW), pow(X1, POW), pow(X2, POW)};
00026 static real c[3];
00027 static bool init_c = false;
00028 
00029 local inline real g(real xx)    // 3-point Lagrange approximation
00030                                 // to xx^POW on [1,2]
00031 {
00032     if (!init_c) {
00033         c[0] = p[0] / ((x[0]-x[1]) * (x[0]-x[2]));
00034         c[1] = p[1] / ((x[1]-x[0]) * (x[1]-x[2]));
00035         c[2] = p[2] / ((x[2]-x[0]) * (x[2]-x[1]));
00036         init_c = true;
00037     }
00038 
00039     return   c[0] * (xx-x[1]) * (xx-x[2])
00040            + c[1] * (xx-x[0]) * (xx-x[2])
00041            + c[2] * (xx-x[0]) * (xx-x[1]);
00042 }
00043 
00044 #define IMAX    24
00045 static real pow_int[IMAX];
00046 static bool init_p = false;
00047 
00048 real pow_approx(real x)
00049 {
00050     if (x < 1) return 1/pow_approx(1/x);        // !!!
00051 
00052     if (!init_p) {
00053         int j = 1;
00054         for (int i = 0; i < IMAX; i++) {
00055             pow_int[i] = pow(j, POW);
00056             j *= 2;
00057         }
00058         init_p = true;
00059     }
00060 
00061     int i = 0;
00062     while (x > 2) {             // 2*log2(x) operations
00063         x *= 0.5;
00064         i++;
00065         if (i >= IMAX-1) return pow_int[IMAX-1];
00066     }
00067     return pow_int[i] * g(x);   // 12 operations
00068 }
00069 
00070 #else
00071 
00072 local real pow_true(real x)
00073 {
00074     return pow(x, POW);
00075 }
00076 
00077 main()
00078 {
00079     real x, dx = 1.e4;
00080     for (x = 1; x < 1.e8+.5*dx; x += dx)
00081         printf("%f %f %f\n",
00082                log10(x), log10(pow_true(x)), log10(pow_approx(x)));
00083 }
00084 
00085 #endif

Generated at Sun Feb 24 09:57:06 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001