Guest User

Untitled

a guest
Dec 14th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.74 KB | None | 0 0
  1. /*  RETURNS MP Y = LN(1+X) IF X IS AN MP NUMBER SATISFYING THE
  2.  *  CONDITION ABS(X) < 1/B, ERROR OTHERWISE.
  3.  *  USES NEWTONS METHOD TO SOLVE THE EQUATION
  4.  *  EXP1(-Y) = X, THEN REVERSES SIGN OF Y.
  5.  */
  6. static void
  7. mp_lns(const MPNumber *x, MPNumber *z)
  8. {
  9.     int t, it0;
  10.     MPNumber t1, t2, t3;
  11.  
  12.     /* ln(1+0) = 0 */
  13.     if (mp_is_zero(x)) {
  14.         mp_set_from_integer(0, z);
  15.         return;
  16.     }
  17.  
  18.     /* Get starting approximation -ln(1+x) ~= -x + x^2/2 - x^3/3 + x^4/4 */
  19.     mp_set_from_mp(x, &t2);
  20.     mp_divide_integer(x, 4, &t1);
  21.     mp_add_fraction(&t1, -1, 3, &t1);
  22.     mp_multiply(x, &t1, &t1);
  23.     mp_add_fraction(&t1, 1, 2, &t1);
  24.     mp_multiply(x, &t1, &t1);
  25.     mp_add_integer(&t1, -1, &t1);
  26.     mp_multiply(x, &t1, z);
  27.  
  28.     /* Solve using Newtons method */
  29.     it0 = t = 5;
  30.     while(1)
  31.     {
  32.         int ts2, ts3;
  33.  
  34.         /* t3 = (e^t3 - 1) */
  35.         /* z = z - (t2 + t3 + (t2 * t3)) */
  36.         mp_epowy(z, &t3);
  37.         mp_add_integer(&t3, -1, &t3);
  38.         mp_multiply(&t2, &t3, &t1);
  39.         mp_add(&t3, &t1, &t3);
  40.         mp_add(&t2, &t3, &t3);
  41.         mp_subtract(z, &t3, z);
  42.         if (t >= MP_T)
  43.             break;
  44.  
  45.         /*  FOLLOWING LOOP COMPUTES NEXT VALUE OF T TO USE.
  46.          *  BECAUSE NEWTONS METHOD HAS 2ND ORDER CONVERGENCE,
  47.          *  WE CAN ALMOST DOUBLE T EACH TIME.
  48.          */
  49.         ts3 = t;
  50.         t = MP_T;
  51.         do {
  52.             ts2 = t;
  53.             t = (t + it0) / 2;
  54.         } while (t > ts3);
  55.         t = ts2;
  56.     }
  57.  
  58.     /* CHECK THAT NEWTON ITERATION WAS CONVERGING AS EXPECTED */
  59.     if (t3.sign != 0 && t3.exponent << 1 > it0 - MP_T) {
  60.         mperr("*** ERROR OCCURRED IN MP_LNS, NEWTON ITERATION NOT CONVERGING PROPERLY ***");
  61.     }
  62.  
  63.     z->sign = -z->sign;
  64. }
Add Comment
Please, Sign In to add comment