nysol-zdd 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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,170 @@
|
|
1
|
+
/* graph library by array list
|
2
|
+
12/Feb/2002 by Takeaki Uno
|
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
|
+
/****************************************************************************/
|
14
|
+
/* d = degree of node i := G->edge/in/out.v[i].t
|
15
|
+
d = max/min (in/out) degree := VEC_MAXT(d,G->edge.v/in.v/out.v,0,...->t) (VEC_MINT, resp.)
|
16
|
+
#nodes := SGRAPH_NODE_NUM(G)
|
17
|
+
#edges := G->edge.eles/2
|
18
|
+
#arcs := G->in.eles or G->out.eles
|
19
|
+
load_node_weight := ARY_LOAD_WEIGHT(G->node_w,WEIGHT,filename,counter,"errormes", EXIT)
|
20
|
+
load_node_weight := ARY_LOAD_WEIGHT(G->node_w,WEIGHT,filename,counter,"errormes", EXIT)
|
21
|
+
|
22
|
+
sort_node by size := SGRAPH_sort_node_iter (G, qsort_perm_VECt ((VEC *)Q, G->node_end, flag)
|
23
|
+
sort_node by weight := SGRAPH_sort_node_iter (G, qsort_perm_WEIGHT (w, G->node_end, flag)
|
24
|
+
*/
|
25
|
+
/****************************************************************************/
|
26
|
+
|
27
|
+
#ifndef _sgraph_h_
|
28
|
+
#define _sgraph_h_
|
29
|
+
|
30
|
+
#include"stdlib2.h"
|
31
|
+
#include"vec.h"
|
32
|
+
|
33
|
+
|
34
|
+
/* structure for graph */
|
35
|
+
typedef struct {
|
36
|
+
unsigned char type; // structure type flag
|
37
|
+
SETFAMILY edge, in, out; // setfamily for edge, in-arc, out-arc
|
38
|
+
QUEUE_INT node1_num; // the size of vertex set 1, bipartite case. otherwise 0
|
39
|
+
int flag; // flag for load routine
|
40
|
+
WEIGHT *node_w, *wbuf; // pointer to the node weight array(int)
|
41
|
+
PERM *perm; // node permutation (nodes->original)
|
42
|
+
} SGRAPH;
|
43
|
+
extern SGRAPH INIT_SGRAPH;
|
44
|
+
|
45
|
+
#define SGRAPH_NODE_NUM(G) MAX((G).edge.t,(G).in.t)
|
46
|
+
|
47
|
+
/*************** initialization/termination ***********************/
|
48
|
+
|
49
|
+
/* initialization, termination, allocate arrays for weights, copy and duplication */
|
50
|
+
void SGRAPH_alloc (SGRAPH *G, int node_num, size_t edge_num, size_t arc_num);
|
51
|
+
void SGRAPH_cpy (SGRAPH *G2, SGRAPH *G);
|
52
|
+
void SGRAPH_end (SGRAPH *G);
|
53
|
+
|
54
|
+
|
55
|
+
/**************** addition/deletion **********************************/
|
56
|
+
|
57
|
+
/* make/take/remove edge e as connecting vertices u and v,
|
58
|
+
and edge (u,v).
|
59
|
+
do nothing if when make already existing edge, or delete non-existing edge.
|
60
|
+
with range check of parameters */
|
61
|
+
|
62
|
+
void SGRAPH_edge_mk (SGRAPH *G, QUEUE_INT u, QUEUE_INT v, WEIGHT w);
|
63
|
+
void SGRAPH_edge_rm (SGRAPH *G, QUEUE_INT u, QUEUE_INT v);
|
64
|
+
void SGRAPH_arc_mk (SGRAPH *G, QUEUE_INT u, QUEUE_INT v, WEIGHT w);
|
65
|
+
void SGRAPH_arc_rm (SGRAPH *G, QUEUE_INT u, QUEUE_INT v);
|
66
|
+
|
67
|
+
|
68
|
+
/******************* node/edge sort, and duplication reduction *********************/
|
69
|
+
|
70
|
+
/* subroutine of sort_edge_list */
|
71
|
+
void SGRAPH_sort_edge_list_iter (QUEUE *Q, WEIGHT **w, PERM *invperm, VEC_ID i, int flag);
|
72
|
+
|
73
|
+
/* sort each array list, increasing if flag=1, and decreasing if flag=-1 */
|
74
|
+
void SGRAPH_sort_edge_list (SGRAPH *G, int flag);
|
75
|
+
|
76
|
+
/* replace node i by perm and invperm */
|
77
|
+
void SGRAPH_replace_index (SGRAPH *G, PERM *perm, PERM *invperm);
|
78
|
+
|
79
|
+
/* sort the nodes by permutation given by tmp */
|
80
|
+
PERM *SGRAPH_sort_node_iter (SGRAPH *G, PERM *tmp);
|
81
|
+
|
82
|
+
/* sort the nodes by degrees, increasing if flag=1, decreasing if flag=-1 */
|
83
|
+
PERM *SGRAPH_sort_node_t (SGRAPH *G, QUEUE *Q, int flag);
|
84
|
+
|
85
|
+
/* sort the nodes by node_weight, increasing if flag=1, decreasing if flag=-1 */
|
86
|
+
PERM *SGRAPH_sort_node_w (SGRAPH *G, WEIGHT *w, int flag);
|
87
|
+
|
88
|
+
/* remove multiple edges/arcs and self loops
|
89
|
+
it works only when after applying sort_incident_edges */
|
90
|
+
void SGRAPH_simple (SGRAPH *G, int flag);
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
/******************* print routines *************************************/
|
96
|
+
|
97
|
+
|
98
|
+
/* print graph by numbers */
|
99
|
+
void SGRAPH_print (SGRAPH *G);
|
100
|
+
|
101
|
+
/* Write the graph to file. Edges, arcs, and nodes from 0 to node_num/edge_num/arc_num are written to file. Parameters are
|
102
|
+
(graph) (file name) (not write edge weight => 0) (not write node weight => 0) */
|
103
|
+
void SGRAPH_save (SGRAPH *G, char *fname);
|
104
|
+
|
105
|
+
/* graph load routine. Allocate memory as much as the size of input file.
|
106
|
+
parameters are,
|
107
|
+
(graph) (file name) (read edges?) (read arcs?) (read node weights?) (read edge weight?) (bipartite?) */
|
108
|
+
/* In the row of each vertex, write only vertices larger than it connected by an edge */
|
109
|
+
void SGRAPH_load (SGRAPH *G, char *fname, char *wfname);
|
110
|
+
void SGRAPH_load_node_weight (SGRAPH *G, char *filename);
|
111
|
+
|
112
|
+
/*
|
113
|
+
format of file:(including notifications to make input file)
|
114
|
+
|
115
|
+
the ith row corresponds to node i-1, and
|
116
|
+
ID list of nodes adjacent to i, and having ID > i, for undirected graph
|
117
|
+
ID list of nodes adjacent to i by out-going arc of i, for directed graph
|
118
|
+
Separator is ",", but graph load routine accepts any letter for
|
119
|
+
separator but not a number.
|
120
|
+
If the graph has both edges and arcs, write them in two lines separately,
|
121
|
+
so a node then uses two lines, and #nodes = #lines/2.
|
122
|
+
|
123
|
+
== Notifications to make input file ==
|
124
|
+
Notice that if 0th line has node 2, and the 2nd line has 0, then there
|
125
|
+
will be multiple edge (0,2) and (2,0).
|
126
|
+
The read routine does not make error with multiple edges, it is allowed.
|
127
|
+
|
128
|
+
The ID of nodes begin from 0. After reading graph, node_num is set to
|
129
|
+
node_end.
|
130
|
+
|
131
|
+
Input file example, without weights, E={(0,1),(0,2),(1,1),(1,3),(2,3)}
|
132
|
+
===========
|
133
|
+
1,2
|
134
|
+
1 3
|
135
|
+
3
|
136
|
+
|
137
|
+
[EOF]
|
138
|
+
=========
|
139
|
+
Nodes are 0,1, and 2, both edges and arcs exist, with node/edge/arc weights)
|
140
|
+
5000,1,30
|
141
|
+
0,50,1,20,
|
142
|
+
100,1,3
|
143
|
+
2,20
|
144
|
+
200
|
145
|
+
|
146
|
+
[EOF]
|
147
|
+
=======
|
148
|
+
where node weights are 5000, 100, 200, and edges and their weights are
|
149
|
+
(0,1),30, (1,1),3
|
150
|
+
arcs and their weights are (0,0),50, (0,1), 20, (1,2), 20
|
151
|
+
|
152
|
+
In the case of bipartite graph, write the adjacent-node lists only for
|
153
|
+
the node in node set one.
|
154
|
+
|
155
|
+
|
156
|
+
*/
|
157
|
+
|
158
|
+
|
159
|
+
/*************************************************************************/
|
160
|
+
|
161
|
+
|
162
|
+
#endif
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
@@ -0,0 +1,832 @@
|
|
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_c_
|
14
|
+
#define _stdlib2_c_
|
15
|
+
|
16
|
+
#include"stdlib2.h"
|
17
|
+
#ifdef MTWISTER
|
18
|
+
#include"dSFMT.c"
|
19
|
+
#endif
|
20
|
+
|
21
|
+
size_t common_size_t;
|
22
|
+
INT common_INT, common_INT2;
|
23
|
+
char *common_charp, *common_pnt;
|
24
|
+
FILE *common_FILE;
|
25
|
+
FILE2 common_FILE2;
|
26
|
+
PERM common_PERM;
|
27
|
+
|
28
|
+
char *ERROR_MES = NULL;
|
29
|
+
int print_time_flag=0;
|
30
|
+
PARAMS internal_params;
|
31
|
+
#ifdef MULTI_CORE
|
32
|
+
int SPIN_LOCK_dummy;
|
33
|
+
#endif
|
34
|
+
FILE2 INIT_FILE2 = {TYPE_FILE2,NULL,NULL,NULL,NULL};
|
35
|
+
VEC INIT_VEC = {TYPE_VEC,NULL,0,0};
|
36
|
+
FILE_COUNT INIT_FILE_COUNT = {0,0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,0,0,NULL,NULL,0,0,NULL,NULL};
|
37
|
+
|
38
|
+
QSORT_TYPE (int, int)
|
39
|
+
QSORT_TYPE (uint, unsigned int)
|
40
|
+
QSORT_TYPE (double, double)
|
41
|
+
QSORT_TYPE (char, char)
|
42
|
+
QSORT_TYPE (uchar, unsigned char)
|
43
|
+
QSORT_TYPE (short, short)
|
44
|
+
QSORT_TYPE (ushort, unsigned short)
|
45
|
+
QSORT_TYPE (WEIGHT, WEIGHT)
|
46
|
+
QSORT_TYPE (LONG, LONG)
|
47
|
+
QSORT_TYPE (VEC_ID, VEC_ID)
|
48
|
+
QSORT_TYPE (VEC_VAL, VEC_VAL)
|
49
|
+
QSORT_TYPE (VEC_VAL2, VEC_VAL2)
|
50
|
+
QSORT_TYPE (FILE_COUNT_INT, FILE_COUNT_INT)
|
51
|
+
|
52
|
+
/* bitmasks, used for bit operations */
|
53
|
+
int BITMASK_UPPER1[32] = { 0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
|
54
|
+
0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
|
55
|
+
0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
|
56
|
+
0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000,
|
57
|
+
0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000,
|
58
|
+
0xfff00000, 0xffe00000, 0xffc00000, 0xff800000,
|
59
|
+
0xff000000, 0xfe000000, 0xfc000000, 0xf8000000,
|
60
|
+
0xf0000000, 0xe0000000, 0xc0000000, 0x80000000 };
|
61
|
+
int BITMASK_UPPER1_[32] = { 0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0,
|
62
|
+
0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00,
|
63
|
+
0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000,
|
64
|
+
0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000,
|
65
|
+
0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000,
|
66
|
+
0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
|
67
|
+
0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000,
|
68
|
+
0xe0000000, 0xc0000000, 0x80000000, 0x00000000 };
|
69
|
+
|
70
|
+
int BITMASK_LOWER1[32] = { 0x00000000, 0x00000001, 0x00000003, 0x00000007,
|
71
|
+
0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
|
72
|
+
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
|
73
|
+
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
|
74
|
+
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
|
75
|
+
0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
|
76
|
+
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
|
77
|
+
0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff };
|
78
|
+
int BITMASK_LOWER1_[32] = { 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
|
79
|
+
0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
|
80
|
+
0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
|
81
|
+
0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
|
82
|
+
0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
|
83
|
+
0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
|
84
|
+
0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
|
85
|
+
0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff };
|
86
|
+
|
87
|
+
int BITMASK_1[32] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008,
|
88
|
+
0x00000010, 0x00000020, 0x00000040, 0x00000080,
|
89
|
+
0x00000100, 0x00000200, 0x00000400, 0x00000800,
|
90
|
+
0x00001000, 0x00002000, 0x00004000, 0x00008000,
|
91
|
+
0x00010000, 0x00020000, 0x00040000, 0x00080000,
|
92
|
+
0x00100000, 0x00200000, 0x00400000, 0x00800000,
|
93
|
+
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
94
|
+
0x10000000, 0x20000000, 0x40000000, 0x80000000 };
|
95
|
+
int BITMASK_31[32] = { 0xfffffffe, 0xfffffffd, 0xfffffffb, 0xfffffff7,
|
96
|
+
0xffffffef, 0xffffffdf, 0xffffffbf, 0xffffff7f,
|
97
|
+
0xfffffeff, 0xfffffdff, 0xfffffbff, 0xfffff7ff,
|
98
|
+
0xffffefff, 0xffffdfff, 0xffffbfff, 0xffff7fff,
|
99
|
+
0xfffeffff, 0xfffdffff, 0xfffbffff, 0xfff7ffff,
|
100
|
+
0xffefffff, 0xffdfffff, 0xffbfffff, 0xff7fffff,
|
101
|
+
0xfeffffff, 0xfdffffff, 0xfbffffff, 0xf7ffffff,
|
102
|
+
0xefffffff, 0xdfffffff, 0xbfffffff, 0x7fffffff };
|
103
|
+
|
104
|
+
int BITMASK_16[8] = { 0x0000000f, 0x000000f0, 0x00000f00, 0x0000f000,
|
105
|
+
0x000f0000, 0x00f00000, 0x0f000000, 0xf0000000 };
|
106
|
+
int BITMASK_UPPER16[8] = { 0xffffffff, 0xfffffff0, 0xffffff00, 0xfffff000,
|
107
|
+
0xffff0000, 0xfff00000, 0xff000000, 0xf0000000 };
|
108
|
+
int BITMASK_LOWER16[8] = { 0x0000000f, 0x000000ff, 0x00000fff, 0x0000ffff,
|
109
|
+
0x000fffff, 0x00ffffff, 0x0fffffff, 0xffffffff };
|
110
|
+
int BITMASK_FACT16[8] = { 0x1, 0x10, 0x100, 0x1000,
|
111
|
+
0x10000, 0x100000, 0x1000000,0x10000000 };
|
112
|
+
|
113
|
+
/* free many pointers */
|
114
|
+
void mfree_(void *x, ...){
|
115
|
+
va_list argp;
|
116
|
+
void *a;
|
117
|
+
va_start (argp, x);
|
118
|
+
while((a = va_arg(argp, void *)) != (void*)1){ free (a); }
|
119
|
+
va_end (argp);
|
120
|
+
}
|
121
|
+
|
122
|
+
/* compute the minimum prime no less than n */
|
123
|
+
#define MINPRIME_END 6000
|
124
|
+
LONG min_prime (LONG n){
|
125
|
+
LONG i, j=30, k;
|
126
|
+
char f[MINPRIME_END];
|
127
|
+
while(1) {
|
128
|
+
FLOOP (i, 0, j) f[i]=0;
|
129
|
+
for ( i=3 ; i*i < n+j ; i+=2 )
|
130
|
+
for ( k=((n+i-1)/i)*i ; k<i+j ; k+=i ) f[(k-n)/2] = 1;
|
131
|
+
FLOOP (i, 0, j) if ( f[i] == 0 ) return (n+ i*2+1);
|
132
|
+
j *= 2;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
/* decompose the string by separator, and set v[i] to each resulted string.
|
137
|
+
consecutive separators are regarded as one separator. */
|
138
|
+
/* string s has to have end mark 0 at the end */
|
139
|
+
/* original string s will be written, so that each separator will be end mark 0 */
|
140
|
+
/* at most [num] strings will be generated */
|
141
|
+
int string_decompose ( char **v, char *s, char sep, int max){
|
142
|
+
int i=0;
|
143
|
+
char *ss = s;
|
144
|
+
do {
|
145
|
+
while (*ss == sep) ss++;
|
146
|
+
if ( *ss == 0 ) break;
|
147
|
+
v[i++] = ss;
|
148
|
+
while (*ss != sep){
|
149
|
+
if ( *ss == 0 ) break;
|
150
|
+
ss++;
|
151
|
+
}
|
152
|
+
if ( *ss == 0 ) break;
|
153
|
+
*ss = 0;
|
154
|
+
ss++;
|
155
|
+
} while ( i<max);
|
156
|
+
return (i);
|
157
|
+
}
|
158
|
+
|
159
|
+
unsigned long xor128(){
|
160
|
+
static unsigned long x=123456789,y=362436069,z=521288629,w=88675123;
|
161
|
+
unsigned long t;
|
162
|
+
t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) );
|
163
|
+
}
|
164
|
+
|
165
|
+
/***********************************************************************/
|
166
|
+
/***********************************************************************/
|
167
|
+
#ifdef USE_MATH
|
168
|
+
#define NORMAL_RAND_BASE 2147483648LL
|
169
|
+
|
170
|
+
/* make two random numbers under normal distribution N(0,1) */
|
171
|
+
void rand_mk_2normal (double *a, double *b){
|
172
|
+
double r1, r2;
|
173
|
+
do {
|
174
|
+
r1 = RAND1;
|
175
|
+
} while (r1==0);
|
176
|
+
r2 = RAND1;
|
177
|
+
r1 = sqrt(-log(r1)*2);
|
178
|
+
r2 *= 2*PI;
|
179
|
+
*a = r1*sin(r2);
|
180
|
+
*b = r1*cos(r2);
|
181
|
+
}
|
182
|
+
|
183
|
+
/* make a random point on a supersphere of d-dim., and set to double array already allocated */
|
184
|
+
void rand_d_gaussian (double *p, int d){
|
185
|
+
int i;
|
186
|
+
double a, b;
|
187
|
+
for (i=0 ; i<d ; i+=2){
|
188
|
+
rand_mk_2normal ( &a, &b);
|
189
|
+
p[i] = a;
|
190
|
+
if ( i+1 < d ) p[i+1] = b;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
void rand_sphere (double *p, int d){
|
194
|
+
rand_d_gaussian (p, d);
|
195
|
+
ARY_NORMALIZE (p, d);
|
196
|
+
}
|
197
|
+
#endif
|
198
|
+
|
199
|
+
/******************** file I/O routines ********************************/
|
200
|
+
|
201
|
+
int FILE_err; /* signals 0: for normal termination
|
202
|
+
1: read a number, then encountered a newline,
|
203
|
+
2: read a number, then encountered the end-of-file
|
204
|
+
5: read no number, and encountered a newline
|
205
|
+
6: read no number, and encountered the end-of-file */
|
206
|
+
|
207
|
+
|
208
|
+
void FILE2_flush (FILE2 *fp){
|
209
|
+
if ( fp->buf > fp->buf_org ){
|
210
|
+
fwrite ( fp->buf_org, fp->buf-fp->buf_org, 1, fp->fp);
|
211
|
+
fp->buf = fp->buf_org;
|
212
|
+
}
|
213
|
+
}
|
214
|
+
void FILE2_close (FILE2 *fp){
|
215
|
+
fclose2 (fp->fp);
|
216
|
+
free2 (fp->buf_org);
|
217
|
+
}
|
218
|
+
void FILE2_closew (FILE2 *fp){
|
219
|
+
FILE2_flush (fp);
|
220
|
+
fclose2 (fp->fp);
|
221
|
+
free2 (fp->buf_org);
|
222
|
+
}
|
223
|
+
void FILE2_reset (FILE2 *fp){
|
224
|
+
fp->buf = fp->buf_org;
|
225
|
+
fp->buf_end = fp->buf_org-1;
|
226
|
+
fseek (fp->fp, 0, SEEK_SET);
|
227
|
+
}
|
228
|
+
/* fast file routine, getc, putc, puts, */
|
229
|
+
int FILE2_getc (FILE2 *fp){
|
230
|
+
int c;
|
231
|
+
if ( fp->buf >= fp->buf_end ){
|
232
|
+
if ( (fp->buf_end < fp->buf_org+FILE2_BUFSIZ) && (fp->buf_end>=fp->buf_org) ) return (-1);
|
233
|
+
fp->buf = fp->buf_org;
|
234
|
+
fp->buf_end = fp->buf_org + fread (fp->buf, 1, FILE2_BUFSIZ, fp->fp);
|
235
|
+
return (FILE2_getc (fp));
|
236
|
+
}
|
237
|
+
c = (unsigned char)(*(fp->buf));
|
238
|
+
fp->buf++;
|
239
|
+
return (c);
|
240
|
+
}
|
241
|
+
void FILE2_puts (FILE2 *fp, char *s){
|
242
|
+
while ( *s != 0 ){
|
243
|
+
*(fp->buf) = *s;
|
244
|
+
s++;
|
245
|
+
fp->buf++;
|
246
|
+
}
|
247
|
+
}
|
248
|
+
void FILE2_putc (FILE2 *fp, char c){
|
249
|
+
*(fp->buf) = c;
|
250
|
+
fp->buf++;
|
251
|
+
}
|
252
|
+
/* fast file routine, print number, c is the char to be printed preceding to the number
|
253
|
+
if c==0, nothing will be printed preceding the number
|
254
|
+
if len<0 then the #digits following '.' does not change (filed by '0') */
|
255
|
+
void FILE2_print_int (FILE2 *fp, LONG n, char c){
|
256
|
+
LONG nn = n;
|
257
|
+
char *s;
|
258
|
+
if ( c ) FILE2_putc ( fp, c);
|
259
|
+
if ( n == 0 ){ *(fp->buf) = '0'; fp->buf++; return; }
|
260
|
+
if ( n < 0 ){ *(fp->buf) = '-'; fp->buf++; n = -n; }
|
261
|
+
while ( nn>0 ){ nn /= 10; fp->buf++; }
|
262
|
+
s = fp->buf-1;
|
263
|
+
*(fp->buf) = 0;
|
264
|
+
while ( n>0 ){ *s = '0'+(char)(n%10); s--; n/=10; }
|
265
|
+
}
|
266
|
+
/******/
|
267
|
+
void FILE2_print_real (FILE2 *fp, double n, int len, char c){
|
268
|
+
int i=0, flag=1;
|
269
|
+
double j=1;
|
270
|
+
char *back;
|
271
|
+
|
272
|
+
if ( c ) FILE2_putc (fp, c);
|
273
|
+
if ( n<0 ){ FILE2_putc (fp, '-'); n *= -1; }
|
274
|
+
while ( n >= j ) j*=10;
|
275
|
+
if ( j==1 ){ *(fp->buf) = '0'; fp->buf++; }
|
276
|
+
else while ( j>1 ){
|
277
|
+
j /= 10;
|
278
|
+
i = (int)(n/j);
|
279
|
+
*(fp->buf) = '0'+i;
|
280
|
+
n -= j*i;
|
281
|
+
fp->buf++;
|
282
|
+
}
|
283
|
+
*(fp->buf) = '.'; back = fp->buf;
|
284
|
+
fp->buf++;
|
285
|
+
if ( len<0 ){ len = -len; flag = 0; }
|
286
|
+
for ( ; len>0 ; len--){
|
287
|
+
n *= 10.0;
|
288
|
+
i = (int)n;
|
289
|
+
*(fp->buf) = '0'+i;
|
290
|
+
n -= i;
|
291
|
+
fp->buf++;
|
292
|
+
if ( i>0 ) back = fp->buf;
|
293
|
+
}
|
294
|
+
if ( flag ) fp->buf = back;
|
295
|
+
}
|
296
|
+
/******/
|
297
|
+
void FILE2_print_WEIGHT (FILE2 *fp, WEIGHT w, int len, char c){
|
298
|
+
#ifdef WEIGHT_DOUBLE
|
299
|
+
FILE2_print_real(fp, w, len, c);
|
300
|
+
#else
|
301
|
+
FILE2_print_int(fp, w, c);
|
302
|
+
#endif
|
303
|
+
}
|
304
|
+
|
305
|
+
/* Read an integer/a double from the file and return it,
|
306
|
+
with read through the non-numeric letters.
|
307
|
+
If it reaches to the end-of-file, then set FILE_err=2, if it reads a
|
308
|
+
newline, then set FILE_err=1.
|
309
|
+
If read either the end-of-file or newline before reading an integer,
|
310
|
+
return 5, and 6 */
|
311
|
+
FILE_LONG FILE2_read_int (FILE2 *fp){
|
312
|
+
FILE_LONG item;
|
313
|
+
int flag =1;
|
314
|
+
int ch;
|
315
|
+
FILE_err = 0;
|
316
|
+
do {
|
317
|
+
ch = FILE2_getc(fp);
|
318
|
+
if ( ch == '\n' ){ FILE_err = 5; return (-INTHUGE); }
|
319
|
+
if ( ch < 0 ){ FILE_err = 6; return (-INTHUGE); }
|
320
|
+
if ( ch=='-' ) flag = -1;
|
321
|
+
} while ( ch<'0' || ch>'9' );
|
322
|
+
for ( item=(int)(ch-'0') ; 1 ; item=item*10 +(int)(ch-'0') ){
|
323
|
+
ch = FILE2_getc(fp);
|
324
|
+
if ( ch == '\n' ){ FILE_err = 1; return (flag*item); }
|
325
|
+
if ( ch < 0 ){ FILE_err = 2; return (flag*item); }
|
326
|
+
if ( (ch < '0') || (ch > '9')) return (flag*item);
|
327
|
+
}
|
328
|
+
}
|
329
|
+
double FILE2_read_double (FILE2 *fp){
|
330
|
+
double item, geta=1;
|
331
|
+
int sign=1, ch;
|
332
|
+
FILE_err = 0;
|
333
|
+
while (1){
|
334
|
+
ch = FILE2_getc(fp);
|
335
|
+
if ( ch < 0 ){ FILE_err = 6; return (-DOUBLEHUGE); }
|
336
|
+
if ( ch == '\n' ){ FILE_err = 5; return (-DOUBLEHUGE); }
|
337
|
+
if ( ch=='-' ) sign *= -1;
|
338
|
+
else if ( ch=='.' ) geta = 0.1;
|
339
|
+
else if ( ch>='0' && ch<='9' ) break;
|
340
|
+
else { sign = 1; geta = 1; }
|
341
|
+
}
|
342
|
+
|
343
|
+
item = geta * (ch-'0');
|
344
|
+
if ( geta < 1.0 ) geta *= .1;
|
345
|
+
while (1){
|
346
|
+
ch = FILE2_getc(fp);
|
347
|
+
if ( ch == '\n' ){ FILE_err = 1; return (item*sign); }
|
348
|
+
if ( ch<0 ){ FILE_err = 2; return (item*sign); }
|
349
|
+
if ( ch == '.' ) geta = .1;
|
350
|
+
else if ( (ch < '0') || (ch > '9')) return (item*sign);
|
351
|
+
else if ( geta < 1.0 ){
|
352
|
+
item += geta*(ch-'0');
|
353
|
+
geta *= 0.1;
|
354
|
+
} else item = item*10 + (ch-'0');
|
355
|
+
}
|
356
|
+
}
|
357
|
+
|
358
|
+
/* read a WEIGHT from file */
|
359
|
+
WEIGHT FILE2_read_WEIGHT (FILE2 *fp){
|
360
|
+
#ifdef WEIGHT_DOUBLE
|
361
|
+
return (FILE2_read_double(fp));
|
362
|
+
#else
|
363
|
+
return ((WEIGHT)FILE2_read_int(fp));
|
364
|
+
#endif
|
365
|
+
}
|
366
|
+
|
367
|
+
/* read through the file until newline or EOF */
|
368
|
+
void FILE2_read_until_newline (FILE2 *fp){
|
369
|
+
int ch;
|
370
|
+
if (FILE_err & 3) return;
|
371
|
+
while (1){
|
372
|
+
ch = FILE2_getc(fp);
|
373
|
+
if ( ch == '\n' ){ FILE_err = 5; return; }
|
374
|
+
if ( ch < 0 ){ FILE_err = 6; return; }
|
375
|
+
}
|
376
|
+
}
|
377
|
+
|
378
|
+
void FILE2_printf (FILE2 *fp, char *mes, ...){
|
379
|
+
va_list argp;
|
380
|
+
va_start (argp, mes);
|
381
|
+
sprintf (fp->buf, mes, argp);
|
382
|
+
va_end (argp);
|
383
|
+
}
|
384
|
+
|
385
|
+
/* print a real number in a good style */
|
386
|
+
void fprint_real (FILE *fp, double f){
|
387
|
+
char s[200];
|
388
|
+
size_t i;
|
389
|
+
i = sprintf (s, "%f", f);
|
390
|
+
while ( s[i-1] == '0' ) i--;
|
391
|
+
if ( s[i-1] == '.' ) i--;
|
392
|
+
s[i] = 0;
|
393
|
+
fprintf (fp, s);
|
394
|
+
}
|
395
|
+
void print_real (double f){
|
396
|
+
fprint_real (stdout, f);
|
397
|
+
}
|
398
|
+
|
399
|
+
void fprint_WEIGHT (FILE *fp, WEIGHT f){
|
400
|
+
#ifdef WEIGHT_DOUBLE
|
401
|
+
fprint_real (fp, f);
|
402
|
+
#else
|
403
|
+
fprintf (fp, "%d", f);
|
404
|
+
#endif
|
405
|
+
}
|
406
|
+
void print_WEIGHT (WEIGHT f){
|
407
|
+
fprint_WEIGHT (stdout, f);
|
408
|
+
}
|
409
|
+
|
410
|
+
/* count the clms, rows, items, each row size, each column size */
|
411
|
+
/* file types can be, array list and element list*/
|
412
|
+
/* support transpose */
|
413
|
+
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){
|
414
|
+
FILE_COUNT_INT k=0, j, x, y, t=0;
|
415
|
+
int fr = flag&FILE_COUNT_ROWT, fc = flag&FILE_COUNT_CLMT;
|
416
|
+
int fe = flag&LOAD_ELE, ft = flag&LOAD_TPOSE;
|
417
|
+
FILE_COUNT C = INIT_FILE_COUNT;
|
418
|
+
C.flag = flag;
|
419
|
+
|
420
|
+
FLOOP (j, 0, skip_rows) FILE2_read_until_newline (fp);
|
421
|
+
if ( flag & (FILE_COUNT_NUM+FILE_COUNT_GRAPHNUM) ){
|
422
|
+
C.clms = (FILE_COUNT_INT)FILE2_read_int (fp);
|
423
|
+
C.rows = (flag & FILE_COUNT_NUM)? (FILE_COUNT_INT)FILE2_read_int (fp): C.clms;
|
424
|
+
C.eles = (FILE_COUNT_INT)FILE2_read_int (fp);
|
425
|
+
if ( !(flag & (FILE_COUNT_ROWT + FILE_COUNT_CLMT)) ) return (C);
|
426
|
+
FILE2_read_until_newline (fp);
|
427
|
+
}
|
428
|
+
|
429
|
+
do {
|
430
|
+
if ( fe ){
|
431
|
+
FLOOP (j, 0, skip_clms){ FILE2_read_double (fp); if ( FILE_err&3 ) goto ROW_END; }
|
432
|
+
x = (FILE_COUNT_INT)FILE2_read_int (fp); if ( FILE_err&3 ) goto ROW_END;
|
433
|
+
y = (FILE_COUNT_INT)FILE2_read_int (fp); if ( FILE_err&4 ) goto ROW_END;
|
434
|
+
FILE2_read_until_newline (fp);
|
435
|
+
} else {
|
436
|
+
if ( k==0 ) FLOOP (j, 0, skip_clms){ FILE2_read_double (fp); if (FILE_err&3) goto ROW_END; }
|
437
|
+
x = t;
|
438
|
+
y = (FILE_COUNT_INT)FILE2_read_int (fp); if (FILE_err&4 ) goto ROW_END;
|
439
|
+
FLOOP (j, 0, int_clms){ FILE2_read_double (fp); if (FILE_err&3 ) break; }
|
440
|
+
k++;
|
441
|
+
}
|
442
|
+
|
443
|
+
if ( ft ) SWAP_FILE_COUNT_INT (x, y);
|
444
|
+
if ( y >= C.clms ){
|
445
|
+
C.clms = y+1;
|
446
|
+
if ( fc ) reallocx (C.clmt, C.clm_end, C.clms, 0, "file_count: clmt", goto END);
|
447
|
+
}
|
448
|
+
if ( x >= C.rows ){
|
449
|
+
C.rows = x+1;
|
450
|
+
if ( fr ) reallocx (C.rowt, C.row_end, C.rows, 0, "file_count: rowt", goto END);
|
451
|
+
}
|
452
|
+
if ( x < C.clm_btm || C.eles == 0 ) C.clm_btm = x;
|
453
|
+
if ( y < C.row_btm || C.eles == 0 ) C.row_btm = y;
|
454
|
+
if ( fc ) C.clmt[y]++;
|
455
|
+
if ( fr ) C.rowt[x]++;
|
456
|
+
C.eles++;
|
457
|
+
|
458
|
+
ROW_END:;
|
459
|
+
if ( !fe && (FILE_err&1) ){
|
460
|
+
t++; C.rows = t;
|
461
|
+
ENMAX (C.clm_max, k);
|
462
|
+
ENMAX (C.clm_min, k);
|
463
|
+
FLOOP (j, 0, int_rows) FILE2_read_until_newline (fp);
|
464
|
+
if ( row_limit>0 && t>=row_limit ) break;
|
465
|
+
} else if ( row_limit>0 && C.eles>=row_limit ) break;
|
466
|
+
|
467
|
+
} while ( (FILE_err&2)==0 );
|
468
|
+
END:;
|
469
|
+
if ( C.rowt ){
|
470
|
+
ARY_MAX (C.row_max, k, C.rowt, 0, C.rows);
|
471
|
+
ARY_MIN (C.row_min, k, C.rowt, 0, C.rows);
|
472
|
+
}
|
473
|
+
if ( fe && C.clmt ){
|
474
|
+
ARY_MAX (C.clm_max, k, C.clmt, 0, C.clms);
|
475
|
+
ARY_MIN (C.clm_min, k, C.clmt, 0, C.clms);
|
476
|
+
}
|
477
|
+
if ( ERROR_MES ) mfree (C.rowt, C.clmt);
|
478
|
+
return (C);
|
479
|
+
}
|
480
|
+
|
481
|
+
|
482
|
+
/* SLIST:very simple one-sided list */
|
483
|
+
void SLIST_init (int *l, int num, int siz){
|
484
|
+
malloc2 (l, num+siz, "SLIST_init: l", EXIT);
|
485
|
+
ARY_FILL (l, num, num+siz, -1);
|
486
|
+
}
|
487
|
+
void SLIST_end (int *l){ free (l); }
|
488
|
+
#define SLIST_INS(l,m,e) (l[e]=l[m],l[m]=e);
|
489
|
+
|
490
|
+
/* qsort according to "->t" */
|
491
|
+
int qsort_cmp_VECt (const void *x, const void *y){
|
492
|
+
if ( ((VEC *)x)->t < ((VEC *)y)->t ) return (-1);
|
493
|
+
else return ( ((VEC *)x)->t > ((VEC *)y)->t);
|
494
|
+
}
|
495
|
+
int qsort_cmp__VECt (const void *x, const void *y){
|
496
|
+
if ( ((VEC *)x)->t > ((VEC *)y)->t ) return (-1);
|
497
|
+
else return ( ((VEC *)x)->t < ((VEC *)y)->t);
|
498
|
+
}
|
499
|
+
void qsort_VECt (VEC *v, size_t siz, int unit){
|
500
|
+
if ( unit == 1 || unit==-1 ) unit *= sizeof (VEC);
|
501
|
+
if ( unit < 0 ) qsort (v, siz, -unit, qsort_cmp__VECt);
|
502
|
+
else qsort (v, siz, unit, qsort_cmp_VECt);
|
503
|
+
}
|
504
|
+
|
505
|
+
int qqsort_cmp_VECt (const void *x, const void *y){
|
506
|
+
if ( QQSORT_ELEt(VEC,x) < QQSORT_ELEt(VEC,y) ) return (-1);
|
507
|
+
else return ( QQSORT_ELEt(VEC,x) > QQSORT_ELEt(VEC,y) );
|
508
|
+
}
|
509
|
+
int qqsort_cmp__VECt (const void *x, const void *y){
|
510
|
+
if ( QQSORT_ELEt(VEC,x) > QQSORT_ELEt(VEC,y) ) return (-1);
|
511
|
+
else return ( QQSORT_ELEt(VEC,x) < QQSORT_ELEt(VEC,y) );
|
512
|
+
}
|
513
|
+
void qsort_perm__VECt (VEC *v, size_t siz, PERM *perm, int unit){
|
514
|
+
if ( unit == 1 || unit==-1 ) unit *= sizeof(VEC);
|
515
|
+
common_int=MAX(unit,-unit); common_charp=(char *)v;
|
516
|
+
if (unit<0) qsort (perm, siz, sizeof(PERM), qqsort_cmp__VECt);
|
517
|
+
else qsort (perm, siz, sizeof(PERM), qqsort_cmp_VECt);
|
518
|
+
}
|
519
|
+
|
520
|
+
PERM *qsort_perm_VECt (VEC *v, size_t siz, int unit){
|
521
|
+
PERM *perm;
|
522
|
+
malloc2 (perm, siz, "qsort_perm_VECt: perm", EXIT0);
|
523
|
+
ARY_INIT_PERM(perm,siz);
|
524
|
+
qsort_perm__VECt (v, siz, perm, unit);
|
525
|
+
return(perm);
|
526
|
+
}
|
527
|
+
|
528
|
+
#ifdef STDLIB2_RADIX_SORT // radix sort with 1M byte static memory
|
529
|
+
|
530
|
+
#define RADIX_SORT_BUCKET_SIZ 2048
|
531
|
+
/* sort of integer array with combination of radix sort and quick sort */
|
532
|
+
/* flag&1: sort in decreasing order */
|
533
|
+
|
534
|
+
// sort by lower bits
|
535
|
+
void intarray_sort_iter (unsigned int *a, size_t siz, int unit){
|
536
|
+
static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1;
|
537
|
+
size_t k, x;
|
538
|
+
int i, ii, j, flag=1;
|
539
|
+
static char bbuf[1000], bbuf2[1000];
|
540
|
+
char *aa, *aaa, *aa_end, *buf, *buf2;
|
541
|
+
|
542
|
+
if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; }
|
543
|
+
if ( unit <0 ){ unit = -unit; flag = -1; }
|
544
|
+
if ( unit == 1 ) unit = sizeof (int);
|
545
|
+
buf = bbuf; buf2 = bbuf2;
|
546
|
+
if ( init_flag == 1 ){
|
547
|
+
init_flag = 0;
|
548
|
+
ARY_FILL (cnt, 0, RADIX_SORT_BUCKET_SIZ, 0);
|
549
|
+
}
|
550
|
+
// count elements of each number
|
551
|
+
for ( aa=(char*)a,aa_end=aa+siz*unit ; aa<aa_end ; aa+=unit )
|
552
|
+
cnt[(*((unsigned int *)aa)) & (RADIX_SORT_BUCKET_SIZ-1)]++; // difference!!
|
553
|
+
|
554
|
+
// sum up the numbers in increasing order
|
555
|
+
k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
556
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
557
|
+
cnt2[ii] = k;
|
558
|
+
k += cnt[ii];
|
559
|
+
cnt[ii] = k;
|
560
|
+
}
|
561
|
+
|
562
|
+
FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
563
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
564
|
+
FLOOP (x, cnt2[ii], cnt[ii]){
|
565
|
+
aa = ((char*)a) + x*unit;
|
566
|
+
memcpy ( buf, aa, unit);
|
567
|
+
while (1){
|
568
|
+
j = *((unsigned int *)buf) & (RADIX_SORT_BUCKET_SIZ-1); // difference!!
|
569
|
+
if ( j == ii ) break;
|
570
|
+
aaa = ((char*)a) + cnt2[j]*unit;
|
571
|
+
// printf ("pos[xx]=%d, cnt %d, cnt+1 %d\n", pos[xx], S->let_cnt[dep][cc], S->let_cnt[dep+1][cc]);
|
572
|
+
memcpy ( buf2, aaa, unit);
|
573
|
+
memcpy ( aaa, buf, unit);
|
574
|
+
SWAP_PNT ( buf, buf2);
|
575
|
+
cnt2[j]++;
|
576
|
+
}
|
577
|
+
memcpy ( aa, buf, unit);
|
578
|
+
}
|
579
|
+
cnt[i]=0; // difference!!
|
580
|
+
}
|
581
|
+
}
|
582
|
+
// sort by middle bits
|
583
|
+
void intarray_sort_iter_ ( unsigned int *a, size_t siz, int unit){
|
584
|
+
static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1;
|
585
|
+
int i, ii, j, flag=1;
|
586
|
+
size_t k, x;
|
587
|
+
static char bbuf[1000], bbuf2[1000];
|
588
|
+
char *aa, *aaa, *aa_end, *buf, *buf2;
|
589
|
+
|
590
|
+
if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; }
|
591
|
+
buf = bbuf; buf2 = bbuf2;
|
592
|
+
if ( unit <0 ){ unit = -unit; flag = -1; }
|
593
|
+
if ( unit == 1 ) unit = sizeof (int);
|
594
|
+
if ( init_flag == 1 ){
|
595
|
+
init_flag = 0;
|
596
|
+
ARY_FILL ( cnt, 0, RADIX_SORT_BUCKET_SIZ, 0);
|
597
|
+
}
|
598
|
+
// count elements of each number
|
599
|
+
for ( aa=(char*)a,aa_end=aa+siz*unit ; aa<aa_end ; aa+=unit )
|
600
|
+
cnt[((*((unsigned int *)aa))/RADIX_SORT_BUCKET_SIZ) & (RADIX_SORT_BUCKET_SIZ-1)]++; // difference!!
|
601
|
+
|
602
|
+
// sum up the numbers in increasing order
|
603
|
+
k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
604
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
605
|
+
cnt2[ii] = k;
|
606
|
+
k += cnt[ii];
|
607
|
+
cnt[ii] = k;
|
608
|
+
}
|
609
|
+
|
610
|
+
FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
611
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
612
|
+
FLOOP(x, cnt2[ii], cnt[ii]){
|
613
|
+
aa = ((char*)a) + x*unit;
|
614
|
+
memcpy ( buf, aa, unit);
|
615
|
+
while (1){
|
616
|
+
j = (*((unsigned int *)buf)/RADIX_SORT_BUCKET_SIZ) & (RADIX_SORT_BUCKET_SIZ-1); // difference!!
|
617
|
+
if ( j == ii ) break;
|
618
|
+
aaa = ((char*)a) + cnt2[j]*unit;
|
619
|
+
// printf ("pos[xx]=%d, cnt %d, cnt+1 %d\n", pos[xx], S->let_cnt[dep][cc], S->let_cnt[dep+1][cc]);
|
620
|
+
memcpy (buf2, aaa, unit);
|
621
|
+
memcpy (aaa, buf, unit);
|
622
|
+
SWAP_PNT (buf, buf2);
|
623
|
+
cnt2[j]++;
|
624
|
+
}
|
625
|
+
memcpy (aa, buf, unit);
|
626
|
+
}
|
627
|
+
}
|
628
|
+
k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
629
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
630
|
+
intarray_sort_iter ( (unsigned int*)(((char*)a)+unit*k), cnt[ii]-k, unit*flag);
|
631
|
+
k = cnt[ii];
|
632
|
+
cnt[i]=0;
|
633
|
+
}
|
634
|
+
}
|
635
|
+
|
636
|
+
// sort by upper bits
|
637
|
+
void intarray_sort ( unsigned int *a, size_t siz, int unit){
|
638
|
+
static size_t cnt[RADIX_SORT_BUCKET_SIZ], cnt2[RADIX_SORT_BUCKET_SIZ], init_flag = 1;
|
639
|
+
int i, ii, j, flag=1;
|
640
|
+
size_t k, x;
|
641
|
+
static char bbuf[1000], bbuf2[1000];
|
642
|
+
char *aa, *aaa, *aa_end, *buf, *buf2;
|
643
|
+
|
644
|
+
if ( siz<1000 ){ qsort_uint ( a, siz, unit); return; }
|
645
|
+
if ( unit <0 ){ unit = -unit; flag = -1; }
|
646
|
+
if ( unit == 1 ) unit = sizeof (int);
|
647
|
+
buf = bbuf; buf2 = bbuf2;
|
648
|
+
if ( init_flag == 1){
|
649
|
+
init_flag = 0;
|
650
|
+
ARY_FILL (cnt, 0, RADIX_SORT_BUCKET_SIZ, 0);
|
651
|
+
}
|
652
|
+
// count elements of each number
|
653
|
+
for ( aa=(char*)a,aa_end=aa+siz*unit ; aa<aa_end ; aa+=unit )
|
654
|
+
cnt[(*((unsigned int *)aa)) / RADIX_SORT_BUCKET_SIZ / RADIX_SORT_BUCKET_SIZ]++; // difference!!
|
655
|
+
|
656
|
+
// sum up the numbers in increasing order
|
657
|
+
k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
658
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
659
|
+
cnt2[ii] = k;
|
660
|
+
k += cnt[ii];
|
661
|
+
cnt[ii] = k;
|
662
|
+
}
|
663
|
+
|
664
|
+
FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
665
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
666
|
+
FLOOP (x, cnt2[ii], cnt[ii]){
|
667
|
+
aa = ((char*)a) + x*unit;
|
668
|
+
memcpy ( buf, aa, unit);
|
669
|
+
while (1){
|
670
|
+
j = *((unsigned int *)buf) / RADIX_SORT_BUCKET_SIZ / RADIX_SORT_BUCKET_SIZ; // difference!!
|
671
|
+
if ( j == ii ) break;
|
672
|
+
aaa = ((char*)a) + cnt2[j]*unit;
|
673
|
+
// printf ("pos[xx]=%d, cnt %d, cnt+1 %d\n", pos[xx], S->let_cnt[dep][cc], S->let_cnt[dep+1][cc]);
|
674
|
+
memcpy (buf2, aaa, unit);
|
675
|
+
memcpy (aaa, buf, unit);
|
676
|
+
SWAP_PNT (buf, buf2);
|
677
|
+
cnt2[j]++;
|
678
|
+
}
|
679
|
+
memcpy ( aa, buf, unit);
|
680
|
+
}
|
681
|
+
}
|
682
|
+
k=0; FLOOP (i, 0, RADIX_SORT_BUCKET_SIZ){
|
683
|
+
ii = flag==1? i: RADIX_SORT_BUCKET_SIZ-i-1;
|
684
|
+
intarray_sort_iter_ ( (unsigned int*)(((char*)a)+unit*k), cnt[ii]-k, unit*flag);
|
685
|
+
k = cnt[ii];
|
686
|
+
cnt[i]=0;
|
687
|
+
}
|
688
|
+
|
689
|
+
/*
|
690
|
+
for ( i=0 ; i<siz ; i++){
|
691
|
+
k = *((int *)(((char*)a) + i*unit));
|
692
|
+
printf ("%d %d,%d\n", k, k/65536, k&65535);
|
693
|
+
}
|
694
|
+
*/
|
695
|
+
}
|
696
|
+
|
697
|
+
#endif
|
698
|
+
|
699
|
+
/* radix sort for array of structures, by their integer members
|
700
|
+
ranging from mm to m */
|
701
|
+
/* sort array "perm" according to (int/void*) array "a".
|
702
|
+
if perm==NULL, allocate memory and for perm */
|
703
|
+
/* return the permutation array of the result of the sorting
|
704
|
+
in the decreasing order if unit<0 (unimplemented!!!) */
|
705
|
+
int *radix_sort ( void *a, size_t siz, int unit, int mm, int m, int *perm){
|
706
|
+
int *ll, *l, k, i, t, flag=1;
|
707
|
+
malloc2 (l, m-mm, "radix_sort", EXIT0);
|
708
|
+
ARY_FILL (l, 0, m-mm, -1);
|
709
|
+
malloc2 (ll, siz, "radix_sort: ll", {free2(l);EXIT0;});
|
710
|
+
if ( unit <0 ){ unit = -unit; flag = -1; }
|
711
|
+
FLOOP (i, 0, (int)siz){
|
712
|
+
k = (*((int *)(((char *)a) + unit*i ))) - mm;
|
713
|
+
ll[i] = l[k];
|
714
|
+
l[k] = i;
|
715
|
+
}
|
716
|
+
if ( perm ){
|
717
|
+
i=0; FLOOP (k, 0, m-mm){
|
718
|
+
while ( l[k] >= 0 ){
|
719
|
+
t = l[k];
|
720
|
+
l[k] = ll[t];
|
721
|
+
ll[t] = perm[i];
|
722
|
+
i++;
|
723
|
+
}
|
724
|
+
}
|
725
|
+
memcpy (perm, ll, sizeof(int)*siz);
|
726
|
+
free ( ll);
|
727
|
+
free ( l);
|
728
|
+
return ( perm);
|
729
|
+
} else {
|
730
|
+
i=0; FLOOP (k, 0, m-mm){
|
731
|
+
while ( l[k] >= 0 ){
|
732
|
+
t = l[k];
|
733
|
+
l[k] = ll[t];
|
734
|
+
ll[t] = i;
|
735
|
+
i++;
|
736
|
+
}
|
737
|
+
}
|
738
|
+
free (l);
|
739
|
+
return (ll);
|
740
|
+
}
|
741
|
+
}
|
742
|
+
|
743
|
+
/* permutate structure array *tt of unit size unit of size num, according to perm array *pp */
|
744
|
+
/* num has to be <INTHUGE/2 */
|
745
|
+
/* unit<0 means decreasing order (un-implemented!!!) */
|
746
|
+
void structure_permute (void *tt, int unit, int num, void *pp, int weight_siz){
|
747
|
+
int i, ii, *ip, flag=1;
|
748
|
+
char *tmp, *t=(char *)tt, *p=(char *)pp;
|
749
|
+
if ( unit <0 ){ unit = -unit; flag = -1; }
|
750
|
+
malloc2 (tmp, unit, "structure_permute: tmp", EXIT);
|
751
|
+
FLOOP (i, 0, num){
|
752
|
+
ip = (int *)(p + (sizeof(int)+weight_siz)*i + weight_siz);
|
753
|
+
if ( *ip< num && *ip != i ){
|
754
|
+
ii = i;
|
755
|
+
memcpy ( tmp, t + unit*i, unit);
|
756
|
+
while (1) {
|
757
|
+
if ( *ip == i ){
|
758
|
+
memcpy ( t+unit*ii, tmp, unit);
|
759
|
+
*ip += num;
|
760
|
+
break;
|
761
|
+
}
|
762
|
+
memcpy ( t+unit*ii, t+unit*(*ip), unit);
|
763
|
+
ii = *ip;
|
764
|
+
*ip += num;
|
765
|
+
ip = (int *)(p + (sizeof(int)+weight_siz)*ii + weight_siz);
|
766
|
+
}
|
767
|
+
} else *ip += num;
|
768
|
+
}
|
769
|
+
FLOOP (i, 0, num) *(int *)(p + (sizeof(int)+weight_siz)*i + weight_siz ) -= num;
|
770
|
+
free (tmp);
|
771
|
+
}
|
772
|
+
|
773
|
+
|
774
|
+
|
775
|
+
#endif
|
776
|
+
|
777
|
+
|
778
|
+
/******************************************/
|
779
|
+
/* ==== terminology for comments ====
|
780
|
+
range check: to check the input parameter is valid, or in the valid range.
|
781
|
+
If a function does not have this, its comment has "no range check"
|
782
|
+
*/
|
783
|
+
|
784
|
+
/* ==== rules for the name of functions and routines ====
|
785
|
+
init: initialization for an object, structure, etc. memory is allocated
|
786
|
+
if needed.
|
787
|
+
end: compared to init, termination of structures, etc.
|
788
|
+
free allocated memory if it exists, but not free itself.
|
789
|
+
different from ordinary new, create, del, free.
|
790
|
+
|
791
|
+
cpy: copy an object without allocating memory
|
792
|
+
dup: make a duplication of an object with allocating new memory
|
793
|
+
|
794
|
+
new: new. allocate memory for new object. also used for re-allocation from
|
795
|
+
the list of deleted objects
|
796
|
+
del: delete. free memory, or insert it to the list of deleted objects
|
797
|
+
|
798
|
+
ins : insert. insert an element (active, not deleted) to an object, possible
|
799
|
+
at the given position.
|
800
|
+
out : extract. extract an element, possibly specified, from an object.
|
801
|
+
it will be not deleted.
|
802
|
+
rm : extract, and delete
|
803
|
+
rmall: delete all (specified) elements of an object
|
804
|
+
mk : make. new+ins�B
|
805
|
+
mv : move. move the elements from an object to another,
|
806
|
+
or change the position.
|
807
|
+
|
808
|
+
update : update an object, possibly of specified position, to the exact,
|
809
|
+
or to the current one.
|
810
|
+
chg : change the status of an object to the specified one.
|
811
|
+
|
812
|
+
prv: point the previous element
|
813
|
+
nxt: point the next element
|
814
|
+
end: the maximum size (allocated size) of an array, etc.
|
815
|
+
num: the (current) number of elements in an array, etc.
|
816
|
+
kth: for the use of "first k object"
|
817
|
+
tkth: for the use of "first k object from the end". to kth.
|
818
|
+
rnd: random
|
819
|
+
print: print structure and etc.
|
820
|
+
find: search or find an specified element from the set of structures, etc.
|
821
|
+
*/
|
822
|
+
|
823
|
+
/* ==== rules for the name of variables ====
|
824
|
+
- use i or j for the counter in loops
|
825
|
+
- use e for elements
|
826
|
+
- use k for the specified rank
|
827
|
+
- use f or flag for flagment
|
828
|
+
- use m for maximum value or minimum value
|
829
|
+
- use c for counters
|
830
|
+
*/
|
831
|
+
|
832
|
+
|