~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/pgscript/utilities/m_apm/mapm_lg2.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* 
 
3
 *  M_APM  -  mapm_lg2.c
 
4
 *
 
5
 *  Copyright (C) 2003 - 2007   Michael C. Ring
 
6
 *
 
7
 *  Permission to use, copy, and distribute this software and its
 
8
 *  documentation for any purpose with or without fee is hereby granted,
 
9
 *  provided that the above copyright notice appear in all copies and
 
10
 *  that both that copyright notice and this permission notice appear
 
11
 *  in supporting documentation.
 
12
 *
 
13
 *  Permission to modify the software is granted. Permission to distribute
 
14
 *  the modified code is granted. Modifications are to be distributed by
 
15
 *  using the file 'license.txt' as a template to modify the file header.
 
16
 *  'license.txt' is available in the official MAPM distribution.
 
17
 *
 
18
 *  This software is provided "as is" without express or implied warranty.
 
19
 */
 
20
 
 
21
/*
 
22
 *
 
23
 *      This file contains the iterative function to compute the LOG
 
24
 *      This is an internal function to the library and is not intended
 
25
 *      to be called directly by the user.
 
26
 *
 
27
 */
 
28
 
 
29
#include "pgAdmin3.h"
 
30
#include "pgscript/utilities/mapm-lib/m_apm_lc.h"
 
31
 
 
32
/****************************************************************************/
 
33
 
 
34
/*
 
35
 *      compute rr = log(nn)
 
36
 *
 
37
 *      input is assumed to not exceed the exponent range of a normal
 
38
 *      'C' double ( |exponent| must be < 308)
 
39
 */
 
40
 
 
41
/****************************************************************************/
 
42
void    M_log_solve_cubic(M_APM rr, int places, M_APM nn)
 
43
{
 
44
M_APM   tmp0, tmp1, tmp2, tmp3, guess;
 
45
int     ii, maxp, tolerance, local_precision;
 
46
 
 
47
guess = M_get_stack_var();
 
48
tmp0  = M_get_stack_var();
 
49
tmp1  = M_get_stack_var();
 
50
tmp2  = M_get_stack_var();
 
51
tmp3  = M_get_stack_var();
 
52
 
 
53
M_get_log_guess(guess, nn);
 
54
 
 
55
tolerance       = -(places + 4);
 
56
maxp            = places + 16;
 
57
local_precision = 18;
 
58
 
 
59
/*    Use the following iteration to solve for log :
 
60
 
 
61
                        exp(X) - N 
 
62
      X     =  X - 2 * ------------
 
63
       n+1              exp(X) + N 
 
64
 
 
65
   
 
66
      this is a cubically convergent algorithm 
 
67
      (each iteration yields 3X more digits)
 
68
*/
 
69
 
 
70
ii = 0;
 
71
 
 
72
while (TRUE)
 
73
  {
 
74
   m_apm_exp(tmp1, local_precision, guess);
 
75
 
 
76
   m_apm_subtract(tmp3, tmp1, nn);
 
77
   m_apm_add(tmp2, tmp1, nn);
 
78
 
 
79
   m_apm_divide(tmp1, local_precision, tmp3, tmp2);
 
80
   m_apm_multiply(tmp0, MM_Two, tmp1);
 
81
   m_apm_subtract(tmp3, guess, tmp0);
 
82
 
 
83
   if (ii != 0)
 
84
     {
 
85
      if (((3 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0))
 
86
        break;
 
87
     }
 
88
 
 
89
   m_apm_round(guess, local_precision, tmp3);
 
90
 
 
91
   local_precision *= 3;
 
92
 
 
93
   if (local_precision > maxp)
 
94
     local_precision = maxp;
 
95
 
 
96
   ii = 1;
 
97
  }
 
98
 
 
99
m_apm_round(rr, places, tmp3);
 
100
M_restore_stack(5);
 
101
}
 
102
/****************************************************************************/
 
103
/*
 
104
 *      find log(N)
 
105
 *
 
106
 *      if places < 360
 
107
 *         solve with cubically convergent algorithm above
 
108
 *
 
109
 *      else
 
110
 *
 
111
 *      let 'X' be 'close' to the solution   (we use ~110 decimal places)
 
112
 *
 
113
 *      let Y = N * exp(-X) - 1
 
114
 *
 
115
 *      then
 
116
 *
 
117
 *      log(N) = X + log(1 + Y)
 
118
 *
 
119
 *      since 'Y' will be small, we can use the efficient log_near_1 algorithm.
 
120
 *
 
121
 */
 
122
void    M_log_basic_iteration(M_APM rr, int places, M_APM nn)
 
123
{
 
124
M_APM   tmp0, tmp1, tmp2, tmpX;
 
125
 
 
126
if (places < 360)
 
127
  {
 
128
   M_log_solve_cubic(rr, places, nn);
 
129
  }
 
130
else
 
131
  {
 
132
   tmp0 = M_get_stack_var();
 
133
   tmp1 = M_get_stack_var();
 
134
   tmp2 = M_get_stack_var();
 
135
   tmpX = M_get_stack_var();
 
136
   
 
137
   M_log_solve_cubic(tmpX, 110, nn);
 
138
   
 
139
   m_apm_negate(tmp0, tmpX);
 
140
   m_apm_exp(tmp1, (places + 8), tmp0);
 
141
   m_apm_multiply(tmp2, tmp1, nn);
 
142
   m_apm_subtract(tmp1, tmp2, MM_One);
 
143
   
 
144
   M_log_near_1(tmp0, (places - 104), tmp1);
 
145
   
 
146
   m_apm_add(tmp1, tmpX, tmp0);
 
147
   m_apm_round(rr, places, tmp1);
 
148
   
 
149
   M_restore_stack(4);
 
150
  }
 
151
}
 
152
/****************************************************************************/