1 /*
2  * Name:    misc.c
3  * Author:  Pietro Belotti
4  * Purpose: miscellaneous functions for reading BZ files, printing LPs, etc
5  *
6  * This code is published under the Eclipse Public License (EPL).
7  * See http://www.eclipse.org/legal/epl-v10.html
8  *
9  */
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <math.h>
15 #include <bzlib.h>
16 
17 #include "sparse.h"
18 #include "lpio.h"
19 #include "rtr.h"
20 #include "misc.h"
21 
22 
23 /*
24  * Print LP (for debugging purposes)
25  */
26 
printLP(int * mfs,sparseLP * lp)27 void printLP (int *mfs, sparseLP *lp) {
28 
29   int i,j,k,l;
30 
31   printf ("Minimize\n obj: ");
32 
33   k=0;
34   for (i=0; i<lp->c0; i++) {
35     if (!(++k % 9))
36       printf ("\n    ");
37     printf (" + 1 x%d", i);
38   }
39 
40   printf("\nSubject To\n");
41 
42   for (i=0; (!mfs && (i<lp->r0)) || (mfs && (mfs[i] >= 0)); i++) {
43 
44     l = mfs ? (mfs[i]) : i;
45 
46     printf ("c%d:", l);
47     k=0;
48 
49     for (j=0; j < lp -> il [l]; j++) {
50       if (!(++k % 5)) {printf ("\n    "); k++;}
51       printf ("%c%f x%d ", (((lp -> ic) [l] [j]) > 0 ? '+' : ' '),
52                              (lp -> ic) [l] [j],
53                              (lp -> ip) [l] [j]);
54     }
55 
56     if (!(k++ % 5)) printf ("\n");
57     printf (">= %f\n", lp -> rhs [l]);
58   }
59 
60   printf ("Bounds\n");
61 
62   for (i=0; i<lp->c0; i++)
63     printf ("%f <= x%d <= %f\n", lp->lb [i], i, lp->ub [i]);
64 
65   printf ("End\n");
66 }
67 
68 
69 /*
70  * Remove LP from memory
71  */
72 
clearLP(sparseLP * lp)73 void clearLP (sparseLP *lp) {
74 
75   int i;
76 
77   for (i=lp->c0 - 1; i>=0; i--) free (lp -> vc [i]);
78   for (i=lp->c0 - 1; i>=0; i--) free (lp -> vp [i]);
79 
80   free (lp->vl);
81 
82   free (lp->vp);
83   free (lp->vc);
84 
85   free (lp->ic);
86   free (lp->ip);
87   free (lp->il);
88 
89   free (lp->rhs);
90 
91   free (lp->chosen);
92 }
93 
94 /****************************************************/
95 /*                                                  */
96 /*  Functions to read from a bzip compressed file   */
97 /*                                                  */
98 /****************************************************/
99 
100 /*
101  *  get char from .bz2 file
102  *
103  * ONLY FOR DEBUGGING PURPOSES
104  * DO NOT USE WITH bzGetDouble or bzGetInt
105  */
106 
bzgetchar(BZFILE * f,char * c)107 int bzgetchar (BZFILE *f, char *c) {
108 
109   static char str [MAX_STR];
110   static char *p = NULL;
111   static int count = 0;
112 
113   int status, i;
114 
115   if (!p) {
116 
117     i = BZ2_bzRead (&status, f, str, MAX_STR);
118     p = str;
119 
120     if (i < MAX_STR) str [i] = 1;
121     count = 0;
122   }
123 
124   *c = *p++;
125 
126   if (*c == 1) return 1;
127 
128   if (++count == MAX_STR) p = NULL;
129 
130   return 0;
131 }
132 
133 
134 /*
135  *  get double from .bz2 file
136  */
137 
bzgetdbl(BZFILE * f,double * val)138 int bzgetdbl (BZFILE *f, double *val) {
139 
140   static char str [2 * MAX_STR];
141   static char *p = NULL;
142 
143   int i, status;
144 
145   if (!p) {
146 
147     i = BZ2_bzRead (&status, f, str, 2 * MAX_STR);
148     p = str;
149 
150     if (i < 2 * MAX_STR) str [i] = 1;
151   }
152 
153 #ifdef RTR_USE_PRAGMAS
154 #pragma execution_frequency(very_high)
155 #endif
156   {
157 
158     register int i,j;
159 
160     char flag = 0;
161 
162     i = strcspn (p,   "+-0123456789eE.");
163 
164     if (p [i] == 1) {
165       p = NULL;
166       return 1;
167     }
168 
169     j = strspn  (p+i, "+-0123456789eE.");
170 
171     if (p [i+j] == 1) flag = 1;
172 
173     p [i+j] = 0;
174 
175     *val = atof (p+i);
176 
177     if (flag || (*(p += i+j+1) == 1)) {
178       p = NULL;
179       return 1;
180     }
181 
182     if (p >= str + MAX_STR) {
183 
184       p -= MAX_STR;
185       memcpy (str, str + MAX_STR, MAX_STR);
186       i = BZ2_bzRead (&status, f, str + MAX_STR, MAX_STR);
187       if (i<MAX_STR) str [MAX_STR + i] = 1;
188     }
189   }
190 
191   return 0;
192 }
193 
194 /*
195  * Transpose coefficient matrix
196  */
197 
create_transpose(sparseLP * lp)198 void create_transpose (sparseLP *lp) {
199 
200   int i, k;
201 
202   int c = lp->c0;
203   int r = lp->rk;
204 
205   int     *vl = lp -> vl = (int     *) malloc (c * sizeof (int));
206   int    **vp = lp -> vp = (int    **) malloc (c * sizeof (int    *));
207   double **vc = lp -> vc = (double **) malloc (c * sizeof (double *));
208 
209   int     *il = lp -> il;
210   int    **ip = lp -> ip;
211   double **ic = lp -> ic;
212 
213   for (i=c; i>0; i--) {
214 
215     *vl++ = 0;
216     *vc++ = NULL;
217     *vp++ = NULL;
218   }
219 
220   vl -= c;
221   vc -= c;
222   vp -= c;
223 
224   for (i=0; i<r; i++) {
225 
226     register int    *pp = *ip++;
227     register double *pc = *ic++;
228 
229     for (k=*il++; k>0; k--, pc++, pp++) {
230 
231       register int j = vl [*pp] ++;
232 
233       if (!(j % MALLOC_BLOCK)) {
234 
235 	vc [*pp] = (double *) realloc (vc [*pp], (j + MALLOC_BLOCK) * sizeof (double));
236 	vp [*pp] = (int    *) realloc (vp [*pp], (j + MALLOC_BLOCK) * sizeof (int));
237 
238 	if (!(vp[*pp]) || !(vc[*pp])) {
239 	  perror ("create_transpose");
240 	  exit (-1);
241 	}
242       }
243 
244       vc [*pp] [j] = *pc;
245       vp [*pp] [j] = i;
246     }
247   }
248 
249 
250   for (i=c; i>0; i--, vl++, vp++, vc++) {
251 
252     *vp = (int    *) realloc (*vp, *vl * sizeof (int));
253     *vc = (double *) realloc (*vc, *vl * sizeof (double));
254   }
255 }
256