1 
2 /*! @file dreadrb.c
3  * \brief Read a matrix stored in Rutherford-Boeing format
4  *
5  * <pre>
6  * -- SuperLU routine (version 4.0) --
7  * Lawrence Berkeley National Laboratory.
8  * June 30, 2009
9  * </pre>
10  *
11  * Purpose
12  * =======
13  *
14  * Read a DOUBLE PRECISION matrix stored in Rutherford-Boeing format
15  * as described below.
16  *
17  * Line 1 (A72, A8)
18  *      Col. 1 - 72   Title (TITLE)
19  *      Col. 73 - 80  Matrix name / identifier (MTRXID)
20  *
21  * Line 2 (I14, 3(1X, I13))
22  *      Col. 1 - 14   Total number of lines excluding header (TOTCRD)
23  *      Col. 16 - 28  Number of lines for pointers (PTRCRD)
24  *      Col. 30 - 42  Number of lines for row (or variable) indices (INDCRD)
25  *      Col. 44 - 56  Number of lines for numerical values (VALCRD)
26  *
27  * Line 3 (A3, 11X, 4(1X, I13))
28  *      Col. 1 - 3    Matrix type (see below) (MXTYPE)
29  *      Col. 15 - 28  Compressed Column: Number of rows (NROW)
30  *                    Elemental: Largest integer used to index variable (MVAR)
31  *      Col. 30 - 42  Compressed Column: Number of columns (NCOL)
32  *                    Elemental: Number of element matrices (NELT)
33  *      Col. 44 - 56  Compressed Column: Number of entries (NNZERO)
34  *                    Elemental: Number of variable indeces (NVARIX)
35  *      Col. 58 - 70  Compressed Column: Unused, explicitly zero
36  *                    Elemental: Number of elemental matrix entries (NELTVL)
37  *
38  * Line 4 (2A16, A20)
39  *      Col. 1 - 16   Fortran format for pointers (PTRFMT)
40  *      Col. 17 - 32  Fortran format for row (or variable) indices (INDFMT)
41  *      Col. 33 - 52  Fortran format for numerical values of coefficient matrix
42  *                    (VALFMT)
43  *                    (blank in the case of matrix patterns)
44  *
45  * The three character type field on line 3 describes the matrix type.
46  * The following table lists the permitted values for each of the three
47  * characters. As an example of the type field, RSA denotes that the matrix
48  * is real, symmetric, and assembled.
49  *
50  * First Character:
51  *      R Real matrix
52  *      C Complex matrix
53  *      I integer matrix
54  *      P Pattern only (no numerical values supplied)
55  *      Q Pattern only (numerical values supplied in associated auxiliary value
56  *        file)
57  *
58  * Second Character:
59  *      S Symmetric
60  *      U Unsymmetric
61  *      H Hermitian
62  *      Z Skew symmetric
63  *      R Rectangular
64  *
65  * Third Character:
66  *      A Compressed column form
67  *      E Elemental form
68  *
69  * </pre>
70  */
71 
72 #include "slu_ddefs.h"
73 
74 
75 /*! \brief Eat up the rest of the current line */
dDumpLine(FILE * fp)76 static int dDumpLine(FILE *fp)
77 {
78     register int c;
79     while ((c = fgetc(fp)) != '\n') ;
80     return 0;
81 }
82 
dParseIntFormat(char * buf,int * num,int * size)83 static int dParseIntFormat(char *buf, int *num, int *size)
84 {
85     char *tmp;
86 
87     tmp = buf;
88     while (*tmp++ != '(') ;
89     sscanf(tmp, "%d", num);
90     while (*tmp != 'I' && *tmp != 'i') ++tmp;
91     ++tmp;
92     sscanf(tmp, "%d", size);
93     return 0;
94 }
95 
dParseFloatFormat(char * buf,int * num,int * size)96 static int dParseFloatFormat(char *buf, int *num, int *size)
97 {
98     char *tmp, *period;
99 
100     tmp = buf;
101     while (*tmp++ != '(') ;
102     *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/
103     while (*tmp != 'E' && *tmp != 'e' && *tmp != 'D' && *tmp != 'd'
104            && *tmp != 'F' && *tmp != 'f') {
105         /* May find kP before nE/nD/nF, like (1P6F13.6). In this case the
106            num picked up refers to P, which should be skipped. */
107         if (*tmp=='p' || *tmp=='P') {
108            ++tmp;
109            *num = atoi(tmp); /*sscanf(tmp, "%d", num);*/
110         } else {
111            ++tmp;
112         }
113     }
114     ++tmp;
115     period = tmp;
116     while (*period != '.' && *period != ')') ++period ;
117     *period = '\0';
118     *size = atoi(tmp); /*sscanf(tmp, "%2d", size);*/
119 
120     return 0;
121 }
122 
ReadVector(FILE * fp,int n,int * where,int perline,int persize)123 static int ReadVector(FILE *fp, int n, int *where, int perline, int persize)
124 {
125     register int i, j, item;
126     char tmp, buf[100];
127 
128     i = 0;
129     while (i < n) {
130         fgets(buf, 100, fp);    /* read a line at a time */
131         for (j=0; j<perline && i<n; j++) {
132             tmp = buf[(j+1)*persize];     /* save the char at that place */
133             buf[(j+1)*persize] = 0;       /* null terminate */
134             item = atoi(&buf[j*persize]);
135             buf[(j+1)*persize] = tmp;     /* recover the char at that place */
136             where[i++] = item - 1;
137         }
138     }
139 
140     return 0;
141 }
142 
dReadValues(FILE * fp,int n,double * destination,int perline,int persize)143 static int dReadValues(FILE *fp, int n, double *destination, int perline,
144         int persize)
145 {
146     register int i, j, k, s;
147     char tmp, buf[100];
148 
149     i = 0;
150     while (i < n) {
151         fgets(buf, 100, fp);    /* read a line at a time */
152         for (j=0; j<perline && i<n; j++) {
153             tmp = buf[(j+1)*persize];     /* save the char at that place */
154             buf[(j+1)*persize] = 0;       /* null terminate */
155             s = j*persize;
156             for (k = 0; k < persize; ++k) /* No D_ format in C */
157                 if ( buf[s+k] == 'D' || buf[s+k] == 'd' ) buf[s+k] = 'E';
158             destination[i++] = atof(&buf[s]);
159             buf[(j+1)*persize] = tmp;     /* recover the char at that place */
160         }
161     }
162 
163     return 0;
164 }
165 
166 
167 
168 void
dreadrb(int * nrow,int * ncol,int * nonz,double ** nzval,int ** rowind,int ** colptr)169 dreadrb(int *nrow, int *ncol, int *nonz,
170         double **nzval, int **rowind, int **colptr)
171 {
172 
173     register int i, numer_lines = 0;
174     int tmp, colnum, colsize, rownum, rowsize, valnum, valsize;
175     char buf[100], type[4];
176     FILE *fp;
177 
178     fp = stdin;
179 
180     /* Line 1 */
181     fgets(buf, 100, fp);
182     fputs(buf, stdout);
183 
184     /* Line 2 */
185     for (i=0; i<4; i++) {
186         fscanf(fp, "%14c", buf); buf[14] = 0;
187         sscanf(buf, "%d", &tmp);
188         if (i == 3) numer_lines = tmp;
189     }
190     dDumpLine(fp);
191 
192     /* Line 3 */
193     fscanf(fp, "%3c", type);
194     fscanf(fp, "%11c", buf); /* pad */
195     type[3] = 0;
196 #ifdef DEBUG
197     printf("Matrix type %s\n", type);
198 #endif
199 
200     fscanf(fp, "%14c", buf); sscanf(buf, "%d", nrow);
201     fscanf(fp, "%14c", buf); sscanf(buf, "%d", ncol);
202     fscanf(fp, "%14c", buf); sscanf(buf, "%d", nonz);
203     fscanf(fp, "%14c", buf); sscanf(buf, "%d", &tmp);
204 
205     if (tmp != 0)
206         printf("This is not an assembled matrix!\n");
207     if (*nrow != *ncol)
208         printf("Matrix is not square.\n");
209     dDumpLine(fp);
210 
211     /* Allocate storage for the three arrays ( nzval, rowind, colptr ) */
212     dallocateA(*ncol, *nonz, nzval, rowind, colptr);
213 
214     /* Line 4: format statement */
215     fscanf(fp, "%16c", buf);
216     dParseIntFormat(buf, &colnum, &colsize);
217     fscanf(fp, "%16c", buf);
218     dParseIntFormat(buf, &rownum, &rowsize);
219     fscanf(fp, "%20c", buf);
220     dParseFloatFormat(buf, &valnum, &valsize);
221     dDumpLine(fp);
222 
223 #ifdef DEBUG
224     printf("%d rows, %d nonzeros\n", *nrow, *nonz);
225     printf("colnum %d, colsize %d\n", colnum, colsize);
226     printf("rownum %d, rowsize %d\n", rownum, rowsize);
227     printf("valnum %d, valsize %d\n", valnum, valsize);
228 #endif
229 
230     ReadVector(fp, *ncol+1, *colptr, colnum, colsize);
231     ReadVector(fp, *nonz, *rowind, rownum, rowsize);
232     if ( numer_lines ) {
233         dReadValues(fp, *nonz, *nzval, valnum, valsize);
234     }
235 
236     fclose(fp);
237 }
238