Branch data Line data Source code
1 : : /*!
2 : : * \class matrixtemplate
3 : : * \brief for engineering style matrix starting from 1
4 : : *
5 : : **/
6 : : #ifndef __MESHKIT_MATRIXTEMPLATE_H__
7 : : #define __MESHKIT_MATRIXTEMPLATE_H__
8 : :
9 : : #include <string>
10 : : #include <iostream>
11 : : #include <fstream>
12 : : #include <cassert>
13 : : #include <cmath>
14 : : #include <stdlib.h>
15 : :
16 : : // defines the Matrix class
17 : : template <class T>
18 : : class CMatrix
19 : : #ifdef __RGGMETER
20 : : : public CArrayBase
21 : : #endif
22 : : {
23 : : private:
24 : : T **m_pCells; // address where the matrix of
25 : : // type T is stored
26 : : int m_nRows; // number of rows in the matrix
27 : : int m_nColumns; // number of columns in the matrix
28 : : std::string m_szName; // matrix name
29 : : void ErrorHandler (int,int nR=0, int nC=0) const;
30 : : // handles error conditions
31 : : void Release (); // similar to destructor
32 : :
33 : : public:
34 : : CMatrix (); // default constructor
35 : : CMatrix (int, int); // constructor
36 : : CMatrix (const char *); // constructor
37 : : CMatrix (const char *, int, int); // constructor
38 : : CMatrix (const CMatrix<T>&); // copy constructor
39 : : ~CMatrix (); // destructor
40 : : void SetSize (int, int); // sets the size of the matrix
41 : : // used with the default constructor
42 : :
43 : : // helper functions
44 : : int GetRows () const; // gets the current number of rows
45 : : int GetColumns () const; // gets the current number of columns
46 : : void GetName (std::string&) const; // gets the matrix name
47 : :
48 : : // matrix manipulations (mutator)
49 : : void Set (T); // sets the value of all elements
50 : : // of a matrix
51 : : void SetName (const std::string&); // sets the matrix name
52 : : T& operator() (int, int); // row-col access
53 : : const T& operator() (int, int) const; // row-col access
54 : : T& operator= (const CMatrix&); // overloaded = operator
55 : : int Read (std::ifstream& IFile);
56 : : };
57 : :
58 : : // =============== definitions ===========================================
59 : : template <class T>
60 : 32 : CMatrix<T>::CMatrix ()
61 : : // ---------------------------------------------------------------------------
62 : : // Function: default ctor
63 : : // Input: none
64 : : // Output: none
65 : : // ---------------------------------------------------------------------------
66 : : {
67 : 16 : m_pCells = NULL;
68 : 16 : m_nRows = 0;
69 : 16 : m_nColumns = 0;
70 : 16 : }
71 : :
72 : : template <class T>
73 : 0 : CMatrix<T>::CMatrix (int nR, int nC)
74 : : // ---------------------------------------------------------------------------
75 : : // Function: overloaded ctor
76 : : // Input: # of rows and columns
77 : : // Output: none
78 : : // ---------------------------------------------------------------------------
79 : : {
80 : 0 : m_pCells = NULL;
81 [ # # ]: 0 : SetSize (nR, nC);
82 : 0 : }
83 : :
84 : : template <class T>
85 : : CMatrix<T>::CMatrix (const char* szName)
86 : : // ---------------------------------------------------------------------------
87 : : // Function: overloaded ctor
88 : : // Input: matrix name
89 : : // Output: none
90 : : // ---------------------------------------------------------------------------
91 : : {
92 : : m_pCells = NULL;
93 : : m_szName = szName;
94 : : m_nRows = 0;
95 : : m_nColumns = 0;
96 : : }
97 : :
98 : : template <class T>
99 : : CMatrix<T>::CMatrix (const char* szName, int nR, int nC)
100 : : // ---------------------------------------------------------------------------
101 : : // Function: overloaded ctor
102 : : // Input: matrix name, # of rows and columns
103 : : // Output: none
104 : : // ---------------------------------------------------------------------------
105 : : {
106 : : m_pCells = NULL;
107 : : m_szName = szName;
108 : : SetSize (nR, nC);
109 : : }
110 : :
111 : : template <class T>
112 : 32 : CMatrix<T>::CMatrix (const CMatrix<T>& A)
113 : : // ---------------------------------------------------------------------------
114 : : // Function: copy ctor
115 : : // Input: matrix
116 : : // Output: none
117 : : // ---------------------------------------------------------------------------
118 : : {
119 : 16 : m_pCells = NULL;
120 : 16 : m_nRows = A.m_nRows;
121 : 16 : m_nColumns = A.m_nColumns;
122 [ + - ]: 16 : m_szName = A.m_szName;
123 [ + - ]: 16 : SetSize (m_nRows, m_nColumns);
124 [ + + ]: 80 : for (int i=1; i <= m_nRows; i++)
125 : : {
126 [ + + ]: 320 : for (int j=1; j <= m_nColumns; j++)
127 : : {
128 [ + - ]: 256 : m_pCells[i][j] = A.m_pCells[i][j];
129 : : }
130 : : }
131 : 16 : }
132 : :
133 : : template <class T>
134 : 27 : void CMatrix<T>::SetSize (int nR, int nC)
135 : : // ---------------------------------------------------------------------------
136 : : // Function: dynamically allocates memory
137 : : // Input: matrix size (# of rows and columns)
138 : : // Output: none
139 : : // ---------------------------------------------------------------------------
140 : : {
141 : : // check whether nR and nC are legal
142 [ + - ][ - + ]: 27 : if (nR <= 0 || nC <= 0)
[ + - ][ - + ]
143 : 0 : ErrorHandler (3);
144 : 27 : Release ();
145 : 27 : int size = nR*nC + 1;
146 [ + - ][ + - ]: 27 : try {m_pCells = new T *[nR + 1];}
[ + - ][ + - ]
147 [ # # # # : 0 : catch (std::bad_alloc) {ErrorHandler (1);}
# # # # #
# ]
148 [ + - ][ + - ]: 322 : try {m_pCells[0] = new T[size];}
[ + - ][ + + ]
[ # # ][ + - ]
[ + - ]
149 [ # # # # : 0 : catch (std::bad_alloc) {ErrorHandler (1);}
# # # # ]
150 : 27 : m_pCells[1] = m_pCells[0];
151 [ + + ][ - + ]: 78 : for (int i=2; i <= nR; i++)
152 : 51 : m_pCells[i] = m_pCells[i-1]+nC;
153 : 27 : m_nRows = nR;
154 : 27 : m_nColumns = nC;
155 : : #ifdef __RGGMETER
156 : : m_dAllocated += static_cast<double>(sizeof(T*)*(nR+1));
157 : : m_dAllocated += static_cast<double>(sizeof(T)*size);
158 : : #endif
159 : 27 : }
160 : :
161 : : template <class T>
162 : 32 : CMatrix<T>::~CMatrix ()
163 : : // ---------------------------------------------------------------------------
164 : : // Function: dtor
165 : : // Input: none
166 : : // Output: none
167 : : // ---------------------------------------------------------------------------
168 : : {
169 : : // deallocate storage
170 [ + + ][ + + ]: 32 : if (m_pCells != NULL)
171 : : {
172 [ + - ][ + - ]: 322 : delete [] m_pCells[0];
[ + + ]
173 : 27 : m_pCells[0] = NULL;
174 : : #ifdef __RGGMETER
175 : : m_dDeAllocated += static_cast<double>(sizeof(T*)*(m_nRows+1));
176 : : #endif
177 : : }
178 [ + + ][ + + ]: 32 : if (m_pCells != NULL)
179 : : {
180 [ + - ][ + - ]: 27 : delete [] m_pCells;
181 : 27 : m_pCells = NULL;
182 : : #ifdef __RGGMETER
183 : : int nSize = m_nRows*m_nColumns+1;
184 : : m_dDeAllocated += static_cast<double>(sizeof(T)*nSize);
185 : : #endif
186 : : }
187 : 32 : m_nRows = 0;
188 : 32 : m_nColumns = 0;
189 : 32 : }
190 : :
191 : : template <class T>
192 : 27 : void CMatrix<T>::Release ()
193 : : // ---------------------------------------------------------------------------
194 : : // Function: dynamically deallocates memory
195 : : // Input: none
196 : : // Output: none
197 : : // ---------------------------------------------------------------------------
198 : : {
199 : : // deallocate storage
200 [ - + ][ - + ]: 27 : if (m_pCells != NULL)
201 : : {
202 [ # # ][ # # ]: 0 : delete [] m_pCells[0];
[ # # ]
203 : : #ifdef __RGGMETER
204 : : m_dDeAllocated += static_cast<double>(sizeof(T*)*(m_nRows+1));
205 : : #endif
206 : : }
207 [ - + ][ - + ]: 27 : if (m_pCells != NULL)
208 : : {
209 [ # # ][ # # ]: 0 : delete [] m_pCells;
210 : : #ifdef __RGGMETER
211 : : int nSize = m_nRows*m_nColumns+1;
212 : : m_dDeAllocated += static_cast<double>(sizeof(T)*nSize);
213 : : #endif
214 : : }
215 : 27 : m_pCells = NULL;
216 : 27 : m_nRows = 0;
217 : 27 : m_nColumns = 0;
218 : 27 : }
219 : :
220 : : // =============== member functions ===========================================
221 : : template <class T>
222 : : void CMatrix<T>::SetName (const std::string& szName)
223 : : // ---------------------------------------------------------------------------
224 : : // Function: sets the name of the matrix
225 : : // Input: matrix name
226 : : // Output: none
227 : : // ---------------------------------------------------------------------------
228 : : {
229 : : m_szName = szName;
230 : : }
231 : :
232 : : template <class T>
233 : : void CMatrix<T>::GetName (std::string& szName) const
234 : : // ---------------------------------------------------------------------------
235 : : // Function: gets the name of the matrix
236 : : // Input: string to hold matrix name
237 : : // Output: matrix name
238 : : // ---------------------------------------------------------------------------
239 : : {
240 : : szName = m_szName;
241 : : }
242 : :
243 : : template <class T>
244 : 4 : int CMatrix<T>::GetRows () const
245 : : // ---------------------------------------------------------------------------
246 : : // Function: gets the # of rows in the matrix
247 : : // Input: none
248 : : // Output: # of rows
249 : : // ---------------------------------------------------------------------------
250 : : {
251 : 4 : return (m_nRows);
252 : : }
253 : :
254 : : template <class T>
255 : 0 : int CMatrix<T>::GetColumns () const
256 : : // ---------------------------------------------------------------------------
257 : : // Function: gets the # of columns in the matrix
258 : : // Input: none
259 : : // Output: # of columns
260 : : // ---------------------------------------------------------------------------
261 : : {
262 : 0 : return (m_nColumns);
263 : : }
264 : :
265 : : template <class T>
266 : 0 : void CMatrix<T>::Set (T dV)
267 : : // ---------------------------------------------------------------------------
268 : : // Function: sets the value of all the elements in the matrix to the
269 : : // specified value
270 : : // Input: specified value
271 : : // Output: none
272 : : // ---------------------------------------------------------------------------
273 : : {
274 [ # # ]: 0 : for (int i=1; i <= m_nRows; i++)
275 : : {
276 [ # # ]: 0 : for (int j=1; j <= m_nColumns; j++)
277 : : {
278 : 0 : m_pCells[i][j] = dV; // or, (*this)(i,j) = dV;
279 : : }
280 : : }
281 : 0 : }
282 : :
283 : : // ==================== Overloaded Operators ========================
284 : : template <class T>
285 : 209 : T& CMatrix<T>::operator() (int nR, int nC)
286 : : // ---------------------------------------------------------------------------
287 : : // Function: overloaded () operator to access matrix contents
288 : : // carries out bound checking
289 : : // Input: row and column indices
290 : : // Output: value at the specified indices
291 : : // ---------------------------------------------------------------------------
292 : : {
293 : : #ifdef _DEBUG
294 : : if (nR <= 0 || nR > m_nRows || nC <= 0 || nC > m_nColumns)
295 : : {
296 : : ErrorHandler (2,nR,nC);
297 : : return m_pCells[1][1];
298 : : }
299 : : else
300 : : return m_pCells[nR][nC];
301 : : #else
302 : 209 : return m_pCells[nR][nC];
303 : : #endif
304 : : }
305 : :
306 : : template <class T>
307 : : const T& CMatrix<T>::operator() (int nR, int nC) const
308 : : // ---------------------------------------------------------------------------
309 : : // Function: overloaded () operator to access matrix contents
310 : : // carries out bound checking
311 : : // Input: row and column indices
312 : : // Output: value at the specified indices
313 : : // ---------------------------------------------------------------------------
314 : : {
315 : : #ifdef _DEBUG
316 : : if (nR <= 0 || nR > m_nRows || nC <= 0 || nC > m_nColumns)
317 : : {
318 : : ErrorHandler (2,nR,nC);
319 : : return m_pCells[1][1];
320 : : }
321 : : else
322 : : return m_pCells[nR][nC];
323 : : #else
324 : : return m_pCells[nR][nC];
325 : : #endif
326 : : }
327 : :
328 : : template <class T>
329 : : T& CMatrix<T>::operator= (const CMatrix& matarg)
330 : : // ---------------------------------------------------------------------------
331 : : // Function: overloaded = operator
332 : : // Input: matrix to use as rvalue
333 : : // Output: modified values
334 : : // ---------------------------------------------------------------------------
335 : : {
336 : : // check whether matrix is assigned to itself
337 : : if (this != &matarg)
338 : : {
339 : : // compatible matrices?
340 : : if (m_nRows != matarg.m_nRows || m_nColumns != matarg.m_nColumns)
341 : : {
342 : : ErrorHandler (4);
343 : : return (T&)(*this);
344 : : }
345 : : // now copy
346 : : for (int i=1; i <= matarg.m_nRows; i++)
347 : : {
348 : : for (int j=1; j <= matarg.m_nColumns; j++)
349 : : {
350 : : m_pCells[i][j]= matarg.m_pCells[i][j];
351 : : }
352 : : }
353 : : }
354 : :
355 : : return (T&)(*this);
356 : : }
357 : :
358 : : template <class T>
359 : : int CMatrix<T>::Read (std::ifstream& IFile)
360 : : // ---------------------------------------------------------------------------
361 : : // Function: Reads a matrix rowwise
362 : : // Input: input stream to read from
363 : : // Output: the modified matrix
364 : : // ---------------------------------------------------------------------------
365 : : {
366 : : // read matrix size
367 : : int m_nRowsI, nColsI;
368 : : IFile >> m_nRowsI >> nColsI;
369 : : if (m_nRowsI <= 0 || nColsI <= 0)
370 : : return 1;
371 : : if (IFile.eof() || IFile.fail())
372 : : return 1;
373 : :
374 : : // reallocate?
375 : : if (m_nRows != m_nRowsI || m_nColumns != nColsI)
376 : : SetSize (m_nRowsI, nColsI);
377 : :
378 : : T v;
379 : :
380 : : for (int i=1; i <= m_nRows; i++)
381 : : {
382 : : for (int j=1; j <= m_nColumns; j++)
383 : : {
384 : : IFile >> v;
385 : : m_pCells[i][j] = v;
386 : : if (IFile.eof() || IFile.fail())
387 : : return 1;
388 : : }
389 : : }
390 : :
391 : : return 0;
392 : : }
393 : :
394 : : // ==================== Error Handler ========================
395 : : template <class T>
396 : 0 : void CMatrix<T>::ErrorHandler (int nErrorCode, int nR, int nC) const
397 : : // ---------------------------------------------------------------------------
398 : : // Function: channels error message via std:err
399 : : // Input: error code and optional int value
400 : : // Output: none
401 : : // ---------------------------------------------------------------------------
402 : : {
403 : 0 : std::cerr << "CMatrix: Matrix Name: " << m_szName << ".\n";
404 [ # # # # : 0 : switch (nErrorCode)
# # # # #
# ]
405 : : {
406 : : case 1:
407 : 0 : std::cerr << "Matrix:: Memory allocation failure.\n";
408 : 0 : break;
409 : : case 2:
410 : 0 : std::cerr << "Matrix::Row-Column reference is out of bounds.\n";
411 : 0 : break;
412 : : case 3:
413 : 0 : std::cerr << "Matrix::Constructor. Invalid number of rows "
414 : : "or columns.\n";
415 : 0 : break;
416 : : case 4:
417 : 0 : std::cerr << "Matrix::Incompatible matrices.\n";
418 : 0 : break;
419 : : }
420 : 0 : std::cerr << "Unable to populate matrix.\n";
421 : 0 : exit (1);
422 : : }
423 : :
424 : : #endif
|