nysol-zdd 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/zdd_so/BDD.cc +495 -0
- data/ext/zdd_so/BDD.h +356 -0
- data/ext/zdd_so/BDDDG.cc +1818 -0
- data/ext/zdd_so/BDDDG.h +107 -0
- data/ext/zdd_so/BDDHASH.cc +91 -0
- data/ext/zdd_so/BtoI.cc +503 -0
- data/ext/zdd_so/BtoI.h +144 -0
- data/ext/zdd_so/CtoI.cc +1072 -0
- data/ext/zdd_so/CtoI.h +186 -0
- data/ext/zdd_so/MLZBDDV.cc +153 -0
- data/ext/zdd_so/MLZBDDV.h +42 -0
- data/ext/zdd_so/SOP.cc +608 -0
- data/ext/zdd_so/SOP.h +199 -0
- data/ext/zdd_so/ZBDD.cc +1035 -0
- data/ext/zdd_so/ZBDD.h +243 -0
- data/ext/zdd_so/ZBDDDG.cc +1834 -0
- data/ext/zdd_so/ZBDDDG.h +105 -0
- data/ext/zdd_so/ZBDDHASH.cc +91 -0
- data/ext/zdd_so/bddc.c +2816 -0
- data/ext/zdd_so/bddc.h +132 -0
- data/ext/zdd_so/extconf.rb +25 -0
- data/ext/zdd_so/include/aheap.c +211 -0
- data/ext/zdd_so/include/aheap.h +111 -0
- data/ext/zdd_so/include/base.c +93 -0
- data/ext/zdd_so/include/base.h +60 -0
- data/ext/zdd_so/include/itemset.c +473 -0
- data/ext/zdd_so/include/itemset.h +153 -0
- data/ext/zdd_so/include/problem.c +371 -0
- data/ext/zdd_so/include/problem.h +160 -0
- data/ext/zdd_so/include/queue.c +518 -0
- data/ext/zdd_so/include/queue.h +177 -0
- data/ext/zdd_so/include/sgraph.c +331 -0
- data/ext/zdd_so/include/sgraph.h +170 -0
- data/ext/zdd_so/include/stdlib2.c +832 -0
- data/ext/zdd_so/include/stdlib2.h +746 -0
- data/ext/zdd_so/include/trsact.c +723 -0
- data/ext/zdd_so/include/trsact.h +167 -0
- data/ext/zdd_so/include/vec.c +583 -0
- data/ext/zdd_so/include/vec.h +159 -0
- data/ext/zdd_so/lcm-vsop.cc +596 -0
- data/ext/zdd_so/print.cc +683 -0
- data/ext/zdd_so/table.cc +330 -0
- data/ext/zdd_so/vsop.h +88 -0
- data/ext/zdd_so/zdd_so.cpp +3277 -0
- data/lib/nysol/zdd.rb +31 -0
- metadata +131 -0
@@ -0,0 +1,746 @@
|
|
1
|
+
/* library for standard macros and functions
|
2
|
+
by Takeaki Uno 2/22/2002 e-mail: uno@nii.jp
|
3
|
+
homepage: http://research.nii.ac.jp/~uno/index.html */
|
4
|
+
/* This program is available for only academic use, basically.
|
5
|
+
Anyone can modify this program, but he/she has to write down
|
6
|
+
the change of the modification on the top of the source code.
|
7
|
+
Neither contact nor appointment to Takeaki Uno is needed.
|
8
|
+
If one wants to re-distribute this code, do not forget to
|
9
|
+
refer the newest code, and show the link to homepage of
|
10
|
+
Takeaki Uno, to notify the news about the codes for the users.
|
11
|
+
For the commercial use, please make a contact to Takeaki Uno. */
|
12
|
+
|
13
|
+
#ifndef _stdlib2_h_
|
14
|
+
#define _stdlib2_h_
|
15
|
+
|
16
|
+
#include<stdlib.h>
|
17
|
+
#include<stdio.h>
|
18
|
+
#include<string.h>
|
19
|
+
#include<math.h>
|
20
|
+
#include<time.h>
|
21
|
+
#include<stdarg.h>
|
22
|
+
|
23
|
+
#if defined(__cplusplus) && defined(__GNUC__)
|
24
|
+
#define _cplusplus_
|
25
|
+
#endif
|
26
|
+
|
27
|
+
#ifdef MULTI_CORE
|
28
|
+
#include <pthread.h>
|
29
|
+
#endif
|
30
|
+
|
31
|
+
/* comment out the following line if no error check is needed */
|
32
|
+
//#define ERROR_CHECK
|
33
|
+
/* comment out the following if exit is not needed after each error routine */
|
34
|
+
//#define ERROR_RET
|
35
|
+
|
36
|
+
#ifdef ERROR_RET // definition of the process for errors
|
37
|
+
#define EXIT return
|
38
|
+
#define EXIT0 return(0)
|
39
|
+
#else
|
40
|
+
#define EXIT exit(1)
|
41
|
+
#define EXIT0 exit(1)
|
42
|
+
#endif
|
43
|
+
|
44
|
+
// for dealing with files more than 2GB
|
45
|
+
#define _LARGEFILE_SOURCE
|
46
|
+
#define _FILE_OFFSET_BITS 64
|
47
|
+
|
48
|
+
#ifndef NULL
|
49
|
+
#define NULL 0
|
50
|
+
#endif
|
51
|
+
|
52
|
+
#ifdef MTWISTER
|
53
|
+
#define RANDOM ((long)(dsfmt_gv_genrand_close_open()*2147483648LL))
|
54
|
+
#define RAND1 dsfmt_gv_genrand_close_open()
|
55
|
+
#define RAND_INIT dsfmt_gv_init_gen_rand(514346237)
|
56
|
+
#elif defined(__GNUC__)
|
57
|
+
#define RANDOM xor128()
|
58
|
+
#define RAND1 ((double)xor128())/4294967296.0
|
59
|
+
#define RAND_INIT xor128()
|
60
|
+
#else
|
61
|
+
#define RANDOM rand()
|
62
|
+
#define RAND1 ((double)rand())/2147483648.0
|
63
|
+
#define RAND_INIT srand(0)
|
64
|
+
#endif
|
65
|
+
|
66
|
+
|
67
|
+
// 64bit integer
|
68
|
+
#ifndef LONG
|
69
|
+
#define LONG long long
|
70
|
+
#define LONGHUGE 9000000000000000000LL
|
71
|
+
#define LONGF "%lld"
|
72
|
+
#endif
|
73
|
+
|
74
|
+
// actual int (most proper sized integer, for the processor)
|
75
|
+
#ifdef INT_64
|
76
|
+
#define INT LONG
|
77
|
+
#define INTF LONGF
|
78
|
+
#else
|
79
|
+
#define INT int
|
80
|
+
#define INTF "%d"
|
81
|
+
#endif
|
82
|
+
|
83
|
+
#ifndef FILE_LONG
|
84
|
+
#define FILE_LONG LONG
|
85
|
+
#define FILE_LONGHUGE LONGHUGE
|
86
|
+
#define FILE_LONGF "%lld"
|
87
|
+
#endif
|
88
|
+
|
89
|
+
#define UINTHUGE 4000000000U
|
90
|
+
#define INTHUGE 2000000000
|
91
|
+
#define USHORTHUGE 32767
|
92
|
+
#define SHORTHUGE 65535
|
93
|
+
#define DOUBLEHUGE 999999999999999999999999999999.9
|
94
|
+
#define ISEQUAL_VALUE 0.0000001
|
95
|
+
#define ISEQUAL_VALUE2 0.00001
|
96
|
+
#define PI 3.1415926535897932384647950288
|
97
|
+
#define PI_INT 31416
|
98
|
+
#define NPE 2.718281828459045235360287471352
|
99
|
+
#define NPE_INT 27183
|
100
|
+
#define MULTI_CORE_MAX 64
|
101
|
+
|
102
|
+
#ifndef WEIGHT
|
103
|
+
#ifdef WEIGHT_DOUBLE
|
104
|
+
#define WEIGHT double
|
105
|
+
#define WEIGHTHUGE DOUBLEHUGE
|
106
|
+
#define WEIGHTF "%f"
|
107
|
+
#else // define WEIGHT by int if it's undefined
|
108
|
+
#define WEIGHT int
|
109
|
+
#define WEIGHTHUGE INTHUGE
|
110
|
+
#define WEIGHTF "%d"
|
111
|
+
#endif
|
112
|
+
#endif
|
113
|
+
|
114
|
+
#ifndef PERM
|
115
|
+
#ifdef PERM_LONG
|
116
|
+
#define PERM LONG
|
117
|
+
#define PERMHUGE LONGHUGE
|
118
|
+
#define PERMF "%lld"
|
119
|
+
#else
|
120
|
+
#define PERM int
|
121
|
+
#define PERMHUGE INTHUGE
|
122
|
+
#define PERMF "%d"
|
123
|
+
#endif
|
124
|
+
#endif
|
125
|
+
|
126
|
+
|
127
|
+
extern size_t common_size_t;
|
128
|
+
extern INT common_INT, common_INT2;
|
129
|
+
extern char *common_pnt, *common_charp;
|
130
|
+
extern FILE *common_FILE;
|
131
|
+
extern WEIGHT common_WEIGHT, *common_WEIGHTp;
|
132
|
+
extern char *ERROR_MES;
|
133
|
+
extern int print_time_flag;
|
134
|
+
typedef struct {
|
135
|
+
int i1, i2, i3, i4, i5, i6, i7, i8, i9;
|
136
|
+
LONG l1, l2, l3, l4, l5, l6, l7, l8, l9;
|
137
|
+
double d1, d2, d3, d4, d5, d6, d7, d8, d9;
|
138
|
+
char *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9;
|
139
|
+
void *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9;
|
140
|
+
} PARAMS;
|
141
|
+
extern PARAMS internal_params;
|
142
|
+
|
143
|
+
/* lock&unlock for multi-core mode */
|
144
|
+
#ifdef MULTI_CORE
|
145
|
+
extern int SPIN_LOCK_dummy;
|
146
|
+
#define SPIN_LOCK(b,a) (SPIN_LOCK_dummy=(((b)>1)&&pthread_spin_lock(&(a))))
|
147
|
+
#define SPIN_UNLOCK(b,a) (SPIN_LOCK_dummy=(((b)>1)&&pthread_spin_unlock(&(a))))
|
148
|
+
#else
|
149
|
+
#define SPIN_LOCK(b,a)
|
150
|
+
#define SPIN_UNLOCK(b,a)
|
151
|
+
#endif
|
152
|
+
|
153
|
+
#define TYPE_VEC 1
|
154
|
+
#define TYPE_MAT 2
|
155
|
+
#define TYPE_SVEC 3
|
156
|
+
#define TYPE_SMAT 4
|
157
|
+
#define TYPE_QUEUE 5
|
158
|
+
#define TYPE_SETFAMILY 6
|
159
|
+
#define TYPE_TRSACT 7
|
160
|
+
#define TYPE_ALIST 8
|
161
|
+
#define TYPE_MALIST 9
|
162
|
+
#define TYPE_AGRAPH 10
|
163
|
+
#define TYPE_SGRAPH 11
|
164
|
+
#define TYPE_AHEAP 12
|
165
|
+
#define TYPE_BASE 13
|
166
|
+
#define TYPE_FSTAR 14
|
167
|
+
#define TYPE_FILE2 15
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
/* random */
|
173
|
+
#define rnd(a) (random()%(a))
|
174
|
+
#define prob(a) ((random()%65536)<(int)((a)*65536.0))
|
175
|
+
|
176
|
+
#define MARK 1
|
177
|
+
#define UNMARK 0
|
178
|
+
#define TRUE 1
|
179
|
+
#define FALSE 0
|
180
|
+
|
181
|
+
/* equal/inequal with allowing numerical error for double */
|
182
|
+
#define ISEQUAL(a,b) ((a)-(b)<ISEQUAL_VALUE&&(b)-(a)<ISEQUAL_VALUE)
|
183
|
+
#define ISGREAT(a,b) ((a)-(b)>ISEQUAL_VALUE)
|
184
|
+
#define ISLESS(a,b) ((b)-(a)>ISEQUAL_VALUE)
|
185
|
+
#define RANGE(a,b,c) (((a)<=(b))&&((b)<=(c)))
|
186
|
+
#define BITRM(a,b) ((a)-=((a)&(b)));
|
187
|
+
|
188
|
+
/* macro for getting maximum/minimum of two values */
|
189
|
+
#define MAX(a,b) ((a)>(b)?(a):(b))
|
190
|
+
#define ENMAX(a,b) ((a)=((a)>(b)?(a):(b)))
|
191
|
+
#define MIN(a,b) ((a)<(b)?(a):(b))
|
192
|
+
#define ENMIN(a,b) ((a)=((a)<(b)?(a):(b)))
|
193
|
+
|
194
|
+
/* error routine */
|
195
|
+
#define error(mes,x) do{ERROR_MES=mes;fprintf(stderr,"%s\n",mes);x;}while(0)
|
196
|
+
#define error_num(mes,n,x) do{ERROR_MES=mes;fprintf(stderr,"%s: %g\n",mes,(double)(n));x;}while(0)
|
197
|
+
#define error_str(mes,s,x) do{ERROR_MES=mes;fprintf(stderr,"%s: %s\n",mes,s);x;}while(0)
|
198
|
+
#define print_err(...) fprintf(stderr,__VA_ARGS__)
|
199
|
+
#define print_mes(flag,...) do{if((flag)&1)fprintf(stderr,__VA_ARGS__);}while(0)
|
200
|
+
#define mfree(...) mfree_(NULL, __VA_ARGS__,(void *)1)
|
201
|
+
|
202
|
+
|
203
|
+
/* basic array operations and loops */
|
204
|
+
#define ARY_FILL(f,start,end,c) do{for(common_size_t=(size_t)(start);common_size_t<(size_t)(end);common_size_t++)(f)[common_size_t]=(c);}while(0)
|
205
|
+
#define ARY_INS(f,b) do{(f).v[(f).t++]=(b);}while(0)
|
206
|
+
#define ARY_FLOOP(V,i,x) for( (i)=0,x=(V).v[0] ; (i)<(V).t ; (i)++,x=(V).v[i])
|
207
|
+
#define ARY_BLOOP(V,i,x) for( (i)=(V).t-1,x=i>0?(V).v[i]:0 ; (i)>=0 ; (i)--,x=i>0?(V).v[i]:0)
|
208
|
+
#define FLOOP(i,x,y) for ((i)=(x) ; (i)<(y) ; (i)++)
|
209
|
+
#define BLOOP(i,x,y) for ((i)=(x) ; ((i)--)>(y) ; )
|
210
|
+
#define MLOOP(z,x,M) for ((z)=(x) ; *(z)<(M) ; (z)++)
|
211
|
+
/* binary search: return maximum index no larger than c */
|
212
|
+
#define BIN_SRCH(x,a,s,t,c) \
|
213
|
+
do {\
|
214
|
+
x=s; common_size_t=t; while ( x<common_size_t-1 ){\
|
215
|
+
if ( a[(x+common_size_t)/2] <= c ) x = (x+common_size_t)/2; else common_size_t = (x+common_size_t)/2;\
|
216
|
+
} while (0)\
|
217
|
+
|
218
|
+
/* allocate memory, and exit with error message if fault */
|
219
|
+
#ifdef _cplusplus_
|
220
|
+
#define malloc2(f,b,c,x) do{if(!((f)=(typeof(f))malloc(((size_t)sizeof((f)[0]))*(b)))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
221
|
+
#define calloc2(f,b,c,x) do{if(!((f)=(typeof(f))calloc(sizeof((f)[0]),b))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
222
|
+
#define realloc2(f,b,c,x) do{if(!(f=(typeof(f))realloc(f,((size_t)sizeof((f)[0]))*(b)))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
223
|
+
#else
|
224
|
+
#define malloc2(f,b,c,x) do{if(!((f)=malloc(((size_t)sizeof((f)[0]))*(b)))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
225
|
+
#define calloc2(f,b,c,x) do{if(!((f)=calloc(sizeof((f)[0]),b))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
226
|
+
#define realloc2(f,b,c,x) do{if(!(f=realloc(f,((size_t)sizeof((f)[0]))*(b)))){fprintf(stderr,"memory allocation error %s (%lld byte)\n",c,(LONG)((LONG)sizeof((f)[0])*(b)));ERROR_MES="out of memory";x;}}while(0)
|
227
|
+
#endif
|
228
|
+
|
229
|
+
#define malloc2d(f,b,d,c,x) do{malloc2(f,b,c,x);malloc2((f)[0],(b)*(d)+2,c,{free2(f);x;});FLOOP(common_size_t,0,(size_t)b)(f)[common_size_t]=&((f)[0][common_size_t*(d)]);}while(0)
|
230
|
+
#define calloc2d(f,b,d,c,x) do{malloc2(f,b,c,x);calloc2((f)[0],(b)*(d)+2,c,{free2(f);x;});FLOOP(common_size_t,0,(size_t)b)(f)[common_size_t]=&((f)[0][common_size_t*(d)]);}while(0)
|
231
|
+
|
232
|
+
/* reallocate memory and expand the memory size */
|
233
|
+
#define reallocx_(f,end,end2,e,c,x) do{realloc2(f,end2,c,x);FLOOP(common_size_t,(size_t)end,(size_t)end2)(f)[common_size_t]=(e);}while(0)
|
234
|
+
#define reallocx(f,end,i,e,c,x) do{if((size_t)(i)>=(size_t)(end)){reallocx_(f,end,MAX((end)*2+100,(i)+1),e,c,x);end=MAX((end)*2,(i)+1);}}while(0)
|
235
|
+
|
236
|
+
/* basic array operations */
|
237
|
+
#define ARY_DUP(f,p,end,c,x) do{malloc2(f,end,c,x);memcpy(f,p,sizeof(*(f))*(end));}while(0)
|
238
|
+
#define ARY_MAX(m,i,f,x,y) do{(m)=(f)[x];(i)=(x);FLOOP(common_INT,(x)+1,(y))if((m)<(f)[common_INT]){(i)=common_INT;(m)=(f)[i];}}while(0)
|
239
|
+
#define ARY_MIN(m,i,f,x,y) do{(m)=(f)[x];(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)>(f)[common_INT]){(i)=common_INT;(m)=(f)[i];}}while(0)
|
240
|
+
#define ARY_SUM(f,v,x,y) do{(f)=0;FLOOP(common_INT,x,y)(f)+=(v)[common_INT];}while(0)
|
241
|
+
#define ARY_NORM(f,v,b) do{(f)=0;FLOOP(common_INT,0,b)(f)+=(v)[common_INT]*(v)[common_INT];(f)=sqrt(f);}while(0)
|
242
|
+
#define ARY_NORMALIZE(v,b) do{ARY_NORM(common_double,v,b);FLOOP(common_INT,0,b)(v)[common_INT]/=common_double;}while(0)
|
243
|
+
#define ARY_INPRO(f,u,v,b) do{(f)=0;for (common_INT=0 ; common_INT<(b)-3 ; common_INT+=4) (f)+=(u)[common_INT]*(v)[common_INT] + (u)[common_INT+1]*(v)[common_INT+1] + (u)[common_INT+2]*(v)[common_INT+2] + (u)[common_INT+3]*(v)[common_INT+3]; if (common_INT+1<(b)){(f)+=(u)[common_INT]*v[common_INT]+(u)[common_INT+1]*(v)[common_INT+1]; if (common_INT+2<(b)) (f)+=(u)[common_INT+2]*(v)[common_INT+2];} else if (common_INT<(b)) (f)+=(u)[common_INT]*(v)[common_INT];}while(0)
|
244
|
+
|
245
|
+
//#define ARY_DIST(f,u,v,b) do{(f)=0;for (common_size_t=0 ; common_size_t<(b)-3 ; common_size_t+=4)(f)+=(u)[common_size_t]*(v)[common_size_t]; if (common_size_t+1<(b)){(f)+=(u)[common_size_t]*v[common_size_t]+(u)[common_size_t+1]*(v)[common_size_t+1]; if (common_size_t+2<(b)) (f)+=(u)[common_size_t+2]*(v)[common_size_t+2];} else if (common_size_t<b) (f)+=(u)[common_size_t]*(v)[common_size_t];}while(0)
|
246
|
+
|
247
|
+
/* macros for permutation arrays */
|
248
|
+
#define ARY_INIT_PERM(f,end) do{FLOOP(common_INT,0,(INT)end)(f)[common_INT]=common_INT;}while(0)
|
249
|
+
#define ARY_INV_PERM_(f,p,end) do{ARY_FILL(f,0,end,-1);FLOOP(common_INT,0,end)if((p)[common_INT]>=0&&(p)[common_INT]<(end))(f)[(p)[common_INT]]=common_INT;}while(0)
|
250
|
+
#define ARY_INV_PERM(f,p,end,c,x) do{malloc2(f,end,c,x);ARY_INV_PERM_(f,p,end);}while(0)
|
251
|
+
#define ARY_RND_PERM_(f,end) do{(f)[0]=0;FLOOP(common_INT,1,end){common_INT2=rnd(common_INT+1);(f)[common_INT]=(f)[common_INT2];(f)[common_INT2]=common_INT;}}while(0)
|
252
|
+
#define ARY_RND_PERM(f,end,c,x) do{malloc2(f,end,c,x);ARY_RND_PERM_(f,end);}while(0)
|
253
|
+
/* permute f so that f[i]=f[p[i]] (inverse perm). p will be destroyed (filled by end) */
|
254
|
+
#define ARY_INVPERMUTE_(f,p,s,end) do{ FLOOP(common_INT,0,end){ if ( (p)[common_INT]<(end) ){ (s)=(f)[common_INT]; do { common_INT2=common_INT; common_INT=(p)[common_INT]; (f)[common_INT2]=(f)[common_INT]; (p)[common_INT2]=end; }while ( (p)[common_INT]<(end) ); (f)[common_INT2] = (s);}}}while(0)
|
255
|
+
/* permute f so that f[i]=f[p[i]] (inverse perm). not destroy p by allocating tmp memory */
|
256
|
+
#define ARY_INVPERMUTE(f,p,s,end,c,x) do{ calloc2(common_pnt,end,c,x);FLOOP(common_INT,0,end){ if ( common_pnt[common_INT]==0 ){ (s)=(f)[common_INT]; do{ common_INT2=common_INT; common_INT=(p)[common_INT]; (f)[common_INT2]=(f)[common_INT]; common_pnt[common_INT2]=1; }while( common_pnt[common_INT]==0 ); (f)[common_INT2] = (s);}} free(common_pnt); }while(0)
|
257
|
+
//#define ARY_PERM(f,p,s,mark,end) do{FLOOP(common_size_t,0,end){ }}while(0)
|
258
|
+
|
259
|
+
/* macros for printing (writing to file) arrays */
|
260
|
+
#define ARY_PRINT(f,x,y,a) do{FLOOP(common_size_t,x,y)printf(a,(f)[common_size_t]);printf("\n");}while(0)
|
261
|
+
#define ARY_FPRINT(fp,f,x,y,a) do{FLOOP(common_size_t,(size_t)x,(size_t)y)fprintf((FILE *)fp,a,(f)[common_size_t]);fputc('\n',(FILE *)fp);}while(0)
|
262
|
+
#define ARY_EXP(f,a,c,x) do{reallocx((f).v,a,(f).end,(f).t,e,c,x);}while(0)
|
263
|
+
|
264
|
+
#define ST_MAX(m,i,S,a,x,y) do{(m)=(S)[x].a;(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)<(S)[common_INT].a){(i)=common_INT;(m)=(S)[i].a;}}while(0)
|
265
|
+
#define ST_MIN(m,i,S,a,x,y) do{(m)=(S)[x].a;(i)=(x);FLOOP(common_INT,(x)+1,y)if((m)>(S)[common_INT].a){(i)=common_INT;(m)=(S)[i].a;}}while(0)
|
266
|
+
#define ST_SUM(k,S,a,x,y) do{(k)=0;FLOOP(common_INT,x,y)(k)+=(S)[common_INT].a;}while(0)
|
267
|
+
#define ST_FILL(S,a,start,end,c) do{for(common_INT=(start);common_INT<(end);common_INT++)(S)[common_INT].a = (c);}while(0)
|
268
|
+
#define ST_PRINT(S,a,x,y,f) do{FLOOP(common_size_t,x,y)printf(f,(S)[common_size_t].a );printf("\n");}while(0)
|
269
|
+
|
270
|
+
|
271
|
+
|
272
|
+
/* a macro for open files with exiting if an error occurs */
|
273
|
+
#ifdef _MSC_
|
274
|
+
#define fopen2(f,a,b,c,x) do{fopen_s(&f,a,b);if(!f){ERROR_MES="file open error";fprintf(stderr,"file open error: %s, file name %s, open mode %s\n",c,a,b);x;}}while(0)
|
275
|
+
#else
|
276
|
+
#define fopen2(f,a,b,c,x) do{if(!((f)=fopen(a,b))){ERROR_MES="file open error";fprintf(stderr,"file open error: %s, file name %s, open mode %s\n",c,a,b);x;}}while(0)
|
277
|
+
#endif
|
278
|
+
#define FILE2_open(f,a,b,c,x) do{if(a)fopen2((f).fp,a,b,c,x);else(f).fp=NULL;malloc2((f).buf_org,FILE2_BUFSIZ+1,c,x);(f).buf=(f).buf_org;(f).buf_end=(f).buf_org-1;}while(0)
|
279
|
+
#define FILE2_open_(f,a,c,x) do{(f).fp=a;malloc2((f).buf_org,FILE2_BUFSIZ+1,c,x);(f).buf=(f).buf_org;(f).buf_end=(f).buf_org-1;}while(0)
|
280
|
+
|
281
|
+
/* macros for allocating memory with exiting if an error occurs */
|
282
|
+
#define free2(a) do{if(a){free(a);(a)=NULL;}}while(0)
|
283
|
+
#define free2d(a) do{if(a){free2((a)[0]);}free(a);(a)=NULL;}while(0)
|
284
|
+
#define fclose2(a) do{if(a){fclose(a);(a)=NULL;}}while(0)
|
285
|
+
|
286
|
+
/* macros for reading integers from file, d=0 read one-line, d=1 read all file */
|
287
|
+
//#define ARY_SCAN(k,a,fp,d) do{(k)=0;do{do{FILE2_read_##a(&(fp));}while((FILE_err&6)==8-(d)*4);if(FILE_err&(4-2*(d)))break;(k)++;}while((FILE_err&(3-(d)))==0);}while(0)
|
288
|
+
#define ARY_SCAN(k,a,fp,d) do{(k)=0;do{do{FILE2_read_##a(&(fp));}while((FILE_err&((d)*5))==5);if(RANGE(5+(int)(d),FILE_err,6))break;(k)++;}while((FILE_err&(3-(int)(d)))==0);}while(0)
|
289
|
+
#define ARY_READ(f,a,k,fp) do{FLOOP(common_size_t,0,(size_t)k){do{(f)[common_size_t]=FILE2_read_##a(&(fp));}while((FILE_err&6)==4);if(FILE_err&2)break;}}while(0)
|
290
|
+
#define ARY_LOAD(f,a,k,n,d,c,x) do{FILE2_open(common_FILE2,n,"r",c,x);ARY_SCAN(k,a,common_FILE2,d);malloc2(f,(k)+1,c,x);FILE2_reset(&common_FILE2);ARY_READ(f,a,k,common_FILE2);FILE2_close(&common_FILE2);}while(0)
|
291
|
+
#define ARY_WRITE(n,f,k,q,c,x) do{fopen2(common_FILE,n,"w",c,x);ARY_FPRINT(common_FILE,f,0,k,q);fclose(common_FILE);}while(0)
|
292
|
+
|
293
|
+
/* macros for generalized queue; end mark is necessary for INTSEC */
|
294
|
+
#define MQUE_FLOOP(V,z) for((z)=(V).v;(z)<(V).v+(V).t ; (z)++)
|
295
|
+
|
296
|
+
#ifdef _cplusplus_
|
297
|
+
#define MQUE_FLOOP_(V,z,s) for((z)=(V).v ; (char *)(z)<((char *)(V).v)+(V).t*(s) ; (z)=(typeof(z))(((char *)(z))+(s)))
|
298
|
+
#else
|
299
|
+
#define MQUE_FLOOP_(V,z,s) for((z)=(V).v ; (char *)(z)<((char *)(V).v)+(V).t*(s) ; (z)=(void *)(((char *)(z))+(s)))
|
300
|
+
#endif
|
301
|
+
|
302
|
+
#define MQUE_MLOOP(V,z,M) for((z)=(V).v; *((QUEUE_INT *)z)<(M) ; (z)++)
|
303
|
+
|
304
|
+
/// !!! errr MQUE_INTSEC !!!!!
|
305
|
+
#define MQUE_INTSEC(f,U,V) do{\
|
306
|
+
common_INT=0;(f)=0;\
|
307
|
+
FLOOP(common_INT2,0,(U).t){\
|
308
|
+
while(*((QUEUE_INT *)(&((V).v[common_INT])))<*((QUEUE_INT *)(&((U).v[common_INT2])))&&common_INT<(V).t){ \
|
309
|
+
if (++common_INT >= (V).t) break;\
|
310
|
+
}if(*((QUEUE_INT *)(&((V).v[common_INT])))==*((QUEUE_INT *)(&((U).v[common_INT2]))))(f)++;\
|
311
|
+
}}while(0)
|
312
|
+
#define MQUE_UNION(f,U,V) do{MQUE_INTSEC(f,U,V);(f)=(U).t+(V).t-(f);}while(0)
|
313
|
+
#define MQUE_DIF(f,U,V) do{MQUE_INTSEC(f,U,V);(f)=(U).t+(V).t-(f)-(f);}while(0)
|
314
|
+
#define MQUE_RM_DUP(V) do{\
|
315
|
+
if((V).t>1){\
|
316
|
+
common_INT=1;\
|
317
|
+
FLOOP(common_INT2,1,(V).t){\
|
318
|
+
if ( *((QUEUE_INT *)(&((V).v[common_INT2-1]))) != *((QUEUE_INT *)(&((V).v[common_INT2]))) ) (V).v[common_INT++]=(V).v[common_INT2];\
|
319
|
+
} (V).t=common_INT;\
|
320
|
+
}\
|
321
|
+
}while(0)
|
322
|
+
|
323
|
+
#define MQUE_UNIFY(V,a) do{\
|
324
|
+
if((V).t>1){\
|
325
|
+
common_INT=0;\
|
326
|
+
FLOOP(common_INT2,1,(V).t){\
|
327
|
+
if ( *((QUEUE_INT *)(&((V).v[common_INT2-1]))) != *((QUEUE_INT *)(&((V).v[common_INT2]))) ) (V).v[++common_INT]=(V).v[common_INT2];\
|
328
|
+
else *((a*)(((QUEUE_INT *)(&((V).v[common_INT2])))+1)) += *((a*)(((QUEUE_INT *)(&((V).v[common_INT2])))+1));\
|
329
|
+
} (V).t=common_INT+1;\
|
330
|
+
}}while(0)
|
331
|
+
|
332
|
+
|
333
|
+
|
334
|
+
|
335
|
+
#ifndef VEC_VAL
|
336
|
+
#ifdef VEC_VAL_CHAR
|
337
|
+
#define VEC_VAL char
|
338
|
+
#define VEC_VAL2 LONG
|
339
|
+
#define VEC_VAL_END 128
|
340
|
+
#define VEC_VAL2_END LONGHUGE
|
341
|
+
#define VEC_VALF "%hhd"
|
342
|
+
#elif defined(VEC_VAL_UCHAR)
|
343
|
+
#define VEC_VAL unsigned char
|
344
|
+
#define VEC_VAL2 LONG
|
345
|
+
#define VEC_VAL_END 256
|
346
|
+
#define VEC_VAL2_END LONGHUGE
|
347
|
+
#define VEC_VALF "%hhu"
|
348
|
+
#elif defined(VEC_VAL_INT)
|
349
|
+
#define VEC_VAL int
|
350
|
+
#define VEC_VAL2 LONG
|
351
|
+
#define VEC_VAL_END INTHUGE
|
352
|
+
#define VEC_VAL2_END LONGHUGE
|
353
|
+
#define VEC_VALF "%d"
|
354
|
+
#else
|
355
|
+
#define VEC_VAL double
|
356
|
+
#define VEC_VAL2 double
|
357
|
+
#define VEC_VAL_END DOUBLEHUGE
|
358
|
+
#define VEC_VAL2_END DOUBLEHUGE
|
359
|
+
#define VEC_VALF "%f"
|
360
|
+
#endif
|
361
|
+
#endif
|
362
|
+
|
363
|
+
#ifndef VEC_ID
|
364
|
+
#ifdef VEC_ID_LONG
|
365
|
+
#define VEC_ID LONG
|
366
|
+
#define VEC_ID_END LONGHUGE
|
367
|
+
#define VEC_IDF "%lld"
|
368
|
+
#else
|
369
|
+
#define VEC_ID int
|
370
|
+
#define VEC_ID_END INTHUGE
|
371
|
+
#define VEC_IDF "%d"
|
372
|
+
#endif
|
373
|
+
#endif
|
374
|
+
|
375
|
+
/* vector */
|
376
|
+
typedef struct {
|
377
|
+
unsigned char type; // mark to identify type of the structure
|
378
|
+
VEC_VAL *v;
|
379
|
+
VEC_ID end;
|
380
|
+
VEC_ID t;
|
381
|
+
} VEC;
|
382
|
+
|
383
|
+
extern VEC INIT_VEC;
|
384
|
+
extern PERM common_PERM, *common_PERMp;
|
385
|
+
extern VEC_VAL common_VEC_VAL, *common_VEC_VALp;
|
386
|
+
extern VEC_ID common_VEC_ID;
|
387
|
+
|
388
|
+
/* tranpose the matrix ; counting/transpose/memory_allocate */
|
389
|
+
#define MQUE_DELIVERY_CNT(c,jump,f,y,M) do{ \
|
390
|
+
FLOOP(common_VEC_ID, 0, (f).t){ \
|
391
|
+
MQUE_MLOOP( (f).v[common_VEC_ID], y, M){ \
|
392
|
+
if( (c)[*((QUEUE_INT *)y)] == 0 ) ARY_INS(jump, *((QUEUE_INT *)y)); \
|
393
|
+
(c)[*((QUEUE_INT *)y)]++; \
|
394
|
+
} \
|
395
|
+
}}while(0)
|
396
|
+
#define MQUE_DELIVERY(occ,jump,f,y,M) do{ \
|
397
|
+
FLOOP (common_VEC_ID, 0, (f).t){ \
|
398
|
+
MQUE_MLOOP ((f).v[common_VEC_ID], y, M){ \
|
399
|
+
if( (occ)[*((QUEUE_INT *)y)].t == 0 ) ARY_INS( jump, *((QUEUE_INT *)y)); \
|
400
|
+
ARY_INS( (occ)[*((QUEUE_INT *)y)], common_VEC_ID); \
|
401
|
+
} \
|
402
|
+
}}while(0)
|
403
|
+
#ifdef _cplusplus_
|
404
|
+
#define MQUE_ALLOC(Q,rows,rowt,unit,ext,x) do{ \
|
405
|
+
common_size_t=0; \
|
406
|
+
FLOOP (common_VEC_ID, 0, rows) common_size_t += rowt[common_VEC_ID]; \
|
407
|
+
calloc2 (Q, (rows)+1, "MQUE_ALLOC: Q", x); \
|
408
|
+
malloc2 (common_pnt, (common_size_t+(rows)*(ext)+2)*((unit)<sizeof(QUEUE_INT)?sizeof(QUEUE_INT):(unit)), "MQUE_ALLOC: Q.v", {free(Q);x;}); \
|
409
|
+
FLOOP (common_VEC_ID, 0, rows){ \
|
410
|
+
(Q)[common_VEC_ID].end = rowt[common_VEC_ID]; \
|
411
|
+
(Q)[common_VEC_ID].v = (typeof((Q)[common_VEC_ID].v))common_pnt; \
|
412
|
+
common_pnt += ((unit)<sizeof(QUEUE_INT)?sizeof(QUEUE_INT):(unit))*(rowt[common_VEC_ID]+(ext));\
|
413
|
+
}}while(0)
|
414
|
+
#else
|
415
|
+
#define MQUE_ALLOC(Q,rows,rowt,unit,ext,x) do{ \
|
416
|
+
common_size_t=0; \
|
417
|
+
FLOOP (common_VEC_ID, 0, rows) common_size_t += rowt[common_VEC_ID]; \
|
418
|
+
calloc2 (Q, (rows)+1, "MQUE_ALLOC: Q", x); \
|
419
|
+
malloc2 (common_pnt, (common_size_t+(rows)*(ext)+2)*((unit)<sizeof(QUEUE_INT)?sizeof(QUEUE_INT):(unit)), "MQUE_ALLOC: Q.v", {free(Q);x;}); \
|
420
|
+
FLOOP (common_VEC_ID, 0, rows){ \
|
421
|
+
(Q)[common_VEC_ID].end = rowt[common_VEC_ID]; \
|
422
|
+
(Q)[common_VEC_ID].v = (void *)common_pnt; \
|
423
|
+
common_pnt += ((unit)<sizeof(QUEUE_INT)?sizeof(QUEUE_INT):(unit))*(rowt[common_VEC_ID]+(ext));\
|
424
|
+
}}while(0)
|
425
|
+
#endif
|
426
|
+
|
427
|
+
/*********************************************************/
|
428
|
+
|
429
|
+
#define SHOW_MESSAGE 1 // not print messages
|
430
|
+
#define SHOW_PROGRESS 2 // show progress of the computation
|
431
|
+
#define LOAD_PERM 8 // permute the nodes/items by something
|
432
|
+
#define LOAD_RM_DUP 16 // duplicate items in each row, for loading data
|
433
|
+
#define LOAD_INCSORT 32 // sort rows in increasing order, for loading data
|
434
|
+
#define LOAD_DECSORT 64 // sort rows in decreasing order, for loading data
|
435
|
+
#define LOAD_ELE 128 // load tuple-list file
|
436
|
+
#define LOAD_TPOSE 256 // transpose the file when load
|
437
|
+
#define LOAD_DBLBUF 512 // transpose the file when load
|
438
|
+
#define LOAD_WSORT 1024 // sort rows by their weights
|
439
|
+
#define LOAD_SIZSORT 2048 // sort rows by their sizes
|
440
|
+
#define LOAD_DECROWSORT 4096 // sort rows in decreasing order
|
441
|
+
#define LOAD_NUM 8192 // read #columns, #rows and #elements from the 1st line of the file
|
442
|
+
|
443
|
+
#define LOAD_EDGEW 16384 // read edge weight
|
444
|
+
#define LOAD_ARCW 32768 // read arc weight
|
445
|
+
#define LOAD_NODEW 65536 // read node weight
|
446
|
+
#define LOAD_BIPARTITE 131072 // read bipartite graph
|
447
|
+
#define LOAD_EDGE 262144 // read edge
|
448
|
+
#define LOAD_ARC 524288 // read arc
|
449
|
+
#define LOAD_GRAPHNUM 1048576 // read #vertices and #edges from the 1st line of the file
|
450
|
+
#define LOAD_ID1 2097152 // node ID begins from 1
|
451
|
+
|
452
|
+
#define FILE_COUNT_ROWT 32 // count size of each row
|
453
|
+
#define FILE_COUNT_CLMT 64 // count size of each column
|
454
|
+
#define FILE_COUNT_NUM LOAD_NUM // read #columns, #rows and #elements
|
455
|
+
#define FILE_COUNT_GRAPHNUM LOAD_GRAPHNUM // read #vertices and #edges
|
456
|
+
|
457
|
+
#define FILE2_BUFSIZ 16384
|
458
|
+
typedef struct { // structure for fast file reader routines
|
459
|
+
unsigned char type; // type definition
|
460
|
+
FILE *fp;
|
461
|
+
char *buf_org, *buf, *buf_end; // head/current/tail of buffer
|
462
|
+
} FILE2;
|
463
|
+
extern FILE2 INIT_FILE2, common_FILE2;
|
464
|
+
|
465
|
+
void FILE2_flush (FILE2 *fp);
|
466
|
+
void FILE2_close (FILE2 *fp);
|
467
|
+
void FILE2_closew (FILE2 *fp);
|
468
|
+
void FILE2_reset (FILE2 *fp);
|
469
|
+
int FILE2_getc (FILE2 *fp);
|
470
|
+
void FILE2_puts (FILE2 *fp, char *s);
|
471
|
+
void FILE2_putc (FILE2 *fp, char c);
|
472
|
+
|
473
|
+
/* message output */
|
474
|
+
//void print_mes (int flag, char *mes, ...);
|
475
|
+
//void print_err (char *mes, ...);
|
476
|
+
void mfree_(void *x, ...);
|
477
|
+
|
478
|
+
/* compute the minimum prime no less than n */
|
479
|
+
LONG min_prime (LONG n);
|
480
|
+
|
481
|
+
/* decompose the string by separator, and set v[i] to each resulted string.
|
482
|
+
consecutive separators are regarded as one separator. */
|
483
|
+
int string_decompose (char **v, char *s, char sep, int max);
|
484
|
+
|
485
|
+
/* make two random numbers under normal distribution N(0,1) */
|
486
|
+
void rand_mk_2normal (double *a, double *b);
|
487
|
+
/* make a random point on a supersphere of d-dim., and set to double array already allocated */
|
488
|
+
void rand_d_gaussian (double *p, int d);
|
489
|
+
void rand_sphere (double *p, int d);
|
490
|
+
|
491
|
+
|
492
|
+
|
493
|
+
/* Read an integer from the file and return it,
|
494
|
+
with read through the non-numeric letters.
|
495
|
+
If it reaches to the end-of-file, then set FILE_err=2, if it reads a
|
496
|
+
newline, then set FILE_err=1.
|
497
|
+
If read either the end-of-file or newline before reading an integer,
|
498
|
+
return -1 */
|
499
|
+
FILE_LONG FILE2_read_int (FILE2 *fp);
|
500
|
+
double FILE2_read_double (FILE2 *fp);
|
501
|
+
WEIGHT FILE2_read_WEIGHT (FILE2 *fp);
|
502
|
+
|
503
|
+
/* fast file routine, print number, c is the char to be printed preceding to the number
|
504
|
+
if c==0, nothing will be printed preceding the number
|
505
|
+
if len<0 then the #digits following '.' does not change (filed by '0') */
|
506
|
+
void FILE2_print_int (FILE2 *fp, LONG n, char c);
|
507
|
+
void FILE2_print_real (FILE2 *fp, double n, int len, char c);
|
508
|
+
void FILE2_print_WEIGHT (FILE2 *fp, WEIGHT w, int len, char c);
|
509
|
+
void FILE2_printf (FILE2 *fp, char *mes, ...);
|
510
|
+
|
511
|
+
/* print a real number in a good style */
|
512
|
+
void fprint_real (FILE *fp, double f);
|
513
|
+
void print_real (double f);
|
514
|
+
void fprint_WEIGHT (FILE *fp, WEIGHT f);
|
515
|
+
void print_WEIGHT (WEIGHT f);
|
516
|
+
|
517
|
+
#define FILE_COUNT_INT VEC_ID
|
518
|
+
#define FILE_COUNT_INTF VEC_IDF
|
519
|
+
typedef struct {
|
520
|
+
int flag;
|
521
|
+
FILE_COUNT_INT clms, rows, eles, clm_end, row_end, row_btm, clm_btm; // #rows, #column, #elements, minimum elements
|
522
|
+
FILE_COUNT_INT row_min, row_max, clm_min, clm_max; // maximum/minimum size of column
|
523
|
+
FILE_COUNT_INT *rowt, *clmt; // size of each row/clmn
|
524
|
+
WEIGHT total_rw, total_cw, *rw, *cw; // WEIGHTs for rows/columns ... reserved.
|
525
|
+
FILE_COUNT_INT rw_end, cw_end;
|
526
|
+
PERM *rperm, *cperm; // permutation (original->internal) of rows and columns
|
527
|
+
} FILE_COUNT;
|
528
|
+
|
529
|
+
extern FILE_COUNT INIT_FILE_COUNT;
|
530
|
+
|
531
|
+
/* count the clms, rows, items, each row size, each column size */
|
532
|
+
/* file types can be, array list and element list*/
|
533
|
+
/* support transpose */
|
534
|
+
FILE_COUNT FILE2_count (FILE2 *fp, int flag, int skip_rows, int int_rows, int skip_clms, int int_clms, FILE_COUNT_INT row_limit);
|
535
|
+
|
536
|
+
/******************* integer array routines **************************/
|
537
|
+
|
538
|
+
/******************************* permutation routines ****************/
|
539
|
+
/* permutation is given by an integer array */
|
540
|
+
|
541
|
+
/* sort an array of size "siz", composed of a structure of size "unit" byte
|
542
|
+
in the order of perm */
|
543
|
+
/* use temporary memory of siz*unit byte */
|
544
|
+
//void perm_struct (void *a, int unit, int *perm, size_t siz);
|
545
|
+
|
546
|
+
/* SLIST:very simple one-sided list */
|
547
|
+
void SLIST_init (int *l, int num, int siz);
|
548
|
+
void SLIST_end (int *l);
|
549
|
+
#define SLIST_INS(l,m,e) (l[e]=l[m],l[m]=e);
|
550
|
+
|
551
|
+
#define QQSORT_ELE(a,x) ((a *)(&(common_pnt[(*((PERM *)(x)))*common_int])))
|
552
|
+
#define QQSORT_ELEt(a,x) (((a *)&(common_pnt[(*((PERM *)x))*common_int]))->t)
|
553
|
+
/* quick sort macros */
|
554
|
+
#define QSORT_TYPE(a,b) \
|
555
|
+
b common_##a; \
|
556
|
+
int qsort_cmp_##a (const void *x, const void *y){ \
|
557
|
+
if ( *((b *)x) < *((b *)y) ) return (-1); else return ( *((b *)x) > *((b *)y) ); \
|
558
|
+
} \
|
559
|
+
int qsort_cmp__##a (const void *x, const void *y){ \
|
560
|
+
if ( *((b *)x) > *((b *)y) ) return (-1); else return ( *((b *)x) < *((b *)y) ); \
|
561
|
+
} \
|
562
|
+
int qqsort_cmp_##a (const void *x, const void *y){ \
|
563
|
+
b *xx=QQSORT_ELE(b,x), *yy=QQSORT_ELE(b,y); \
|
564
|
+
if ( *xx < *yy ) return (-1); \
|
565
|
+
else return ( *xx > *yy ); \
|
566
|
+
} \
|
567
|
+
int qqsort_cmp__##a (const void *x, const void *y){ \
|
568
|
+
b *xx=QQSORT_ELE(b,x), *yy=QQSORT_ELE(b,y); \
|
569
|
+
if ( *xx > *yy ) return (-1); \
|
570
|
+
else return ( *xx < *yy ); \
|
571
|
+
} \
|
572
|
+
void qsort_##a (b *v, size_t siz, int unit){ \
|
573
|
+
if ( unit == 1 || unit==-1 ) unit *= sizeof (b); \
|
574
|
+
if (unit<0) qsort (v, siz, -unit, qsort_cmp__##a); else qsort (v, siz, unit, qsort_cmp_##a); \
|
575
|
+
} \
|
576
|
+
void qsort_perm__##a (b *v, size_t siz, PERM *perm, int unit){ \
|
577
|
+
ARY_INIT_PERM(perm,(INT)siz); \
|
578
|
+
if ( unit == 1 || unit==-1 ) unit *= sizeof (b); \
|
579
|
+
common_int=MAX(unit,-unit); common_pnt=(char *)v; \
|
580
|
+
if (unit<0) qsort (perm, siz, sizeof(PERM), qqsort_cmp__##a); \
|
581
|
+
else qsort (perm, siz, sizeof(PERM), qqsort_cmp_##a); \
|
582
|
+
} \
|
583
|
+
PERM *qsort_perm_##a (b *v, size_t siz, int unit){ \
|
584
|
+
PERM *perm; malloc2(perm, siz, "qsort_perm_##a:perm", EXIT0); \
|
585
|
+
qsort_perm__##a (v, siz, perm, unit); return(perm); \
|
586
|
+
} \
|
587
|
+
size_t bin_search_##a (b *v, b u, size_t siz, int unit){ \
|
588
|
+
size_t s=0, t; \
|
589
|
+
b n; \
|
590
|
+
int sign = 1; \
|
591
|
+
if ( unit < 0 ){ sign = -1; unit = -unit; } \
|
592
|
+
if ( unit == 1 ) unit *= sizeof (b); \
|
593
|
+
while(1) { \
|
594
|
+
t = (s+siz) /2; \
|
595
|
+
n = *((b *)(((char *)v)+unit*t)); \
|
596
|
+
if ( u == n ){ common_int = 1; return (t); }; \
|
597
|
+
if ( s == t ) break; \
|
598
|
+
if ( (u < n && sign>0) || (u > n && sign<0) ) siz = t; else s = t; \
|
599
|
+
} \
|
600
|
+
common_int = 0; \
|
601
|
+
return (u<=n? s: s+1); \
|
602
|
+
}
|
603
|
+
#define QSORT_TYPE_HEADER(a,b) \
|
604
|
+
extern b common_##a; \
|
605
|
+
int qsort_cmp_##a (const void *x, const void *y); \
|
606
|
+
int qsort_cmp__##a (const void *x, const void *y); \
|
607
|
+
int qqsort_cmp_##a (const void *x, const void *y); \
|
608
|
+
int qqsort_cmp__##a (const void *x, const void *y); \
|
609
|
+
void qsort_##a(b *v, size_t siz, int unit); \
|
610
|
+
void qsort_perm__##a (b *v, size_t siz, PERM *perm, int unit); \
|
611
|
+
PERM *qsort_perm_##a (b *v, size_t siz, int unit); \
|
612
|
+
size_t bin_search_##a (b *v, b u, size_t siz, int unit);
|
613
|
+
|
614
|
+
QSORT_TYPE_HEADER(int, int)
|
615
|
+
QSORT_TYPE_HEADER(uint, unsigned int)
|
616
|
+
QSORT_TYPE_HEADER(double, double)
|
617
|
+
QSORT_TYPE_HEADER(char, char)
|
618
|
+
QSORT_TYPE_HEADER(uchar, unsigned char)
|
619
|
+
QSORT_TYPE_HEADER(short, short)
|
620
|
+
QSORT_TYPE_HEADER(ushort, unsigned short)
|
621
|
+
QSORT_TYPE_HEADER(WEIGHT, WEIGHT)
|
622
|
+
QSORT_TYPE_HEADER(LONG, LONG)
|
623
|
+
QSORT_TYPE_HEADER(VEC_ID, VEC_ID)
|
624
|
+
QSORT_TYPE_HEADER(VEC_VAL, VEC_VAL)
|
625
|
+
QSORT_TYPE_HEADER(VEC_VAL2, VEC_VAL2)
|
626
|
+
QSORT_TYPE_HEADER(FILE_COUNT_INT, FILE_COUNT_INT)
|
627
|
+
|
628
|
+
int qsort_cmp_VECt (const void *x, const void *y);
|
629
|
+
int qsort_cmp__VECt (const void *x, const void *y);
|
630
|
+
void qsort_VECt (VEC *v, size_t siz, int unit);
|
631
|
+
int qqsort_cmp_VECt (const void *x, const void *y);
|
632
|
+
int qqsort_cmp__VECt (const void *x, const void *y);
|
633
|
+
void qsort_perm__VECt (VEC *v, size_t siz, PERM *perm, int unit);
|
634
|
+
PERM *qsort_perm_VECt (VEC *v, size_t siz, int unit);
|
635
|
+
|
636
|
+
/* swap macro for integer, double, char, and pointer */
|
637
|
+
#define SWAP_INT(a,b) (common_LONG=a,a=b,b=common_LONG)
|
638
|
+
#define SWAP_DOUBLE(a,b) (common_double=a,a=b,b=common_double)
|
639
|
+
#define SWAP_size_t(a,b) (common_size_t=a,a=b,b=common_size_t)
|
640
|
+
#ifdef _cplusplus_
|
641
|
+
#define SWAP_PNT(a,b) (common_pnt=(typeof(common_pnt))a,a=(typeof(a))b,b=(typeof(b))common_pnt)
|
642
|
+
#else
|
643
|
+
#define SWAP_PNT(a,b) (common_pnt=(void *)a,a=(void *)b,b=(void *)common_pnt)
|
644
|
+
#endif
|
645
|
+
|
646
|
+
#define SWAP_VEC_ID(a,b) (common_VEC_ID=a,a=b,b=common_VEC_ID)
|
647
|
+
#define SWAP_FILE_COUNT_INT(a,b) (common_FILE_COUNT_INT=a,a=b,b=common_FILE_COUNT_INT)
|
648
|
+
|
649
|
+
/* sort index(int)/WEIGHT array and return the indices of the result */
|
650
|
+
/* perm[i*2] := rank of ith cell */
|
651
|
+
/* perm[i*2+1] := index of ith smallest cell */
|
652
|
+
/* flag!=NULL => opposite direction sort */
|
653
|
+
|
654
|
+
//int *int_index_sort (int *w, size_t siz, int flag);
|
655
|
+
//int *WEIGHT_index_sort (WEIGHT *w, size_t siz, int flag);
|
656
|
+
|
657
|
+
/* radix sort for array of structures, by their integer members
|
658
|
+
ranging from mm to m */
|
659
|
+
/* sort array "perm" according to (int/void*) array "a".
|
660
|
+
if perm==NULL, allocate memory and for perm */
|
661
|
+
/* return the permutation array of the result of the sorting
|
662
|
+
in the decreasing order if unit<0 (unimplemented!!!) */
|
663
|
+
int *radix_sort (void *a, size_t siz, int unit, int mm, int m, int *perm);
|
664
|
+
|
665
|
+
/* permutate structure array *tt of unit size unit of size num, according to perm array *pp */
|
666
|
+
/* num has to be <INTHUGE/2 */
|
667
|
+
/* unit<0 means decreasing order (un-implemented!!!) */
|
668
|
+
void structure_permute (void *tt, int unit, int num, void *pp, int weight_siz);
|
669
|
+
|
670
|
+
#ifdef STDLIB2_RADIX_SORT // radix sort with 1M byte static memory
|
671
|
+
void intarray_sort_iter (unsigned int *a, size_t siz, int unit);
|
672
|
+
void intarray_sort_iter_ (unsigned int *a, size_t siz, int unit);
|
673
|
+
void intarray_sort (unsigned *a, size_t siz, int unit);
|
674
|
+
#endif
|
675
|
+
|
676
|
+
/* bitmasks, used for bit operations */
|
677
|
+
extern int BITMASK_UPPER1[32];
|
678
|
+
extern int BITMASK_UPPER1_[32];
|
679
|
+
extern int BITMASK_LOWER1[32];
|
680
|
+
extern int BITMASK_LOWER1_[32];
|
681
|
+
extern int BITMASK_1[32];
|
682
|
+
extern int BITMASK_31[32];
|
683
|
+
extern int BITMASK_16[8];
|
684
|
+
extern int BITMASK_UPPER16[8];
|
685
|
+
extern int BITMASK_LOWER16[8];
|
686
|
+
extern int BITMASK_FACT16[8];
|
687
|
+
|
688
|
+
|
689
|
+
#endif
|
690
|
+
|
691
|
+
|
692
|
+
/******************************************/
|
693
|
+
/* ==== terminology for comments ====
|
694
|
+
range check: to check the input parameter is valid, or in the valid range.
|
695
|
+
If a function does not have this, its comment has "no range check"
|
696
|
+
*/
|
697
|
+
|
698
|
+
/* ==== rules for the name of functions and routines ====
|
699
|
+
init: initialization for an object, structure, etc. memory is allocated
|
700
|
+
if needed.
|
701
|
+
end: compared to init, termination of structures, etc.
|
702
|
+
free allocated memory if it exists, but not free itself.
|
703
|
+
different from ordinary new, create, del, free.
|
704
|
+
|
705
|
+
cpy: copy an object without allocating memory
|
706
|
+
dup: make a duplication of an object with allocating new memory
|
707
|
+
|
708
|
+
new: new. allocate memory for new object. also used for re-allocation from
|
709
|
+
the list of deleted objects
|
710
|
+
del: delete. free memory, or insert it to the list of deleted objects
|
711
|
+
|
712
|
+
ins : insert. insert an element (active, not deleted) to an object, possible
|
713
|
+
at the given position.
|
714
|
+
out : extract. extract an element, possibly specified, from an object.
|
715
|
+
it will be not deleted.
|
716
|
+
rm : extract, and delete
|
717
|
+
rmall: delete all (specified) elements of an object
|
718
|
+
mk : make. new+ins�B
|
719
|
+
mv : move. move the elements from an object to another,
|
720
|
+
or change the position.
|
721
|
+
|
722
|
+
update : update an object, possibly of specified position, to the exact,
|
723
|
+
or to the current one.
|
724
|
+
chg : change the status of an object to the specified one.
|
725
|
+
|
726
|
+
prv: point the previous element
|
727
|
+
nxt: point the next element
|
728
|
+
end: the maximum size (allocated size) of an array, etc.
|
729
|
+
num: the (current) number of elements in an array, etc.
|
730
|
+
kth: for the use of "first k object"
|
731
|
+
tkth: for the use of "first k object from the end". to kth.
|
732
|
+
rnd: random
|
733
|
+
print: print structure and etc.
|
734
|
+
find: search or find an specified element from the set of structures, etc.
|
735
|
+
*/
|
736
|
+
|
737
|
+
/* ==== rules for the name of variables ====
|
738
|
+
- use i or j for the counter in loops
|
739
|
+
- use e for elements
|
740
|
+
- use k for the specified rank
|
741
|
+
- use f or flag for flagment
|
742
|
+
- use m for maximum value or minimum value
|
743
|
+
- use c for counters
|
744
|
+
*/
|
745
|
+
|
746
|
+
|