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