aGrUM 2.3.2
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>
34using 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
59typedef __int64 int64_t;
60typedef 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#define errcheck(s, e) \
135 if ((int64_t)(e) == -1L) { \
136 perror(s); \
137 exit(1); \
138 }
139#endif
140
141#define CALLOC(n, s) xcalloc(n, s, __LINE__, __FILE__)
142
143
144extern int64_t lrs_digits; /* max permitted no. of digits */
145extern int64_t lrs_record_digits; /* this is the biggest acheived so far. */
146
147extern FILE* lrs_ifp; /* input file pointer */
148extern FILE* lrs_ofp; /* output file pointer */
149
150
151/*************/
152/* typedefs */
153/*************/
154
155typedef int64_t
156 lrs_mp[MAX_DIGITS + 1]; /* type lrs_mp holds one multi-precision integer */
157typedef int64_t* lrs_mp_t;
158typedef int64_t** lrs_mp_vector;
159typedef int64_t*** lrs_mp_matrix;
160
161/*********************************************************/
162/* Initialization and allocation procedures - must use! */
163/******************************************************* */
164
165/* next two functions are not used by lrsmp, but are for lrsgmp compatability */
166#define lrs_alloc_mp(a)
167#define lrs_clear_mp(a)
168lrs_mp_t lrs_alloc_mp_t(); /* dynamic allocation of lrs_mp */
169lrs_mp_vector
170lrs_alloc_mp_vector(int64_t n); /* allocate lrs_mp_vector for n+1 lrs_mp numbers */
171lrs_mp_matrix
172lrs_alloc_mp_matrix(int64_t m,
173 int64_t n); /* allocate lrs_mp_matrix for m+1 x n+1 lrs_mp */
174int64_t lrs_mp_init(int64_t dec_digits,
175 FILE* lrs_ifp,
176 FILE* lrs_ofp); /* max number of decimal digits, fps */
177void lrs_clear_mp_vector(lrs_mp_vector a, int64_t n);
178void lrs_clear_mp_matrix(lrs_mp_matrix a, int64_t m, int64_t n);
179
180
181/*********************************************************/
182/* Core library functions - depend on mp implementation */
183/******************************************************* */
184int64_t length(lrs_mp a); /* return length of lrs_mp integer */
185void atomp(char s[], lrs_mp a); /* convert string to lrs_mp integer */
186int64_t compare(lrs_mp a, lrs_mp b); /* a ? b and returns -1,0,1 for <,=,> */
187void copy(lrs_mp a, lrs_mp b); /* assigns a=b */
188void divint(lrs_mp a,
189 lrs_mp b,
190 lrs_mp c); /* c=a/b, a contains remainder on return */
191void gcd(lrs_mp u, lrs_mp v); /* returns u=gcd(u,v) destroying v */
192int64_t mp_greater(lrs_mp a, lrs_mp b); /* tests if a > b and returns (TRUE=POS) */
193void itomp(int64_t in, lrs_mp a); /* convert integer i to lrs_mp */
194void linint(lrs_mp a,
195 int64_t ka,
196 lrs_mp b,
197 int64_t kb); /* compute a*ka+b*kb --> a */
198void mptodouble(lrs_mp a, double* x); /* convert lrs_mp to double */
199int64_t mptoi(lrs_mp a); /* convert lrs_mp to long integer */
200void mulint(lrs_mp a, lrs_mp b, lrs_mp c); /* multiply two integers a*b --> c */
201void normalize(lrs_mp a); /* normalize lrs_mp after computation */
202#ifdef PLRS
203string pmp(char name[], lrs_mp a); /* print the long precision integer a */
204string prat(char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */
205char* cprat(char name[], lrs_mp Nt, lrs_mp Dt); /* C version of prat */
206int64_t
207plrs_readrat(lrs_mp Na,
208 lrs_mp Da,
209 const char* rat); /* take a rational number and convert to lrs_mp */
210#else
211void pmp(char name[], lrs_mp a); /* print the long precision integer a */
212void prat(char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */
213#endif
214int64_t readrat(lrs_mp Na,
215 lrs_mp Da); /* read a rational or int and convert to lrs_mp */
216void reduce(lrs_mp Na, lrs_mp Da); /* reduces Na Da by gcd(Na,Da) */
217
218/*********************************************************/
219/* Standard arithmetic & misc. functions */
220/* should be independent of mp implementation */
221/******************************************************* */
222
223void atoaa(char in[],
224 char num[],
225 char den[]); /* convert rational string in to num/den strings */
226void addint(lrs_mp a, lrs_mp b, lrs_mp c); /* compute c=a+b */
227int64_t atos(char s[]); /* convert s to integer */
228int64_t comprod(lrs_mp Na,
229 lrs_mp Nb,
230 lrs_mp Nc,
231 lrs_mp Nd); /* +1 if Na*Nb > Nc*Nd,-1 if Na*Nb > Nc*Nd else 0 */
232void decint(lrs_mp a, lrs_mp b); /* compute a=a-b */
233void divrat(lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
234/* computes Nc/Dc = (Na/Da) /( Nb/Db ) and reduce */
235void getfactorial(lrs_mp factorial, int64_t k); /* compute k factorial in lrs_mp */
236/* NC/DC = ka*Na/Da + kb*Nb/Db */
237void linrat(lrs_mp Na,
238 lrs_mp Da,
239 int64_t ka,
240 lrs_mp Nb,
241 lrs_mp Db,
242 int64_t kb,
243 lrs_mp Nc,
244 lrs_mp Dc);
245void lcm(lrs_mp a, lrs_mp b); /* a = least common multiple of a, b; b is saved */
246void mulrat(lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
247/* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce */
248int64_t myrandom(int64_t num,
249 int64_t nrange); /* return a random number in range 0..nrange-1 */
250void notimpl(char s[]); /* bail out - help! */
251void rattodouble(lrs_mp a,
252 lrs_mp b,
253 double* x); /* convert lrs_mp rational to double */
254void reduceint(lrs_mp Na, lrs_mp Da); /* divide Na by Da and return it */
255void reducearray(lrs_mp_vector p,
256 int64_t n); /* find gcd of p[0]..p[n-1] and divide through by */
257void scalerat(lrs_mp Na, lrs_mp Da, int64_t ka); /* scales rational by ka */
258void subint(lrs_mp a, lrs_mp b, lrs_mp c); /* compute c=a-b */
259
260/**********************************/
261/* Miscellaneous functions */
262/******************************** */
263
264// void free (void *ptr);
265
266void lrs_getdigits(int64_t* a, int64_t* b); /* send digit information to user */
267
268void stringcpy(char* s, char* t); /* copy t to s pointer version */
269
270void* xcalloc(int64_t n, int64_t s, int64_t l, char* f);
271
272void lrs_default_digits_overflow();
273void digits_overflow();
274
275/* end of lrsmp.h (vertex enumeration using lexicographic reverse search) */
276
277#endif // DOXYGEN_SHOULD_SKIP_THIS
STL namespace.