00001
00024 #include "util_hack.h"
00025 #include "cuddInt.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef lint
00047 static char rcsid[] DD_UNUSED = "$Id: cuddHarwell.c,v 1.1.1.1 2003/02/24 22:23:52 wjiang Exp $";
00048 #endif
00049
00050
00051
00052
00053
00054
00057
00058
00059
00060
00061
00065
00066
00067
00068
00092 int
00093 Cudd_addHarwell(
00094 FILE * fp ,
00095 DdManager * dd ,
00096 DdNode ** E ,
00097 DdNode *** x ,
00098 DdNode *** y ,
00099 DdNode *** xn ,
00100 DdNode *** yn_ ,
00101 int * nx ,
00102 int * ny ,
00103 int * m ,
00104 int * n ,
00105 int bx ,
00106 int sx ,
00107 int by ,
00108 int sy ,
00109 int pr )
00110 {
00111 DdNode *one, *zero;
00112 DdNode *w;
00113 DdNode *cubex, *cubey, *minterm1;
00114 int u, v, err, i, j, nv;
00115 double val;
00116 DdNode **lx, **ly, **lxn, **lyn;
00117 int lnx, lny;
00118 char title[73], key[9], mxtype[4], rhstyp[4];
00119 int totcrd, ptrcrd, indcrd, valcrd, rhscrd,
00120 nrow, ncol, nnzero, neltvl,
00121 nrhs, nrhsix;
00122 int *colptr, *rowind;
00123 #if 0
00124 int nguess, nexact;
00125 int *rhsptr, *rhsind;
00126 #endif
00127
00128 if (*nx < 0 || *ny < 0) return(0);
00129
00130 one = DD_ONE(dd);
00131 zero = DD_ZERO(dd);
00132
00133
00134 err = fscanf(fp, "%72c %8c", title, key);
00135 if (err == EOF) {
00136 return(0);
00137 } else if (err != 2) {
00138 return(0);
00139 }
00140 title[72] = (char) 0;
00141 key[8] = (char) 0;
00142
00143 err = fscanf(fp, "%d %d %d %d %d", &totcrd, &ptrcrd, &indcrd,
00144 &valcrd, &rhscrd);
00145 if (err == EOF) {
00146 return(0);
00147 } else if (err != 5) {
00148 return(0);
00149 }
00150
00151 err = fscanf(fp, "%3s %d %d %d %d", mxtype, &nrow, &ncol,
00152 &nnzero, &neltvl);
00153 if (err == EOF) {
00154 return(0);
00155 } else if (err != 5) {
00156 return(0);
00157 }
00158
00159
00160 if (rhscrd == 0) {
00161 err = fscanf(fp, "%*s %*s %*s \n");
00162 } else {
00163 err = fscanf(fp, "%*s %*s %*s %*s \n");
00164 }
00165 if (err == EOF) {
00166 return(0);
00167 } else if (err != 0) {
00168 return(0);
00169 }
00170
00171
00172 if (pr>0) {
00173 (void) fprintf(dd->out,"%s: type %s, %d rows, %d columns, %d entries\n", key,
00174 mxtype, nrow, ncol, nnzero);
00175 if (pr>1) (void) fprintf(dd->out,"%s\n", title);
00176 }
00177
00178
00179 if (mxtype[0] != 'R' || mxtype[1] != 'U' || mxtype[2] != 'A') {
00180 (void) fprintf(dd->err,"%s: Illegal matrix type: %s\n",
00181 key, mxtype);
00182 return(0);
00183 }
00184 if (neltvl != 0) return(0);
00185
00186
00187 if (rhscrd != 0) {
00188 err = fscanf(fp, "%3c %d %d", rhstyp, &nrhs, &nrhsix);
00189 if (err == EOF) {
00190 return(0);
00191 } else if (err != 3) {
00192 return(0);
00193 }
00194 rhstyp[3] = (char) 0;
00195 if (rhstyp[0] != 'F') {
00196 (void) fprintf(dd->err,
00197 "%s: Sparse right-hand side not yet supported\n", key);
00198 return(0);
00199 }
00200 if (pr>0) (void) fprintf(dd->out,"%d right-hand side(s)\n", nrhs);
00201 } else {
00202 nrhs = 0;
00203 }
00204
00205
00206
00207
00208 u = nrow - 1;
00209 for (i=0; u > 0; i++) {
00210 u >>= 1;
00211 }
00212 lnx = i;
00213 if (nrhs == 0) {
00214 v = ncol - 1;
00215 } else {
00216 v = 2* (ddMax(ncol, nrhs) - 1);
00217 }
00218 for (i=0; v > 0; i++) {
00219 v >>= 1;
00220 }
00221 lny = i;
00222
00223
00224 if (*nx == 0) {
00225 if (lnx > 0) {
00226 *x = lx = ALLOC(DdNode *,lnx);
00227 if (lx == NULL) {
00228 dd->errorCode = CUDD_MEMORY_OUT;
00229 return(0);
00230 }
00231 *xn = lxn = ALLOC(DdNode *,lnx);
00232 if (lxn == NULL) {
00233 dd->errorCode = CUDD_MEMORY_OUT;
00234 return(0);
00235 }
00236 } else {
00237 *x = *xn = NULL;
00238 }
00239 } else if (lnx > *nx) {
00240 *x = lx = REALLOC(DdNode *, *x, lnx);
00241 if (lx == NULL) {
00242 dd->errorCode = CUDD_MEMORY_OUT;
00243 return(0);
00244 }
00245 *xn = lxn = REALLOC(DdNode *, *xn, lnx);
00246 if (lxn == NULL) {
00247 dd->errorCode = CUDD_MEMORY_OUT;
00248 return(0);
00249 }
00250 } else {
00251 lx = *x;
00252 lxn = *xn;
00253 }
00254 if (*ny == 0) {
00255 if (lny >0) {
00256 *y = ly = ALLOC(DdNode *,lny);
00257 if (ly == NULL) {
00258 dd->errorCode = CUDD_MEMORY_OUT;
00259 return(0);
00260 }
00261 *yn_ = lyn = ALLOC(DdNode *,lny);
00262 if (lyn == NULL) {
00263 dd->errorCode = CUDD_MEMORY_OUT;
00264 return(0);
00265 }
00266 } else {
00267 *y = *yn_ = NULL;
00268 }
00269 } else if (lny > *ny) {
00270 *y = ly = REALLOC(DdNode *, *y, lny);
00271 if (ly == NULL) {
00272 dd->errorCode = CUDD_MEMORY_OUT;
00273 return(0);
00274 }
00275 *yn_ = lyn = REALLOC(DdNode *, *yn_, lny);
00276 if (lyn == NULL) {
00277 dd->errorCode = CUDD_MEMORY_OUT;
00278 return(0);
00279 }
00280 } else {
00281 ly = *y;
00282 lyn = *yn_;
00283 }
00284
00285
00286 for (i= *nx,nv=bx+(*nx)*sx; i < lnx; i++,nv+=sx) {
00287 do {
00288 dd->reordered = 0;
00289 lx[i] = cuddUniqueInter(dd, nv, one, zero);
00290 } while (dd->reordered == 1);
00291 if (lx[i] == NULL) return(0);
00292 cuddRef(lx[i]);
00293 do {
00294 dd->reordered = 0;
00295 lxn[i] = cuddUniqueInter(dd, nv, zero, one);
00296 } while (dd->reordered == 1);
00297 if (lxn[i] == NULL) return(0);
00298 cuddRef(lxn[i]);
00299 }
00300 for (i= *ny,nv=by+(*ny)*sy; i < lny; i++,nv+=sy) {
00301 do {
00302 dd->reordered = 0;
00303 ly[i] = cuddUniqueInter(dd, nv, one, zero);
00304 } while (dd->reordered == 1);
00305 if (ly[i] == NULL) return(0);
00306 cuddRef(ly[i]);
00307 do {
00308 dd->reordered = 0;
00309 lyn[i] = cuddUniqueInter(dd, nv, zero, one);
00310 } while (dd->reordered == 1);
00311 if (lyn[i] == NULL) return(0);
00312 cuddRef(lyn[i]);
00313 }
00314
00315
00316 *nx = lnx;
00317 *ny = lny;
00318 *m = nrow;
00319 if (nrhs == 0) {
00320 *n = ncol;
00321 } else {
00322 *n = (1 << (lny - 1)) + nrhs;
00323 }
00324
00325
00326 colptr = ALLOC(int, ncol+1);
00327 if (colptr == NULL) {
00328 dd->errorCode = CUDD_MEMORY_OUT;
00329 return(0);
00330 }
00331 rowind = ALLOC(int, nnzero);
00332 if (rowind == NULL) {
00333 dd->errorCode = CUDD_MEMORY_OUT;
00334 return(0);
00335 }
00336
00337 for (i=0; i<ncol+1; i++) {
00338 err = fscanf(fp, " %d ", &u);
00339 if (err == EOF){
00340 FREE(colptr);
00341 FREE(rowind);
00342 return(0);
00343 } else if (err != 1) {
00344 FREE(colptr);
00345 FREE(rowind);
00346 return(0);
00347 }
00348 colptr[i] = u - 1;
00349 }
00350 if (colptr[0] != 0) {
00351 (void) fprintf(dd->err,"%s: Unexpected colptr[0] (%d)\n",
00352 key,colptr[0]);
00353 FREE(colptr);
00354 FREE(rowind);
00355 return(0);
00356 }
00357 for (i=0; i<nnzero; i++) {
00358 err = fscanf(fp, " %d ", &u);
00359 if (err == EOF){
00360 FREE(colptr);
00361 FREE(rowind);
00362 return(0);
00363 } else if (err != 1) {
00364 FREE(colptr);
00365 FREE(rowind);
00366 return(0);
00367 }
00368 rowind[i] = u - 1;
00369 }
00370
00371 *E = zero; cuddRef(*E);
00372
00373 for (j=0; j<ncol; j++) {
00374 v = j;
00375 cubey = one; cuddRef(cubey);
00376 for (nv = lny - 1; nv>=0; nv--) {
00377 if (v & 1) {
00378 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
00379 } else {
00380 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
00381 }
00382 if (w == NULL) {
00383 Cudd_RecursiveDeref(dd, cubey);
00384 FREE(colptr);
00385 FREE(rowind);
00386 return(0);
00387 }
00388 cuddRef(w);
00389 Cudd_RecursiveDeref(dd, cubey);
00390 cubey = w;
00391 v >>= 1;
00392 }
00393 for (i=colptr[j]; i<colptr[j+1]; i++) {
00394 u = rowind[i];
00395 err = fscanf(fp, " %lf ", &val);
00396 if (err == EOF || err != 1){
00397 Cudd_RecursiveDeref(dd, cubey);
00398 FREE(colptr);
00399 FREE(rowind);
00400 return(0);
00401 }
00402
00403 cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
00404 if (cubex == NULL) {
00405 Cudd_RecursiveDeref(dd, cubey);
00406 FREE(colptr);
00407 FREE(rowind);
00408 return(0);
00409 }
00410 cuddRef(cubex);
00411
00412 for (nv = lnx - 1; nv>=0; nv--) {
00413 if (u & 1) {
00414 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
00415 } else {
00416 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
00417 }
00418 if (w == NULL) {
00419 Cudd_RecursiveDeref(dd, cubey);
00420 Cudd_RecursiveDeref(dd, cubex);
00421 FREE(colptr);
00422 FREE(rowind);
00423 return(0);
00424 }
00425 cuddRef(w);
00426 Cudd_RecursiveDeref(dd, cubex);
00427 cubex = w;
00428 u >>= 1;
00429 }
00430 minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
00431 if (minterm1 == NULL) {
00432 Cudd_RecursiveDeref(dd, cubey);
00433 Cudd_RecursiveDeref(dd, cubex);
00434 FREE(colptr);
00435 FREE(rowind);
00436 return(0);
00437 }
00438 cuddRef(minterm1);
00439 Cudd_RecursiveDeref(dd, cubex);
00440 w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
00441 if (w == NULL) {
00442 Cudd_RecursiveDeref(dd, cubey);
00443 FREE(colptr);
00444 FREE(rowind);
00445 return(0);
00446 }
00447 cuddRef(w);
00448 Cudd_RecursiveDeref(dd, minterm1);
00449 Cudd_RecursiveDeref(dd, *E);
00450 *E = w;
00451 }
00452 Cudd_RecursiveDeref(dd, cubey);
00453 }
00454 FREE(colptr);
00455 FREE(rowind);
00456
00457
00458 for (j=0; j<nrhs; j++) {
00459 v = j + (1<< (lny-1));
00460 cubey = one; cuddRef(cubey);
00461 for (nv = lny - 1; nv>=0; nv--) {
00462 if (v & 1) {
00463 w = Cudd_addApply(dd, Cudd_addTimes, cubey, ly[nv]);
00464 } else {
00465 w = Cudd_addApply(dd, Cudd_addTimes, cubey, lyn[nv]);
00466 }
00467 if (w == NULL) {
00468 Cudd_RecursiveDeref(dd, cubey);
00469 return(0);
00470 }
00471 cuddRef(w);
00472 Cudd_RecursiveDeref(dd, cubey);
00473 cubey = w;
00474 v >>= 1;
00475 }
00476 for (i=0; i<nrow; i++) {
00477 u = i;
00478 err = fscanf(fp, " %lf ", &val);
00479 if (err == EOF || err != 1){
00480 Cudd_RecursiveDeref(dd, cubey);
00481 return(0);
00482 }
00483
00484 if (val == (double) 0.0) continue;
00485 cubex = cuddUniqueConst(dd, (CUDD_VALUE_TYPE) val);
00486 if (cubex == NULL) {
00487 Cudd_RecursiveDeref(dd, cubey);
00488 return(0);
00489 }
00490 cuddRef(cubex);
00491
00492 for (nv = lnx - 1; nv>=0; nv--) {
00493 if (u & 1) {
00494 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lx[nv]);
00495 } else {
00496 w = Cudd_addApply(dd, Cudd_addTimes, cubex, lxn[nv]);
00497 }
00498 if (w == NULL) {
00499 Cudd_RecursiveDeref(dd, cubey);
00500 Cudd_RecursiveDeref(dd, cubex);
00501 return(0);
00502 }
00503 cuddRef(w);
00504 Cudd_RecursiveDeref(dd, cubex);
00505 cubex = w;
00506 u >>= 1;
00507 }
00508 minterm1 = Cudd_addApply(dd, Cudd_addTimes, cubey, cubex);
00509 if (minterm1 == NULL) {
00510 Cudd_RecursiveDeref(dd, cubey);
00511 Cudd_RecursiveDeref(dd, cubex);
00512 return(0);
00513 }
00514 cuddRef(minterm1);
00515 Cudd_RecursiveDeref(dd, cubex);
00516 w = Cudd_addApply(dd, Cudd_addPlus, *E, minterm1);
00517 if (w == NULL) {
00518 Cudd_RecursiveDeref(dd, cubey);
00519 return(0);
00520 }
00521 cuddRef(w);
00522 Cudd_RecursiveDeref(dd, minterm1);
00523 Cudd_RecursiveDeref(dd, *E);
00524 *E = w;
00525 }
00526 Cudd_RecursiveDeref(dd, cubey);
00527 }
00528
00529 return(1);
00530
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541