aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
lrsmp.h
Go to the documentation of this file.
1 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2 
3 /* lrsmp.h (lrs extended precision arithmetic library) */
4 /* Copyright: David Avis 2000, avis@cs.mcgill.ca */
5 /* Version 4.1, February 17, 2000 */
6 
7 /* This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
20  */
21 /******************************************************************************/
22 /* See http://cgm.cs.mcgill.ca/~avis/C/lrs.html for lrs usage instructions */
23 /******************************************************************************/
24 /* This package contains the extended precision routines used by lrs
25  and some other miscellaneous routines. The maximum precision depends on
26  the parameter MAX_DIGITS defined below, with usual default of 255L. This
27  gives a maximum of 1020 decimal digits on 32 bit machines. The procedure
28  lrs_mp_init(dec_digits) may set a smaller number of dec_digits, and this
29  is useful if arrays or matrices will be used.
30  */
31 
32 #ifdef PLRS
33 #include <string>
34 using namespace std;
35 #endif
36 
37 /***********/
38 /* defines */
39 /***********/
40 /*
41  this is number of longwords. Increasing this won't cost you that much
42  since only variables other than the A matrix are allocated this size.
43  Changing affects running time in small but not very predictable ways.
44  */
45 
46 #define MAX_DIGITS 255L
47 
48 /*
49  this is in decimal digits, you pay in memory if you increase this,
50  unless you override by a line with
51  digits n
52  before the begin line of your file.
53  */
54 #define DEFAULT_DIGITS 100L
55 
56 
57 // 64 bits for windows (long is 32 bits)
58 #ifdef _MSC_VER
59 typedef __int64 int64_t;
60 typedef unsigned __int64 uint64_t;
61 #else
62 #include <stdint.h>
63 #endif
64 
65 /**********MACHINE DEPENDENT CONSTANTS***********/
66 /* MAXD is 2^(k-1)-1 where k=16,32,64 word size */
67 /* MAXD must be at least 2*BASE^2 */
68 /* If BASE is 10^k, use "%k.ku" for FORMAT */
69 /* INTSIZE is number of bytes for integer */
70 /* 32/64 bit machines */
71 /***********************************************/
72 #ifdef B32
73 /*32 bit machines */
74 #define FORMAT "%4.4lu"
75 #define MAXD 2147483647L
76 #define BASE 10000L
77 #define BASE_DIG 4
78 #define INTSIZE 8L
79 #define BIT "32bit"
80 #else
81 /* 64 bit machines */
82 #define MAXD 9223372036854775807L
83 #define BASE 1000000000L
84 #define FORMAT "%9.9lu"
85 #define BASE_DIG 9
86 #define INTSIZE 16L
87 #define BIT "64bit"
88 #endif
89 
90 #define MAXINPUT 1000 /*max length of any input rational */
91 
92 #define POS 1L
93 #define NEG -1L
94 #ifndef TRUE
95 #define TRUE 1L
96 #endif
97 #ifndef FALSE
98 #define FALSE 0L
99 #endif
100 #define ONE 1L
101 #define TWO 2L
102 #define ZERO 0L
103 
104 /**********************************/
105 /* MACROS */
106 /* dependent on mp implementation */
107 /**********************************/
108 
109 #define exactdivint(a, b, c)
110  divint((a), (b), (c)) /*should use special code here */
111 #define positive(a) (((a)[0] < 2 || ((a)[0] == 2 && (a)[1] == 0)) ? FALSE : TRUE)
112 #define negative(a) (((a)[0] > -2 || ((a)[0] == -2 && (a)[1] == 0)) ? FALSE : TRUE)
113 #define iszero(a) ((((a)[0] == 2 || (a)[0] == -2) && (a)[1] == 0) ? TRUE : FALSE)
114 #define one(a) (((a)[0] == 2 && (a)[1] == 1) ? TRUE : FALSE)
115 //#define length(a) (((a)[0] > 0) ? (a)[0] : -(a)[0])
116 #define sign(a) (((a)[0] < 0) ? NEG : POS)
117 #define storesign(a, sa) a[0] = ((a)[0] > 0) ? (sa) * ((a)[0]) : -(sa) * ((a)[0])
118 #define changesign(a) a[0] = -(a)[0]
119 #define storelength(a, la) a[0] = ((a)[0] > 0) ? (la) : -(la)
120 
121 
122 /*
123  * convert between decimal and machine (longword digits). Notice lovely
124  * implementation of ceiling function :-)
125  */
126 #define DEC2DIG(d) ((d) % BASE_DIG ? (d) / BASE_DIG + 1 : (d) / BASE_DIG)
127 #define DIG2DEC(d) ((d)*BASE_DIG)
128 
129 #include <stdlib.h>
130 
131 
132 #ifdef SIGNALS
133 #include <signal.h>
134 #include <unistd.h>
135 #define errcheck(s, e)
136  if ((int64_t)(e) == -1L) {
137  perror(s);
138  exit(1);
139  }
140 #endif
141 
142 #define CALLOC(n, s) xcalloc(n, s, __LINE__, __FILE__)
143 
144 
145 extern int64_t lrs_digits; /* max permitted no. of digits */
146 extern int64_t lrs_record_digits; /* this is the biggest acheived so far. */
147 
148 extern FILE* lrs_ifp; /* input file pointer */
149 extern FILE* lrs_ofp; /* output file pointer */
150 
151 
152 /*************/
153 /* typedefs */
154 /*************/
155 
156 typedef int64_t
157  lrs_mp[MAX_DIGITS + 1]; /* type lrs_mp holds one multi-precision integer */
158 typedef int64_t* lrs_mp_t;
159 typedef int64_t** lrs_mp_vector;
160 typedef int64_t*** lrs_mp_matrix;
161 
162 /*********************************************************/
163 /* Initialization and allocation procedures - must use! */
164 /******************************************************* */
165 
166 /* next two functions are not used by lrsmp, but are for lrsgmp compatability */
167 #define lrs_alloc_mp(a)
168 #define lrs_clear_mp(a)
169 lrs_mp_t lrs_alloc_mp_t(); /* dynamic allocation of lrs_mp */
170 lrs_mp_vector
171 lrs_alloc_mp_vector(int64_t n); /* allocate lrs_mp_vector for n+1 lrs_mp numbers */
172 lrs_mp_matrix
173 lrs_alloc_mp_matrix(int64_t m,
174  int64_t n); /* allocate lrs_mp_matrix for m+1 x n+1 lrs_mp */
175 int64_t lrs_mp_init(int64_t dec_digits,
176  FILE* lrs_ifp,
177  FILE* lrs_ofp); /* max number of decimal digits, fps */
178 void lrs_clear_mp_vector(lrs_mp_vector a, int64_t n);
179 void lrs_clear_mp_matrix(lrs_mp_matrix a, int64_t m, int64_t n);
180 
181 
182 /*********************************************************/
183 /* Core library functions - depend on mp implementation */
184 /******************************************************* */
185 int64_t length(lrs_mp a); /* return length of lrs_mp integer */
186 void atomp(char s[], lrs_mp a); /* convert string to lrs_mp integer */
187 int64_t compare(lrs_mp a, lrs_mp b); /* a ? b and returns -1,0,1 for <,=,> */
188 void copy(lrs_mp a, lrs_mp b); /* assigns a=b */
189 void divint(lrs_mp a,
190  lrs_mp b,
191  lrs_mp c); /* c=a/b, a contains remainder on return */
192 void gcd(lrs_mp u, lrs_mp v); /* returns u=gcd(u,v) destroying v */
193 int64_t mp_greater(lrs_mp a, lrs_mp b); /* tests if a > b and returns (TRUE=POS) */
194 void itomp(int64_t in, lrs_mp a); /* convert integer i to lrs_mp */
195 void linint(lrs_mp a,
196  int64_t ka,
197  lrs_mp b,
198  int64_t kb); /* compute a*ka+b*kb --> a */
199 void mptodouble(lrs_mp a, double* x); /* convert lrs_mp to double */
200 int64_t mptoi(lrs_mp a); /* convert lrs_mp to long integer */
201 void mulint(lrs_mp a, lrs_mp b, lrs_mp c); /* multiply two integers a*b --> c */
202 void normalize(lrs_mp a); /* normalize lrs_mp after computation */
203 #ifdef PLRS
204 string pmp(char name[], lrs_mp a); /* print the long precision integer a */
205 string prat(char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */
206 char* cprat(char name[], lrs_mp Nt, lrs_mp Dt); /* C version of prat */
207 int64_t
208 plrs_readrat(lrs_mp Na,
209  lrs_mp Da,
210  const char* rat); /* take a rational number and convert to lrs_mp */
211 #else
212 void pmp(char name[], lrs_mp a); /* print the long precision integer a */
213 void prat(char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */
214 #endif
215 int64_t readrat(lrs_mp Na,
216  lrs_mp Da); /* read a rational or int and convert to lrs_mp */
217 void reduce(lrs_mp Na, lrs_mp Da); /* reduces Na Da by gcd(Na,Da) */
218 
219 /*********************************************************/
220 /* Standard arithmetic & misc. functions */
221 /* should be independent of mp implementation */
222 /******************************************************* */
223 
224 void atoaa(char in[],
225  char num[],
226  char den[]); /* convert rational string in to num/den strings */
227 void addint(lrs_mp a, lrs_mp b, lrs_mp c); /* compute c=a+b */
228 int64_t atos(char s[]); /* convert s to integer */
229 int64_t comprod(lrs_mp Na,
230  lrs_mp Nb,
231  lrs_mp Nc,
232  lrs_mp Nd); /* +1 if Na*Nb > Nc*Nd,-1 if Na*Nb > Nc*Nd else 0 */
233 void decint(lrs_mp a, lrs_mp b); /* compute a=a-b */
234 void divrat(lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
235 /* computes Nc/Dc = (Na/Da) /( Nb/Db ) and reduce */
236 void getfactorial(lrs_mp factorial, int64_t k); /* compute k factorial in lrs_mp */
237 /* NC/DC = ka*Na/Da + kb*Nb/Db */
238 void linrat(lrs_mp Na,
239  lrs_mp Da,
240  int64_t ka,
241  lrs_mp Nb,
242  lrs_mp Db,
243  int64_t kb,
244  lrs_mp Nc,
245  lrs_mp Dc);
246 void lcm(lrs_mp a, lrs_mp b); /* a = least common multiple of a, b; b is saved */
247 void mulrat(lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
248 /* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce */
249 int64_t myrandom(int64_t num,
250  int64_t nrange); /* return a random number in range 0..nrange-1 */
251 void notimpl(char s[]); /* bail out - help! */
252 void rattodouble(lrs_mp a,
253  lrs_mp b,
254  double* x); /* convert lrs_mp rational to double */
255 void reduceint(lrs_mp Na, lrs_mp Da); /* divide Na by Da and return it */
256 void reducearray(lrs_mp_vector p,
257  int64_t n); /* find gcd of p[0]..p[n-1] and divide through by */
258 void scalerat(lrs_mp Na, lrs_mp Da, int64_t ka); /* scales rational by ka */
259 void subint(lrs_mp a, lrs_mp b, lrs_mp c); /* compute c=a-b */
260 
261 /**********************************/
262 /* Miscellaneous functions */
263 /******************************** */
264 
265 // void free (void *ptr);
266 
267 void lrs_getdigits(int64_t* a, int64_t* b); /* send digit information to user */
268 
269 void stringcpy(char* s, char* t); /* copy t to s pointer version */
270 
271 void* xcalloc(int64_t n, int64_t s, int64_t l, char* f);
272 
273 void lrs_default_digits_overflow();
274 void digits_overflow();
275 
276 /* end of lrsmp.h (vertex enumeration using lexicographic reverse search) */
277 
278 #endif // DOXYGEN_SHOULD_SKIP_THIS
#define BASE_DIG
Definition: LrsWrapper.h:75