Graphviz 13.0.0~dev.20241220.2304
Loading...
Searching...
No Matches
matrix_market.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <sparse/SparseMatrix.h>
12#include "mmio.h"
13#include "matrix_market.h"
14#include <stdbool.h>
15#include <util/alloc.h>
16
18{
19 int ret_code;
20 MM_typecode matcode;
21 double *val = NULL, *v;
22 int *vali = NULL, i, m, n, *I = NULL, *J = NULL, nz;
23 void *vp = NULL;
25 int nzold;
26 int c;
27
28 if ((c = fgetc(f)) != '%') {
29 ungetc(c, f);
30 return NULL;
31 }
32 ungetc(c, f);
33 if (mm_read_banner(f, &matcode) != 0) {
34#ifdef DEBUG
35 printf("Could not process Matrix Market banner.\n");
36#endif
37 return NULL;
38 }
39
40 /* find out size of sparse matrix .... */
41 if ((ret_code = mm_read_mtx_crd_size(f, &m, &n, &nz)) != 0) {
42 return NULL;
43 }
44 /* reseve memory for matrices */
45
46 I = gv_calloc(nz, sizeof(int));
47 J = gv_calloc(nz, sizeof(int));
48
49 const int type = matcode.type;
50 switch (type) {
52 val = gv_calloc(nz, sizeof(double));
53 for (i = 0; i < nz; i++) {
54 int num = fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
55 if (num != 3) {
56 goto done;
57 }
58 I[i]--; /* adjust from 1-based to 0-based */
59 J[i]--;
60 }
61 if (matcode.shape == MS_SYMMETRIC) {
62 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
63 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
64 val = gv_recalloc(val, nz, 2 * nz, sizeof(double));
65 nzold = nz;
66 for (i = 0; i < nzold; i++) {
67 if (I[i] != J[i]) {
68 I[nz] = J[i];
69 J[nz] = I[i];
70 val[nz++] = val[i];
71 }
72 }
73 } else if (matcode.shape == MS_SKEW) {
74 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
75 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
76 val = gv_recalloc(val, nz, 2 * nz, sizeof(double));
77 nzold = nz;
78 for (i = 0; i < nzold; i++) {
79 if (I[i] == J[i]) { // skew symm should have no diag
80 goto done;
81 }
82 I[nz] = J[i];
83 J[nz] = I[i];
84 val[nz++] = -val[i];
85 }
86 } else if (matcode.shape == MS_HERMITIAN) {
87 goto done;
88 }
89 vp = val;
90 break;
92 vali = gv_calloc(nz, sizeof(int));
93 for (i = 0; i < nz; i++) {
94 int num = fscanf(f, "%d %d %d\n", &I[i], &J[i], &vali[i]);
95 if (num != 3) {
96 goto done;
97 }
98 I[i]--; /* adjust from 1-based to 0-based */
99 J[i]--;
100 }
101 if (matcode.shape == MS_SYMMETRIC) {
102 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
103 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
104 vali = gv_recalloc(vali, nz, 2 * nz, sizeof(int));
105 nzold = nz;
106 for (i = 0; i < nzold; i++) {
107 if (I[i] != J[i]) {
108 I[nz] = J[i];
109 J[nz] = I[i];
110 vali[nz++] = vali[i];
111 }
112 }
113 } else if (matcode.shape == MS_SKEW) {
114 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
115 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
116 vali = gv_recalloc(vali, nz, 2 * nz, sizeof(int));
117 nzold = nz;
118 for (i = 0; i < nzold; i++) {
119 if (I[i] == J[i]) { // skew symm should have no diag
120 goto done;
121 }
122 I[nz] = J[i];
123 J[nz] = I[i];
124 vali[nz++] = -vali[i];
125 }
126 } else if (matcode.shape == MS_HERMITIAN) {
127 goto done;
128 }
129 vp = vali;
130 break;
132 for (i = 0; i < nz; i++) {
133 int num = fscanf(f, "%d %d\n", &I[i], &J[i]);
134 if (num != 2) {
135 goto done;
136 }
137 I[i]--; /* adjust from 1-based to 0-based */
138 J[i]--;
139 }
140 if (matcode.shape == MS_SYMMETRIC || matcode.shape == MS_SKEW) {
141 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
142 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
143 nzold = nz;
144 for (i = 0; i < nzold; i++) {
145 if (I[i] != J[i]) {
146 I[nz] = J[i];
147 J[nz++] = I[i];
148 }
149 }
150 } else if (matcode.shape == MS_HERMITIAN) {
151 goto done;
152 }
153 break;
155 val = gv_calloc(2 * nz, sizeof(double));
156 v = val;
157 for (i = 0; i < nz; i++) {
158 int num = fscanf(f, "%d %d %lg %lg\n", &I[i], &J[i], &v[0], &v[1]);
159 if (num != 4) {
160 goto done;
161 }
162 v += 2;
163 I[i]--; /* adjust from 1-based to 0-based */
164 J[i]--;
165 }
166 if (matcode.shape == MS_SYMMETRIC) {
167 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
168 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
169 val = gv_recalloc(val, 2 * nz, 4 * nz, sizeof(double));
170 nzold = nz;
171 for (i = 0; i < nzold; i++) {
172 if (I[i] != J[i]) {
173 I[nz] = J[i];
174 J[nz] = I[i];
175 val[2 * nz] = val[2 * i];
176 val[2 * nz + 1] = val[2 * i + 1];
177 nz++;
178 }
179 }
180 } else if (matcode.shape == MS_SKEW) {
181 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
182 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
183 val = gv_recalloc(val, 2 * nz, 4 * nz, sizeof(double));
184 nzold = nz;
185 for (i = 0; i < nzold; i++) {
186 if (I[i] == J[i]) { // skew symm should have no diag
187 goto done;
188 }
189 I[nz] = J[i];
190 J[nz] = I[i];
191 val[2 * nz] = -val[2 * i];
192 val[2 * nz + 1] = -val[2 * i + 1];
193 nz++;
194
195 }
196 } else if (matcode.shape == MS_HERMITIAN) {
197 I = gv_recalloc(I, nz, 2 * nz, sizeof(int));
198 J = gv_recalloc(J, nz, 2 * nz, sizeof(int));
199 val = gv_recalloc(val, 2 * nz, 4 * nz, sizeof(double));
200 nzold = nz;
201 for (i = 0; i < nzold; i++) {
202 if (I[i] != J[i]) {
203 I[nz] = J[i];
204 J[nz] = I[i];
205 val[2 * nz] = val[2 * i];
206 val[2 * nz + 1] = -val[2 * i + 1];
207 nz++;
208 }
209 }
210 }
211 vp = val;
212 break;
213 default:
214 goto done;
215 }
216
217 A = SparseMatrix_from_coordinate_arrays(nz, m, n, I, J, vp,
218 type, sizeof(double));
219done:
220 free(I);
221 free(J);
222 free(val);
223
224 if (A != NULL && matcode.shape == MS_SYMMETRIC) {
225 A->is_symmetric = true;
226 A->is_pattern_symmetric = true;
227 }
228
229
230 return A;
231}
SparseMatrix SparseMatrix_from_coordinate_arrays(int nz, int m, int n, int *irn, int *jcn, void *val0, int type, size_t sz)
@ MATRIX_TYPE_REAL
@ MATRIX_TYPE_PATTERN
@ MATRIX_TYPE_COMPLEX
@ MATRIX_TYPE_INTEGER
Memory allocation wrappers that exit on failure.
static void * gv_recalloc(void *ptr, size_t old_nmemb, size_t new_nmemb, size_t size)
Definition alloc.h:73
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
expr procedure type
Definition exparse.y:208
#define A(n, t)
Definition expr.h:76
#define I
Definition expr.h:71
void free(void *)
node NULL
Definition grammar.y:163
SparseMatrix SparseMatrix_import_matrix_market(FILE *f)
import Matrix Market
int mm_read_mtx_crd_size(FILE *f, int *M, int *N, int *nz)
Definition mmio.c:92
int mm_read_banner(FILE *f, MM_typecode *matcode)
Definition mmio.c:28
Matrix Market I/O API
@ MS_SYMMETRIC
Definition mmio.h:29
@ MS_SKEW
Definition mmio.h:29
@ MS_HERMITIAN
Definition mmio.h:29
matrix_shape_t shape
Definition mmio.h:33
int type
one of the MATRIX_TYPE_* values from lib/sparse
Definition mmio.h:32