Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F80590109
mmio.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Sep 1, 13:28
Size
12 KB
Mime Type
text/x-c
Expires
Tue, Sep 3, 13:28 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
20239426
Attached To
R12662 PHPC-graded_hw_1
mmio.c
View Options
/*
* Matrix Market I/O library for ANSI C
*
* See http://math.nist.gov/MatrixMarket for details.
*
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "mmio.h"
int
mm_read_unsymmetric_sparse
(
const
char
*
fname
,
int
*
M_
,
int
*
N_
,
int
*
nz_
,
double
**
val_
,
int
**
I_
,
int
**
J_
)
{
FILE
*
f
;
MM_typecode
matcode
;
int
M
,
N
,
nz
;
int
i
;
double
*
val
;
int
*
I
,
*
J
;
if
((
f
=
fopen
(
fname
,
"r"
))
==
NULL
)
return
-
1
;
if
(
mm_read_banner
(
f
,
&
matcode
)
!=
0
)
{
printf
(
"mm_read_unsymetric: Could not process Matrix Market banner "
);
printf
(
" in file [%s]
\n
"
,
fname
);
return
-
1
;
}
if
(
!
(
mm_is_real
(
matcode
)
&&
mm_is_matrix
(
matcode
)
&&
mm_is_sparse
(
matcode
)))
{
fprintf
(
stderr
,
"Sorry, this application does not support "
);
fprintf
(
stderr
,
"Market Market type: [%s]
\n
"
,
mm_typecode_to_str
(
matcode
));
return
-
1
;
}
/* find out size of sparse matrix: M, N, nz .... */
if
(
mm_read_mtx_crd_size
(
f
,
&
M
,
&
N
,
&
nz
)
!=
0
)
{
fprintf
(
stderr
,
"read_unsymmetric_sparse(): could not parse matrix size.
\n
"
);
return
-
1
;
}
*
M_
=
M
;
*
N_
=
N
;
*
nz_
=
nz
;
/* reseve memory for matrices */
I
=
(
int
*
)
malloc
(
nz
*
sizeof
(
int
));
J
=
(
int
*
)
malloc
(
nz
*
sizeof
(
int
));
val
=
(
double
*
)
malloc
(
nz
*
sizeof
(
double
));
*
val_
=
val
;
*
I_
=
I
;
*
J_
=
J
;
/* NOTE: when reading in doubles, ANSI C requires the use of the "l" */
/* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */
/* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */
for
(
i
=
0
;
i
<
nz
;
i
++
)
{
fscanf
(
f
,
"%d %d %lg
\n
"
,
&
I
[
i
],
&
J
[
i
],
&
val
[
i
]);
I
[
i
]
--
;
/* adjust from 1-based to 0-based */
J
[
i
]
--
;
}
fclose
(
f
);
return
0
;
}
int
mm_is_valid
(
MM_typecode
matcode
)
{
if
(
!
mm_is_matrix
(
matcode
))
return
0
;
if
(
mm_is_dense
(
matcode
)
&&
mm_is_pattern
(
matcode
))
return
0
;
if
(
mm_is_real
(
matcode
)
&&
mm_is_hermitian
(
matcode
))
return
0
;
if
(
mm_is_pattern
(
matcode
)
&&
(
mm_is_hermitian
(
matcode
)
||
mm_is_skew
(
matcode
)))
return
0
;
return
1
;
}
int
mm_read_banner
(
FILE
*
f
,
MM_typecode
*
matcode
)
{
char
line
[
MM_MAX_LINE_LENGTH
];
char
banner
[
MM_MAX_TOKEN_LENGTH
];
char
mtx
[
MM_MAX_TOKEN_LENGTH
];
char
crd
[
MM_MAX_TOKEN_LENGTH
];
char
data_type
[
MM_MAX_TOKEN_LENGTH
];
char
storage_scheme
[
MM_MAX_TOKEN_LENGTH
];
char
*
p
;
mm_clear_typecode
(
matcode
);
if
(
fgets
(
line
,
MM_MAX_LINE_LENGTH
,
f
)
==
NULL
)
return
MM_PREMATURE_EOF
;
if
(
sscanf
(
line
,
"%s %s %s %s %s"
,
banner
,
mtx
,
crd
,
data_type
,
storage_scheme
)
!=
5
)
return
MM_PREMATURE_EOF
;
for
(
p
=
mtx
;
*
p
!=
'\0'
;
*
p
=
tolower
(
*
p
),
p
++
);
/* convert to lower case */
for
(
p
=
crd
;
*
p
!=
'\0'
;
*
p
=
tolower
(
*
p
),
p
++
);
for
(
p
=
data_type
;
*
p
!=
'\0'
;
*
p
=
tolower
(
*
p
),
p
++
);
for
(
p
=
storage_scheme
;
*
p
!=
'\0'
;
*
p
=
tolower
(
*
p
),
p
++
);
/* check for banner */
if
(
strncmp
(
banner
,
MatrixMarketBanner
,
strlen
(
MatrixMarketBanner
))
!=
0
)
return
MM_NO_HEADER
;
/* first field should be "mtx" */
if
(
strcmp
(
mtx
,
MM_MTX_STR
)
!=
0
)
return
MM_UNSUPPORTED_TYPE
;
mm_set_matrix
(
matcode
);
/* second field describes whether this is a sparse matrix (in coordinate
storgae) or a dense array */
if
(
strcmp
(
crd
,
MM_SPARSE_STR
)
==
0
)
mm_set_sparse
(
matcode
);
else
if
(
strcmp
(
crd
,
MM_DENSE_STR
)
==
0
)
mm_set_dense
(
matcode
);
else
return
MM_UNSUPPORTED_TYPE
;
/* third field */
if
(
strcmp
(
data_type
,
MM_REAL_STR
)
==
0
)
mm_set_real
(
matcode
);
else
if
(
strcmp
(
data_type
,
MM_COMPLEX_STR
)
==
0
)
mm_set_complex
(
matcode
);
else
if
(
strcmp
(
data_type
,
MM_PATTERN_STR
)
==
0
)
mm_set_pattern
(
matcode
);
else
if
(
strcmp
(
data_type
,
MM_INT_STR
)
==
0
)
mm_set_integer
(
matcode
);
else
return
MM_UNSUPPORTED_TYPE
;
/* fourth field */
if
(
strcmp
(
storage_scheme
,
MM_GENERAL_STR
)
==
0
)
mm_set_general
(
matcode
);
else
if
(
strcmp
(
storage_scheme
,
MM_SYMM_STR
)
==
0
)
mm_set_symmetric
(
matcode
);
else
if
(
strcmp
(
storage_scheme
,
MM_HERM_STR
)
==
0
)
mm_set_hermitian
(
matcode
);
else
if
(
strcmp
(
storage_scheme
,
MM_SKEW_STR
)
==
0
)
mm_set_skew
(
matcode
);
else
return
MM_UNSUPPORTED_TYPE
;
return
0
;
}
int
mm_write_mtx_crd_size
(
FILE
*
f
,
int
M
,
int
N
,
int
nz
)
{
if
(
fprintf
(
f
,
"%d %d %d
\n
"
,
M
,
N
,
nz
)
!=
3
)
return
MM_COULD_NOT_WRITE_FILE
;
else
return
0
;
}
int
mm_read_mtx_crd_size
(
FILE
*
f
,
int
*
M
,
int
*
N
,
int
*
nz
)
{
char
line
[
MM_MAX_LINE_LENGTH
];
int
num_items_read
;
/* set return null parameter values, in case we exit with errors */
*
M
=
*
N
=
*
nz
=
0
;
/* now continue scanning until you reach the end-of-comments */
do
{
if
(
fgets
(
line
,
MM_MAX_LINE_LENGTH
,
f
)
==
NULL
)
return
MM_PREMATURE_EOF
;
}
while
(
line
[
0
]
==
'%'
);
/* line[] is either blank or has M,N, nz */
if
(
sscanf
(
line
,
"%d %d %d"
,
M
,
N
,
nz
)
==
3
)
return
0
;
else
do
{
num_items_read
=
fscanf
(
f
,
"%d %d %d"
,
M
,
N
,
nz
);
if
(
num_items_read
==
EOF
)
return
MM_PREMATURE_EOF
;
}
while
(
num_items_read
!=
3
);
return
0
;
}
int
mm_read_mtx_array_size
(
FILE
*
f
,
int
*
M
,
int
*
N
)
{
char
line
[
MM_MAX_LINE_LENGTH
];
int
num_items_read
;
/* set return null parameter values, in case we exit with errors */
*
M
=
*
N
=
0
;
/* now continue scanning until you reach the end-of-comments */
do
{
if
(
fgets
(
line
,
MM_MAX_LINE_LENGTH
,
f
)
==
NULL
)
return
MM_PREMATURE_EOF
;
}
while
(
line
[
0
]
==
'%'
);
/* line[] is either blank or has M,N, nz */
if
(
sscanf
(
line
,
"%d %d"
,
M
,
N
)
==
2
)
return
0
;
else
/* we have a blank line */
do
{
num_items_read
=
fscanf
(
f
,
"%d %d"
,
M
,
N
);
if
(
num_items_read
==
EOF
)
return
MM_PREMATURE_EOF
;
}
while
(
num_items_read
!=
2
);
return
0
;
}
int
mm_write_mtx_array_size
(
FILE
*
f
,
int
M
,
int
N
)
{
if
(
fprintf
(
f
,
"%d %d
\n
"
,
M
,
N
)
!=
2
)
return
MM_COULD_NOT_WRITE_FILE
;
else
return
0
;
}
/*-------------------------------------------------------------------------*/
/******************************************************************/
/* use when I[], J[], and val[]J, and val[] are already allocated */
/******************************************************************/
int
mm_read_mtx_crd_data
(
FILE
*
f
,
int
M
,
int
N
,
int
nz
,
int
I
[],
int
J
[],
double
val
[],
MM_typecode
matcode
)
{
int
i
;
if
(
mm_is_complex
(
matcode
))
{
for
(
i
=
0
;
i
<
nz
;
i
++
)
if
(
fscanf
(
f
,
"%d %d %lg %lg"
,
&
I
[
i
],
&
J
[
i
],
&
val
[
2
*
i
],
&
val
[
2
*
i
+
1
])
!=
4
)
return
MM_PREMATURE_EOF
;
}
else
if
(
mm_is_real
(
matcode
))
{
for
(
i
=
0
;
i
<
nz
;
i
++
)
{
if
(
fscanf
(
f
,
"%d %d %lg
\n
"
,
&
I
[
i
],
&
J
[
i
],
&
val
[
i
])
!=
3
)
return
MM_PREMATURE_EOF
;
}
}
else
if
(
mm_is_pattern
(
matcode
))
{
for
(
i
=
0
;
i
<
nz
;
i
++
)
if
(
fscanf
(
f
,
"%d %d"
,
&
I
[
i
],
&
J
[
i
])
!=
2
)
return
MM_PREMATURE_EOF
;
}
else
return
MM_UNSUPPORTED_TYPE
;
return
0
;
}
int
mm_read_mtx_crd_entry
(
FILE
*
f
,
int
*
I
,
int
*
J
,
double
*
real
,
double
*
imag
,
MM_typecode
matcode
)
{
if
(
mm_is_complex
(
matcode
))
{
if
(
fscanf
(
f
,
"%d %d %lg %lg"
,
I
,
J
,
real
,
imag
)
!=
4
)
return
MM_PREMATURE_EOF
;
}
else
if
(
mm_is_real
(
matcode
))
{
if
(
fscanf
(
f
,
"%d %d %lg
\n
"
,
I
,
J
,
real
)
!=
3
)
return
MM_PREMATURE_EOF
;
}
else
if
(
mm_is_pattern
(
matcode
))
{
if
(
fscanf
(
f
,
"%d %d"
,
I
,
J
)
!=
2
)
return
MM_PREMATURE_EOF
;
}
else
return
MM_UNSUPPORTED_TYPE
;
return
0
;
}
/************************************************************************
mm_read_mtx_crd() fills M, N, nz, array of values, and return
type code, e.g. 'MCRS'
if matrix is complex, values[] is of size 2*nz,
(nz pairs of real/imaginary values)
************************************************************************/
int
mm_read_mtx_crd
(
char
*
fname
,
int
*
M
,
int
*
N
,
int
*
nz
,
int
**
I
,
int
**
J
,
double
**
val
,
MM_typecode
*
matcode
)
{
int
ret_code
;
FILE
*
f
;
if
(
strcmp
(
fname
,
"stdin"
)
==
0
)
f
=
stdin
;
else
if
((
f
=
fopen
(
fname
,
"r"
))
==
NULL
)
return
MM_COULD_NOT_READ_FILE
;
if
((
ret_code
=
mm_read_banner
(
f
,
matcode
))
!=
0
)
return
ret_code
;
if
(
!
(
mm_is_valid
(
*
matcode
)
&&
mm_is_sparse
(
*
matcode
)
&&
mm_is_matrix
(
*
matcode
)))
return
MM_UNSUPPORTED_TYPE
;
if
((
ret_code
=
mm_read_mtx_crd_size
(
f
,
M
,
N
,
nz
))
!=
0
)
return
ret_code
;
*
I
=
(
int
*
)
malloc
(
*
nz
*
sizeof
(
int
));
*
J
=
(
int
*
)
malloc
(
*
nz
*
sizeof
(
int
));
*
val
=
NULL
;
if
(
mm_is_complex
(
*
matcode
))
{
*
val
=
(
double
*
)
malloc
(
*
nz
*
2
*
sizeof
(
double
));
ret_code
=
mm_read_mtx_crd_data
(
f
,
*
M
,
*
N
,
*
nz
,
*
I
,
*
J
,
*
val
,
*
matcode
);
if
(
ret_code
!=
0
)
return
ret_code
;
}
else
if
(
mm_is_real
(
*
matcode
))
{
*
val
=
(
double
*
)
malloc
(
*
nz
*
sizeof
(
double
));
ret_code
=
mm_read_mtx_crd_data
(
f
,
*
M
,
*
N
,
*
nz
,
*
I
,
*
J
,
*
val
,
*
matcode
);
if
(
ret_code
!=
0
)
return
ret_code
;
}
else
if
(
mm_is_pattern
(
*
matcode
))
{
ret_code
=
mm_read_mtx_crd_data
(
f
,
*
M
,
*
N
,
*
nz
,
*
I
,
*
J
,
*
val
,
*
matcode
);
if
(
ret_code
!=
0
)
return
ret_code
;
}
if
(
f
!=
stdin
)
fclose
(
f
);
return
0
;
}
int
mm_write_banner
(
FILE
*
f
,
MM_typecode
matcode
)
{
char
*
str
=
mm_typecode_to_str
(
matcode
);
int
ret_code
;
ret_code
=
fprintf
(
f
,
"%s %s
\n
"
,
MatrixMarketBanner
,
str
);
free
(
str
);
if
(
ret_code
!=
2
)
return
MM_COULD_NOT_WRITE_FILE
;
else
return
0
;
}
int
mm_write_mtx_crd
(
char
fname
[],
int
M
,
int
N
,
int
nz
,
int
I
[],
int
J
[],
double
val
[],
MM_typecode
matcode
)
{
FILE
*
f
;
int
i
;
if
(
strcmp
(
fname
,
"stdout"
)
==
0
)
f
=
stdout
;
else
if
((
f
=
fopen
(
fname
,
"w"
))
==
NULL
)
return
MM_COULD_NOT_WRITE_FILE
;
/* print banner followed by typecode */
fprintf
(
f
,
"%s "
,
MatrixMarketBanner
);
fprintf
(
f
,
"%s
\n
"
,
mm_typecode_to_str
(
matcode
));
/* print matrix sizes and nonzeros */
fprintf
(
f
,
"%d %d %d
\n
"
,
M
,
N
,
nz
);
/* print values */
if
(
mm_is_pattern
(
matcode
))
for
(
i
=
0
;
i
<
nz
;
i
++
)
fprintf
(
f
,
"%d %d
\n
"
,
I
[
i
],
J
[
i
]);
else
if
(
mm_is_real
(
matcode
))
for
(
i
=
0
;
i
<
nz
;
i
++
)
fprintf
(
f
,
"%d %d %20.16g
\n
"
,
I
[
i
],
J
[
i
],
val
[
i
]);
else
if
(
mm_is_complex
(
matcode
))
for
(
i
=
0
;
i
<
nz
;
i
++
)
fprintf
(
f
,
"%d %d %20.16g %20.16g
\n
"
,
I
[
i
],
J
[
i
],
val
[
2
*
i
],
val
[
2
*
i
+
1
]);
else
{
if
(
f
!=
stdout
)
fclose
(
f
);
return
MM_UNSUPPORTED_TYPE
;
}
if
(
f
!=
stdout
)
fclose
(
f
);
return
0
;
}
/**
* Create a new copy of a string s. mm_strdup() is a common routine, but
* not part of ANSI C, so it is included here. Used by mm_typecode_to_str().
*
*/
char
*
mm_strdup
(
const
char
*
s
)
{
int
len
=
strlen
(
s
);
char
*
s2
=
(
char
*
)
malloc
((
len
+
1
)
*
sizeof
(
char
));
return
strcpy
(
s2
,
s
);
}
char
*
mm_typecode_to_str
(
MM_typecode
matcode
)
{
char
buffer
[
MM_MAX_LINE_LENGTH
];
char
*
types
[
4
];
char
*
mm_strdup
(
const
char
*
);
int
error
=
0
;
/* check for MTX type */
if
(
mm_is_matrix
(
matcode
))
types
[
0
]
=
MM_MTX_STR
;
else
error
=
1
;
/* check for CRD or ARR matrix */
if
(
mm_is_sparse
(
matcode
))
types
[
1
]
=
MM_SPARSE_STR
;
else
if
(
mm_is_dense
(
matcode
))
types
[
1
]
=
MM_DENSE_STR
;
else
return
NULL
;
/* check for element data type */
if
(
mm_is_real
(
matcode
))
types
[
2
]
=
MM_REAL_STR
;
else
if
(
mm_is_complex
(
matcode
))
types
[
2
]
=
MM_COMPLEX_STR
;
else
if
(
mm_is_pattern
(
matcode
))
types
[
2
]
=
MM_PATTERN_STR
;
else
if
(
mm_is_integer
(
matcode
))
types
[
2
]
=
MM_INT_STR
;
else
return
NULL
;
/* check for symmetry type */
if
(
mm_is_general
(
matcode
))
types
[
3
]
=
MM_GENERAL_STR
;
else
if
(
mm_is_symmetric
(
matcode
))
types
[
3
]
=
MM_SYMM_STR
;
else
if
(
mm_is_hermitian
(
matcode
))
types
[
3
]
=
MM_HERM_STR
;
else
if
(
mm_is_skew
(
matcode
))
types
[
3
]
=
MM_SKEW_STR
;
else
return
NULL
;
sprintf
(
buffer
,
"%s %s %s %s"
,
types
[
0
],
types
[
1
],
types
[
2
],
types
[
3
]);
return
mm_strdup
(
buffer
);
}
Event Timeline
Log In to Comment