Line data Source code
1 : /*
2 : * Copyright (c) 2012-2013: G-CSC, Goethe University Frankfurt
3 : * Author: Torbjörn Klatt
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : /**
34 : * \file mm_type_code.h
35 : * \author Torbjoern Klatt
36 : * \date 2012-05-06
37 : *
38 : * \details For some parts the implementation of a pure C library for the
39 : * MatrixMarket exchange format was used as a source of inspiration.
40 : * These can be found at http://math.nist.gov/MatrixMarket/mmio-c.html
41 : */
42 :
43 : #ifndef __H__UG__LIB_ALGEBRA__MM_TYPE_CODE_H
44 : #define __H__UG__LIB_ALGEBRA__MM_TYPE_CODE_H
45 :
46 : #include <string>
47 :
48 : #include "common/error.h"
49 :
50 : namespace ug
51 : {
52 :
53 : /// \addtogroup matrixio
54 : /// \{
55 :
56 : /**
57 : * \brief Type representation for MatrixMarket matrix exchange files
58 : */
59 : class MMTypeCode
60 : {
61 : public:
62 : /**
63 : * \brief Class type of the described matrix
64 : *
65 : * \note Only matrices in coordinate format are supported yet.
66 : */
67 : enum ClassType {
68 : COORDINATE = 1,
69 : ARRAY = 2 // TODO array/dense matrix not yet implemented
70 : };
71 :
72 : /**
73 : * \brief Numeric type of the described matrix
74 : *
75 : * \note Only real matrices are supported yet.
76 : */
77 : enum NumericType {
78 : REAL = 1,
79 : COMPLEX = 2, // TODO complex matrices not yet implemented
80 : INTEGER = 3, // TODO integer matrices not yet implemented
81 : PATTERN = 4 // TODO pattern matrices not yet implemented
82 : };
83 :
84 : /**
85 : * \brief Algebraic type of the described matrix
86 : *
87 : * \note Hermitian matrices are not yet supported.
88 : */
89 : enum AlgebraicType {
90 : GENERAL = 1,
91 : SYMMETRIC = 2,
92 : SKEW = 3,
93 : HERMITIAN = 4 // TODO hermitian matrices not yet implemented
94 : };
95 :
96 : /// Maximum line length in characters as defined by the MatrixMarket specifications
97 : static const int MM_LINE_LENGTH = 1025;
98 : #define MM_BANNER_STR "%%MatrixMarket"
99 : #define MM_MTX_STR "matrix"
100 : #define MM_COORDINATE_STR "coordinate"
101 : #define MM_SPARSE_STR "coordinate"
102 : #define MM_ARRAY_STR "array"
103 : #define MM_DENSE_STR "array"
104 : #define MM_REAL_STR "real"
105 : #define MM_COMPLEX_STR "complex"
106 : #define MM_INTEGER_STR "integer"
107 : #define MM_PATTERN_STR "pattern"
108 : #define MM_GENERAL_STR "general"
109 : #define MM_SYMMETRIC_STR "symmetric"
110 : #define MM_SKEW_STR "skew-symmetric"
111 : #define MM_HERMITIAN_STR "hermitian"
112 :
113 : private:
114 : /// Holds a value of MMTypeCode::ClassType (initialized with 0)
115 : int m_class_type;
116 : /// Holds a value of MMTypeCode::NumericType (initialized with 0)
117 : int m_numeric_type;
118 : /// Holds a value of MMTypeCode::AlgebraicType (initialized with 0)
119 : int m_algebraic_type;
120 :
121 : public:
122 : /**
123 : * \brief Default constructor
124 : *
125 : * Initializes all three types to \c 0, thus undefined.
126 : */
127 12 : MMTypeCode() :
128 12 : m_class_type( 0 ), m_numeric_type( 0 ), m_algebraic_type( 0 )
129 : {}
130 :
131 : /**
132 : * \brief Pretty prints the three classes and their current value.
133 : *
134 : * <tt>MatrixMarket Type Codes:
135 : * ClassType: {0,1,2}
136 : * NumericType: {0,1,2,3,4}
137 : * AlgebraicType: {0,1,2,3,4}
138 : * </tt>
139 : *
140 : * \return String
141 : *
142 : * \todo Display corresponding strings instead of internal numeric codes.
143 : */
144 : std::string to_string() {
145 : std::stringstream out;
146 : out << "MatrixMarket Type Codes:\n";
147 : out << " ClassType: " << m_class_type << "\n";
148 : out << " NumericType: " << m_numeric_type << "\n";
149 : out << " AlgebraicType: " << m_algebraic_type;
150 : return out.str();
151 : }
152 :
153 : /**
154 : * \brief Tells whether MMTypeCode is sparse
155 : *
156 : * \return \c true if \c ClassType is sparse (i.e. 1), \c false otherwise.
157 : */
158 : bool is_sparse() const {
159 13 : return ( m_class_type == COORDINATE );
160 : }
161 :
162 : /**
163 : * \brief Tells whether MMTypeCode is real
164 : *
165 : * \return \c true if \c NumericType is real (i.e. 1), \c false otherwise.
166 : */
167 : bool is_real() const {
168 : return ( m_numeric_type == REAL );
169 : }
170 :
171 : /**
172 : * \brief Tells whether MMTypeCode is general
173 : *
174 : * \return \c true if \c AlgebraicType is general (i.e. 1), \c false otherwise.
175 : */
176 : bool is_general() const {
177 3 : return ( m_algebraic_type == GENERAL );
178 : }
179 : /**
180 : * \brief Tells whether MMTypeCode is symmetric
181 : *
182 : * \return \c true if \c AlgebraicType is symmetric (i.e. 2), \c false otherwise.
183 : */
184 : bool is_symmetric() const {
185 15722 : return ( m_algebraic_type == SYMMETRIC );
186 : }
187 : /**
188 : * \brief Tells whether MMTypeCode is skew-symmetric
189 : *
190 : * \return \c true if \c AlgebraicType is skew-symmetric (i.e. 3), \c false otherwise.
191 : */
192 : bool is_skew_symmetric() const {
193 : return ( m_algebraic_type == SKEW );
194 : }
195 :
196 : /**
197 : * \brief Sets a new class type from an enum value
198 : *
199 : * \param[in] type One value of MMTypeCode::ClassType
200 : * \throws UGError if \c type is not a valid value
201 : */
202 3 : void set_class_type( int type ) {
203 3 : switch( type ) {
204 3 : case 1:
205 10 : m_class_type = COORDINATE;
206 3 : break;
207 0 : case 2:
208 0 : m_class_type = ARRAY;
209 0 : break;
210 0 : default:
211 0 : UG_THROW( "MatrixMarket Type code is invalid: " << type );
212 : }
213 10 : }
214 : /**
215 : * \brief Sets a new class type from a string
216 : *
217 : * \param[in] type a string either \c coordinate or \c array
218 : * \throws UGError if \c type is another string
219 : */
220 7 : void set_class_type( std::string type ) {
221 7 : if( type.compare( MM_COORDINATE_STR ) == 0 || type.compare( MM_SPARSE_STR ) == 0 ) {
222 : set_class_type( COORDINATE );
223 0 : } else if( type.compare( MM_ARRAY_STR ) == 0 || type.compare( MM_DENSE_STR ) == 0 ) {
224 : set_class_type( ARRAY );
225 : } else {
226 0 : UG_THROW( "MatrixMarket Type is invalid: " << type );
227 : }
228 7 : }
229 :
230 : /**
231 : * \brief Sets a new numeric type from an enum value
232 : *
233 : * \param[in] type One value of MMTypeCode::NumericType
234 : * \throws UGError if \c type is not a valid value
235 : */
236 3 : void set_numeric_type( int type ) {
237 3 : switch( type ) {
238 10 : case 1:
239 10 : m_numeric_type = REAL;
240 3 : break;
241 0 : case 2:
242 0 : m_numeric_type = COMPLEX;
243 0 : break;
244 0 : case 3:
245 0 : m_numeric_type = INTEGER;
246 0 : break;
247 0 : case 4:
248 0 : m_numeric_type = PATTERN;
249 0 : break;
250 0 : default:
251 0 : UG_THROW( "MatrixMarket numeric type code is invalid: " << type );
252 : }
253 10 : }
254 : /**
255 : * \brief Sets a new numeric type from a string
256 : *
257 : * \param[in] type a string either \c real, \c complex, \c integer or
258 : * \c pattern
259 : * \throws UGError if \c type is another string
260 : */
261 7 : void set_numeric_type( std::string type ) {
262 7 : if( type.compare( MM_REAL_STR ) == 0 ) {
263 : set_numeric_type( REAL );
264 0 : } else if( type.compare( MM_COMPLEX_STR ) == 0 ) {
265 : set_numeric_type( COMPLEX );
266 0 : } else if( type.compare( MM_INTEGER_STR ) == 0 ) {
267 : set_numeric_type( INTEGER );
268 0 : } else if( type.compare( MM_PATTERN_STR ) == 0 ) {
269 : set_numeric_type( PATTERN );
270 : } else {
271 0 : UG_THROW( "MatrixMarket numeric type is invalid: " << type );
272 : }
273 7 : }
274 :
275 : /**
276 : * \brief Sets a new algebraic type from an enum value
277 : *
278 : * \param[in] type One value of MMTypeCode::AlgebraicType
279 : * \throws UGError if \c type is not a valid value
280 : */
281 3 : void set_algebraic_type( int type ) {
282 3 : switch( type ) {
283 3 : case 1:
284 3 : m_algebraic_type = GENERAL;
285 1 : break;
286 4 : case 2:
287 4 : m_algebraic_type = SYMMETRIC;
288 1 : break;
289 3 : case 3:
290 3 : m_algebraic_type = SKEW;
291 1 : break;
292 0 : case 4:
293 0 : m_algebraic_type = HERMITIAN;
294 0 : break;
295 0 : default:
296 0 : UG_THROW( "MatrixMarket algebraic type code is invalid: " << type );
297 : }
298 10 : }
299 : /**
300 : * \brief Sets a new algebraic type from a string
301 : *
302 : * \param[in] type a string either \c general, \c symmetric,
303 : * \c skew-symmetric or \c hermitian
304 : * \throws UGError if \c type is another string
305 : */
306 7 : void set_algebraic_type( std::string type ) {
307 7 : if( type.compare( MM_GENERAL_STR ) == 0 ) {
308 : set_algebraic_type( GENERAL );
309 5 : } else if( type.compare( MM_SYMMETRIC_STR ) == 0 ) {
310 : set_algebraic_type( SYMMETRIC );
311 2 : } else if( type.compare( MM_SKEW_STR ) == 0 ) {
312 : set_algebraic_type( SKEW );
313 0 : } else if( type.compare( MM_HERMITIAN_STR ) == 0 ) {
314 : set_algebraic_type( HERMITIAN );
315 : } else {
316 0 : UG_THROW( "MatrixMarket algebraic type is invalid: " << type );
317 : }
318 7 : }
319 : };
320 :
321 : // end group matrixio
322 : /// \}
323 :
324 : } // namespace ug
325 :
326 : #endif // __H__UG__LIB_ALGEBRA__MM_TYPE_CODE_H
327 :
328 : // EOF
|