1 /**CFile***********************************************************************
3 FileName [cuddHarwell.c]
7 Synopsis [Function to read a matrix in Harwell format.]
9 Description [External procedures included in this module:
11 <li> Cudd_addHarwell()
15 Author [Fabio Somenzi]
17 Copyright [Copyright (c) 1995-2004, Regents of the University of Colorado
21 Redistribution and use in source and binary forms, with or without
22 modification, are permitted provided that the following conditions
25 Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
28 Redistributions in binary form must reproduce the above copyright
29 notice, this list of conditions and the following disclaimer in the
30 documentation and/or other materials provided with the distribution.
32 Neither the name of the University of Colorado nor the names of its
33 contributors may be used to endorse or promote products derived from
34 this software without specific prior written permission.
36 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
40 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
42 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
44 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
46 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
47 POSSIBILITY OF SUCH DAMAGE.]
49 ******************************************************************************/
54 /*---------------------------------------------------------------------------*/
55 /* Constant declarations */
56 /*---------------------------------------------------------------------------*/
59 /*---------------------------------------------------------------------------*/
60 /* Stucture declarations */
61 /*---------------------------------------------------------------------------*/
64 /*---------------------------------------------------------------------------*/
65 /* Type declarations */
66 /*---------------------------------------------------------------------------*/
69 /*---------------------------------------------------------------------------*/
70 /* Variable declarations */
71 /*---------------------------------------------------------------------------*/
74 static char rcsid
[] DD_UNUSED
= "$Id: cuddHarwell.c,v 1.9 2004/08/13 18:04:49 fabio Exp $";
77 /*---------------------------------------------------------------------------*/
78 /* Macro declarations */
79 /*---------------------------------------------------------------------------*/
82 /**AutomaticStart*************************************************************/
84 /*---------------------------------------------------------------------------*/
85 /* Static function prototypes */
86 /*---------------------------------------------------------------------------*/
89 /**AutomaticEnd***************************************************************/
92 /*---------------------------------------------------------------------------*/
93 /* Definition of exported functions */
94 /*---------------------------------------------------------------------------*/
96 /**Function********************************************************************
98 Synopsis [Reads in a matrix in the format of the Harwell-Boeing
101 Description [Reads in a matrix in the format of the Harwell-Boeing
102 benchmark suite. The variables are ordered as follows:
104 x\[0\] y\[0\] x\[1\] y\[1\] ...
106 0 is the most significant bit. On input, nx and ny hold the numbers
107 of row and column variables already in existence. On output, they
108 hold the numbers of row and column variables actually used by the
109 matrix. m and n are set to the numbers of rows and columns of the
110 matrix. Their values on input are immaterial. Returns 1 on
111 success; 0 otherwise. The ADD for the sparse matrix is returned in
112 E, and its reference count is > 0.]
116 SeeAlso [Cudd_addRead Cudd_bddRead]
118 ******************************************************************************/
121 FILE * fp
/* pointer to the input file */,
122 DdManager
* dd
/* DD manager */,
123 DdNode
** E
/* characteristic function of the graph */,
124 DdNode
*** x
/* array of row variables */,
125 DdNode
*** y
/* array of column variables */,
126 DdNode
*** xn
/* array of complemented row variables */,
127 DdNode
*** yn_
/* array of complemented column variables */,
128 int * nx
/* number or row variables */,
129 int * ny
/* number or column variables */,
130 int * m
/* number of rows */,
131 int * n
/* number of columns */,
132 int bx
/* first index of row variables */,
133 int sx
/* step of row variables */,
134 int by
/* first index of column variables */,
135 int sy
/* step of column variables */,
136 int pr
/* verbosity level */)
140 DdNode
*cubex
, *cubey
, *minterm1
;
141 int u
, v
, err
, i
, j
, nv
;
143 DdNode
**lx
, **ly
, **lxn
, **lyn
; /* local copies of x, y, xn, yn_ */
144 int lnx
, lny
; /* local copies of nx and ny */
145 char title
[73], key
[9], mxtype
[4], rhstyp
[4];
146 int totcrd
, ptrcrd
, indcrd
, valcrd
, rhscrd
,
147 nrow
, ncol
, nnzero
, neltvl
,
149 int *colptr
, *rowind
;
152 int *rhsptr
, *rhsind
;
155 if (*nx
< 0 || *ny
< 0) return(0);
160 /* Read the header */
161 err
= fscanf(fp
, "%72c %8c", title
, key
);
164 } else if (err
!= 2) {
167 title
[72] = (char) 0;
170 err
= fscanf(fp
, "%d %d %d %d %d", &totcrd
, &ptrcrd
, &indcrd
,
174 } else if (err
!= 5) {
178 err
= fscanf(fp
, "%3s %d %d %d %d", mxtype
, &nrow
, &ncol
,
182 } else if (err
!= 5) {
186 /* Skip FORTRAN formats */
188 err
= fscanf(fp
, "%*s %*s %*s \n");
190 err
= fscanf(fp
, "%*s %*s %*s %*s \n");
194 } else if (err
!= 0) {
198 /* Print out some stuff if requested to be verbose */
200 (void) fprintf(dd
->out
,"%s: type %s, %d rows, %d columns, %d entries\n", key
,
201 mxtype
, nrow
, ncol
, nnzero
);
202 if (pr
>1) (void) fprintf(dd
->out
,"%s\n", title
);
205 /* Check matrix type */
206 if (mxtype
[0] != 'R' || mxtype
[1] != 'U' || mxtype
[2] != 'A') {
207 (void) fprintf(dd
->err
,"%s: Illegal matrix type: %s\n",
211 if (neltvl
!= 0) return(0);
213 /* Read optional 5-th line */
215 err
= fscanf(fp
, "%3c %d %d", rhstyp
, &nrhs
, &nrhsix
);
218 } else if (err
!= 3) {
221 rhstyp
[3] = (char) 0;
222 if (rhstyp
[0] != 'F') {
223 (void) fprintf(dd
->err
,
224 "%s: Sparse right-hand side not yet supported\n", key
);
227 if (pr
>0) (void) fprintf(dd
->out
,"%d right-hand side(s)\n", nrhs
);
232 /* Compute the number of variables */
234 /* row and column numbers start from 0 */
236 for (i
=0; u
> 0; i
++) {
243 v
= 2* (ddMax(ncol
, nrhs
) - 1);
245 for (i
=0; v
> 0; i
++) {
250 /* Allocate or reallocate arrays for variables as needed */
253 *x
= lx
= ALLOC(DdNode
*,lnx
);
255 dd
->errorCode
= CUDD_MEMORY_OUT
;
258 *xn
= lxn
= ALLOC(DdNode
*,lnx
);
260 dd
->errorCode
= CUDD_MEMORY_OUT
;
266 } else if (lnx
> *nx
) {
267 *x
= lx
= REALLOC(DdNode
*, *x
, lnx
);
269 dd
->errorCode
= CUDD_MEMORY_OUT
;
272 *xn
= lxn
= REALLOC(DdNode
*, *xn
, lnx
);
274 dd
->errorCode
= CUDD_MEMORY_OUT
;
283 *y
= ly
= ALLOC(DdNode
*,lny
);
285 dd
->errorCode
= CUDD_MEMORY_OUT
;
288 *yn_
= lyn
= ALLOC(DdNode
*,lny
);
290 dd
->errorCode
= CUDD_MEMORY_OUT
;
296 } else if (lny
> *ny
) {
297 *y
= ly
= REALLOC(DdNode
*, *y
, lny
);
299 dd
->errorCode
= CUDD_MEMORY_OUT
;
302 *yn_
= lyn
= REALLOC(DdNode
*, *yn_
, lny
);
304 dd
->errorCode
= CUDD_MEMORY_OUT
;
312 /* Create new variables as needed */
313 for (i
= *nx
,nv
=bx
+(*nx
)*sx
; i
< lnx
; i
++,nv
+=sx
) {
316 lx
[i
] = cuddUniqueInter(dd
, nv
, one
, zero
);
317 } while (dd
->reordered
== 1);
318 if (lx
[i
] == NULL
) return(0);
322 lxn
[i
] = cuddUniqueInter(dd
, nv
, zero
, one
);
323 } while (dd
->reordered
== 1);
324 if (lxn
[i
] == NULL
) return(0);
327 for (i
= *ny
,nv
=by
+(*ny
)*sy
; i
< lny
; i
++,nv
+=sy
) {
330 ly
[i
] = cuddUniqueInter(dd
, nv
, one
, zero
);
331 } while (dd
->reordered
== 1);
332 if (ly
[i
] == NULL
) return(0);
336 lyn
[i
] = cuddUniqueInter(dd
, nv
, zero
, one
);
337 } while (dd
->reordered
== 1);
338 if (lyn
[i
] == NULL
) return(0);
342 /* Update matrix parameters */
349 *n
= (1 << (lny
- 1)) + nrhs
;
352 /* Read structure data */
353 colptr
= ALLOC(int, ncol
+1);
354 if (colptr
== NULL
) {
355 dd
->errorCode
= CUDD_MEMORY_OUT
;
358 rowind
= ALLOC(int, nnzero
);
359 if (rowind
== NULL
) {
360 dd
->errorCode
= CUDD_MEMORY_OUT
;
364 for (i
=0; i
<ncol
+1; i
++) {
365 err
= fscanf(fp
, " %d ", &u
);
370 } else if (err
!= 1) {
377 if (colptr
[0] != 0) {
378 (void) fprintf(dd
->err
,"%s: Unexpected colptr[0] (%d)\n",
384 for (i
=0; i
<nnzero
; i
++) {
385 err
= fscanf(fp
, " %d ", &u
);
390 } else if (err
!= 1) {
398 *E
= zero
; cuddRef(*E
);
400 for (j
=0; j
<ncol
; j
++) {
402 cubey
= one
; cuddRef(cubey
);
403 for (nv
= lny
- 1; nv
>=0; nv
--) {
405 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, ly
[nv
]);
407 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, lyn
[nv
]);
410 Cudd_RecursiveDeref(dd
, cubey
);
416 Cudd_RecursiveDeref(dd
, cubey
);
420 for (i
=colptr
[j
]; i
<colptr
[j
+1]; i
++) {
422 err
= fscanf(fp
, " %lf ", &val
);
423 if (err
== EOF
|| err
!= 1){
424 Cudd_RecursiveDeref(dd
, cubey
);
429 /* Create new Constant node if necessary */
430 cubex
= cuddUniqueConst(dd
, (CUDD_VALUE_TYPE
) val
);
432 Cudd_RecursiveDeref(dd
, cubey
);
439 for (nv
= lnx
- 1; nv
>=0; nv
--) {
441 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubex
, lx
[nv
]);
443 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubex
, lxn
[nv
]);
446 Cudd_RecursiveDeref(dd
, cubey
);
447 Cudd_RecursiveDeref(dd
, cubex
);
453 Cudd_RecursiveDeref(dd
, cubex
);
457 minterm1
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, cubex
);
458 if (minterm1
== NULL
) {
459 Cudd_RecursiveDeref(dd
, cubey
);
460 Cudd_RecursiveDeref(dd
, cubex
);
466 Cudd_RecursiveDeref(dd
, cubex
);
467 w
= Cudd_addApply(dd
, Cudd_addPlus
, *E
, minterm1
);
469 Cudd_RecursiveDeref(dd
, cubey
);
475 Cudd_RecursiveDeref(dd
, minterm1
);
476 Cudd_RecursiveDeref(dd
, *E
);
479 Cudd_RecursiveDeref(dd
, cubey
);
484 /* Read right-hand sides */
485 for (j
=0; j
<nrhs
; j
++) {
486 v
= j
+ (1<< (lny
-1));
487 cubey
= one
; cuddRef(cubey
);
488 for (nv
= lny
- 1; nv
>=0; nv
--) {
490 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, ly
[nv
]);
492 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, lyn
[nv
]);
495 Cudd_RecursiveDeref(dd
, cubey
);
499 Cudd_RecursiveDeref(dd
, cubey
);
503 for (i
=0; i
<nrow
; i
++) {
505 err
= fscanf(fp
, " %lf ", &val
);
506 if (err
== EOF
|| err
!= 1){
507 Cudd_RecursiveDeref(dd
, cubey
);
510 /* Create new Constant node if necessary */
511 if (val
== (double) 0.0) continue;
512 cubex
= cuddUniqueConst(dd
, (CUDD_VALUE_TYPE
) val
);
514 Cudd_RecursiveDeref(dd
, cubey
);
519 for (nv
= lnx
- 1; nv
>=0; nv
--) {
521 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubex
, lx
[nv
]);
523 w
= Cudd_addApply(dd
, Cudd_addTimes
, cubex
, lxn
[nv
]);
526 Cudd_RecursiveDeref(dd
, cubey
);
527 Cudd_RecursiveDeref(dd
, cubex
);
531 Cudd_RecursiveDeref(dd
, cubex
);
535 minterm1
= Cudd_addApply(dd
, Cudd_addTimes
, cubey
, cubex
);
536 if (minterm1
== NULL
) {
537 Cudd_RecursiveDeref(dd
, cubey
);
538 Cudd_RecursiveDeref(dd
, cubex
);
542 Cudd_RecursiveDeref(dd
, cubex
);
543 w
= Cudd_addApply(dd
, Cudd_addPlus
, *E
, minterm1
);
545 Cudd_RecursiveDeref(dd
, cubey
);
549 Cudd_RecursiveDeref(dd
, minterm1
);
550 Cudd_RecursiveDeref(dd
, *E
);
553 Cudd_RecursiveDeref(dd
, cubey
);
558 } /* end of Cudd_addHarwell */
561 /*---------------------------------------------------------------------------*/
562 /* Definition of internal functions */
563 /*---------------------------------------------------------------------------*/
565 /*---------------------------------------------------------------------------*/
566 /* Definition of static functions */
567 /*---------------------------------------------------------------------------*/