Subversion Repositories gelsvn

Rev

Rev 58 | Rev 595 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 58 Rev 89
1
#if !defined(MATRIX_H_HAA_AGUST_2001)
1
#if !defined(MATRIX_H_HAA_AGUST_2001)
2
#define MATRIX_H_HAA_AGUST_2001
2
#define MATRIX_H_HAA_AGUST_2001
3
 
3
 
4
#include <cassert>
4
#include <cassert>
5
#include <iostream>
5
#include <iostream>
6
#include <cmath>
6
#include <cmath>
7
#include "Vector.h"
7
#include "Vector.h"
8
#include "CGLA/ArithMatFloat.h"
8
#include "CGLA/ArithMatFloat.h"
9
 
9
 
10
/*!
-
 
11
	\namespace<LinAlg>
-
 
12
	\brief The Linear Algebra Implementation/Module/Package. 
-
 
13
 
-
 
14
  This is the linear algebra package deal with vector and matrix types plus 
-
 
15
  the basic operation on them. The Vector and Matrix Types are templated such 
-
 
16
  that the precision of a given 'system' can be changen. Though the precision 
-
 
17
  or type in mind is the double. Special types for 2 and 3 vectors 
-
 
18
  (CVec2 and CVec3) are included for improved performance. The more advanced 
-
 
19
  linear algebra functions are supplied by lincage to the LaPack package.
-
 
20
 
-
 
21
  \test The functionality in this pacage has if nothing else is mentioned 
-
 
22
  been tested by making small functions utilizing the functions. The 
-
 
23
  reason being that the functions here are rather esay to validate due to 
-
 
24
  their functional simplicity.
-
 
25
 
-
 
26
	A list of improvements in mind is:
-
 
27
	- Lapack interface
-
 
28
	- Vector and Matrix product and so on, with interface to _BLAS_
-
 
29
	- iterator thing
-
 
30
	- Memory leak check ? inline ?
-
 
31
	- Element functor
-
 
32
	- Identity matrixs
-
 
33
	- Compile and utilize the newer versions of the Lapack routines.
-
 
34
	- Have a nameing convention section in the documentaion
-
 
35
	- Integrate the design into the documentation
-
 
36
	- Have a get data in the matrix and vector instead of &A[0].
-
 
37
	- Have 3x3, 3x4 4x1 and 4x4 specialities.
-
 
38
	- Look at casting e.g. vec2i=vec2l.
-
 
39
	- Error handling in From/To matrix
-
 
40
	- Has error handling in Lapack been made ?
-
 
41
 
-
 
42
	\author Henrik Aanæs
-
 
43
	\version Aug 2001
-
 
44
*/
-
 
45
namespace LinAlg
10
namespace LinAlg
46
{
11
{
47
 
12
 
48
	/*!
13
	/*!
49
		\file Matrix.h
14
		\file Matrix.h
50
		\brief The Matrix type
15
		\brief The Matrix type
51
	*/
16
	*/
52
 
17
 
53
 
18
 
54
	/*!
19
	/*!
55
		\brief The Matrix type.
20
		\brief The Matrix type.
56
 
21
 
57
		This matrix teplate is one of the basic linear algebra types. In 
22
		This matrix teplate is one of the basic linear algebra types. In 
58
		principle it an overloaded Array of type T. The typedef Matrix with 
23
		principle it an overloaded Array of type T. The typedef Matrix with 
59
		T set to double
24
		T set to double
60
 
25
 
61
		typedef CMatrixType<double> CMatrix;
26
		typedef CMatrixType<double> CMatrix;
62
 
27
 
63
		is the delclaration intended to be used as the matrix type outside 
28
		is the delclaration intended to be used as the matrix type outside 
64
		the this and related files. The reson for making a template is 
29
		the this and related files. The reson for making a template is 
65
		twofold, first it allows for an esay change of precision in this
30
		twofold, first it allows for an esay change of precision in this
66
		linear algebre package. Secondly it allows for other MAtrix types 
31
		linear algebre package. Secondly it allows for other MAtrix types 
67
		in special cases.
32
		in special cases.
68
 
33
 
69
		The data structure consists of the array of type T, T* Data, 
34
		The data structure consists of the array of type T, T* Data, 
70
		with the Ilife vector, T** Ilife, refering to the begining 
35
		with the Ilife vector, T** Ilife, refering to the begining 
71
		of each of the columns. Hereby a coherent data area is avalable and 
36
		of each of the columns. Hereby a coherent data area is avalable and 
72
		the concept of 2-dimensionality is acheived by the Ilife vector. The 
37
		the concept of 2-dimensionality is acheived by the Ilife vector. The 
73
		pointer to the data area can be obtained by operator [] (int i) 
38
		pointer to the data area can be obtained by operator [] (int i) 
74
		with i=0, e.g. 
39
		with i=0, e.g. 
75
 
40
 
76
		Matrix A;
41
		Matrix A;
77
 
42
 
78
		T* pData=A[0];  
43
		T* pData=A[0];  
79
 
44
 
80
		will  make pData point to the data.
45
		will  make pData point to the data.
81
 
46
 
82
		It should be noted that much of the functionality associated with this
47
		It should be noted that much of the functionality associated with this
83
		Matrix type and the associated Vector type is located in the 
48
		Matrix type and the associated Vector type is located in the 
84
		LapackFunc.h file.
49
		LapackFunc.h file.
85
 
50
 
86
		\see LapackFunc.h
51
		\see LapackFunc.h
87
		\see CVectorType  
52
		\see CVectorType  
88
		\see Additional matrix operators (Located in this file Matrix.h).
53
		\see Additional matrix operators (Located in this file Matrix.h).
89
		\see CMatrix
54
		\see CMatrix
90
		\see CVector
55
		\see CVector
91
		\see CVec2Type
56
		\see CVec2Type
92
		\see CVec3Type
57
		\see CVec3Type
93
		\see CVec2
58
		\see CVec2
94
		\see CVec3
59
		\see CVec3
95
 
60
 
96
		\author Henrik Aanæs
61
		\author Henrik Aanæs
97
		\version Aug 2001
62
		\version Aug 2001
98
	*/
63
	*/
99
	template <class T>
64
	template <class T>
100
	class CMatrixType 
65
	class CMatrixType 
101
	{
66
	{
102
		friend class CVectorType<T>;
67
		friend class CVectorType<T>;
103
 
68
 
104
	private:
69
	private:
105
		///The number of rows in the matrix
70
		///The number of rows in the matrix
106
		int nRows;
71
		int nRows;
107
		///The number of columns in the matrix
72
		///The number of columns in the matrix
108
		int nCols;
73
		int nCols;
109
		/// The number of elements in the matrix, i.e. nElems=nRows*nCols.
74
		/// The number of elements in the matrix, i.e. nElems=nRows*nCols.
110
		int nElems;
75
		int nElems;
111
		///The pointer to the data containing the elements of the matrix.
76
		///The pointer to the data containing the elements of the matrix.
112
		T* Data;
77
		T* Data;
113
		///The Ilife vector containing pointers to the start of the columns. That is pointers to elements in Data.
78
		///The Ilife vector containing pointers to the start of the columns. That is pointers to elements in Data.
114
		T** Ilife;
79
		T** Ilife;
115
	
80
	
116
		///Sets all the elements in the matrix to Scalar.
81
		///Sets all the elements in the matrix to Scalar.
117
		void SetScalar(const T& Scalar) 
82
		void SetScalar(const T& Scalar) 
118
		{
83
		{
119
			T* Itt=Data;
84
			T* Itt=Data;
120
			T* Stop=&(Data[nElems]);
85
			T* Stop=&(Data[nElems]);
121
			while(Itt!=Stop)
86
			while(Itt!=Stop)
122
				{
87
				{
123
					*Itt=Scalar;
88
					*Itt=Scalar;
124
					++Itt;
89
					++Itt;
125
				}
90
				}
126
		} 
91
		} 
127
	
92
	
128
		///Clears the allocated memory.
93
		///Clears the allocated memory.
129
		void CleanUp(void)
94
		void CleanUp(void)
130
		{
95
		{
131
			if(Data!=NULL) 
96
			if(Data!=NULL) 
132
				delete [] Data; 
97
				delete [] Data; 
133
			if(Ilife!=NULL) 
98
			if(Ilife!=NULL) 
134
				delete [] Ilife;
99
				delete [] Ilife;
135
		};
100
		};
136
	
101
	
137
		///Allocates memory. Note that nRows,nCols and nElems should be set first.
102
		///Allocates memory. Note that nRows,nCols and nElems should be set first.
138
		void Allocate(void)
103
		void Allocate(void)
139
		{ 
104
		{ 
140
			Data= new T[nElems]; 
105
			Data= new T[nElems]; 
141
			Ilife=new T*[nRows];	
106
			Ilife=new T*[nRows];	
142
			for(int cRow=0;cRow<nRows;cRow++) 
107
			for(int cRow=0;cRow<nRows;cRow++) 
143
				Ilife[cRow]=&Data[cRow*nCols];
108
				Ilife[cRow]=&Data[cRow*nCols];
144
		};
109
		};
145
	
110
	
146
	public:
111
	public:
147
		///	\name The Constructors and Destructors of the CMatrixType class.
112
		///	\name The Constructors and Destructors of the CMatrixType class.
148
		//@{
113
		//@{
149
		CMatrixType<T>() : nRows(0),nCols(0),nElems(0),Data(NULL),Ilife(NULL) {};
114
		CMatrixType<T>() : nRows(0),nCols(0),nElems(0),Data(NULL),Ilife(NULL) {};
150
 
115
 
151
		CMatrixType<T>(const int Row,const int Col) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate();}
116
		CMatrixType<T>(const int Row,const int Col) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate();}
152
 
117
 
153
		CMatrixType<T>(const int Row,const int Col,const T& Scalar) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate(); SetScalar(Scalar);};
118
		CMatrixType<T>(const int Row,const int Col,const T& Scalar) : nRows(Row),nCols(Col),nElems(Row*Col) {Allocate(); SetScalar(Scalar);};
154
 
119
 
155
		CMatrixType<T>(const CMatrixType<T>& Rhs) : nRows(Rhs.nRows),nCols(Rhs.nCols),nElems(Rhs.nRows*Rhs.nCols) 
120
		CMatrixType<T>(const CMatrixType<T>& Rhs) : nRows(Rhs.nRows),nCols(Rhs.nCols),nElems(Rhs.nRows*Rhs.nCols) 
156
		{ 
121
		{ 
157
			Allocate();
122
			Allocate();
158
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
123
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
159
		}
124
		}
160
 
125
 
161
		template <class VVT, class HVT, class MT, unsigned int ROWS>
126
		template <class VVT, class HVT, class MT, unsigned int ROWS>
162
		CMatrixType<T>(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs): 
127
		CMatrixType<T>(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs): 
163
			nRows(Rhs.get_v_dim()),nCols(Rhs.get_h_dim()),
128
			nRows(Rhs.get_v_dim()),nCols(Rhs.get_h_dim()),
164
			nElems(nRows*nCols) 
129
			nElems(nRows*nCols) 
165
		{ 
130
		{ 
166
			Allocate();
131
			Allocate();
167
			for(int i=0;i<nElems;++i)
132
			for(int i=0;i<nElems;++i)
168
				Data[i] = Rhs.get()[i];
133
				Data[i] = Rhs.get()[i];
169
		}
134
		}
170
 
135
 
171
		CMatrixType<T>(const CVectorType<T>& Rhs) : nRows(Rhs.Length()),nCols(1),nElems(Rhs.Length()) 
136
		CMatrixType<T>(const CVectorType<T>& Rhs) : nRows(Rhs.Length()),nCols(1),nElems(Rhs.Length()) 
172
		{ 
137
		{ 
173
			Allocate();
138
			Allocate();
174
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
139
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
175
		}
140
		}
176
		virtual ~CMatrixType<T>(){CleanUp();};
141
		virtual ~CMatrixType<T>(){CleanUp();};
177
		//@}
142
		//@}
178
 
143
 
179
		/*!
144
		/*!
180
			\name	Asignment opertors.
145
			\name	Asignment opertors.
181
			The assignment operators of the CMatrixType class.
146
			The assignment operators of the CMatrixType class.
182
			Note that the matrix is resized if it does not have the correct size.
147
			Note that the matrix is resized if it does not have the correct size.
183
		*/
148
		*/
184
		//@{
149
		//@{
185
		CMatrixType<T>& operator=(const T& Rhs){ SetScalar(Rhs);return *this;}
150
		CMatrixType<T>& operator=(const T& Rhs){ SetScalar(Rhs);return *this;}
186
 
151
 
187
    CMatrixType<T>& operator=(const CMatrixType<T>& Rhs)
152
    CMatrixType<T>& operator=(const CMatrixType<T>& Rhs)
188
		{ 
153
		{ 
189
			Resize(Rhs.nRows,Rhs.nCols); 
154
			Resize(Rhs.nRows,Rhs.nCols); 
190
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
155
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
191
			return *this;
156
			return *this;
192
		}
157
		}
193
 
158
 
194
		template <class VVT, class HVT, class MT, unsigned int ROWS>
159
		template <class VVT, class HVT, class MT, unsigned int ROWS>
195
		CMatrixType<T>& operator=(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs)
160
		CMatrixType<T>& operator=(const CGLA::ArithMatFloat<VVT,HVT,MT,ROWS>& Rhs)
196
		{ 
161
		{ 
197
			Resize(Rhs.get_v_dim(),Rhs.get_h_dim()); 
162
			Resize(Rhs.get_v_dim(),Rhs.get_h_dim()); 
198
			for(int i=0;i<nElems;++i)
163
			for(int i=0;i<nElems;++i)
199
				Data[i] = Rhs.get()[i];
164
				Data[i] = Rhs.get()[i];
200
			return *this;
165
			return *this;
201
		}
166
		}
202
 
167
 
203
		CMatrixType<T>& operator=(const CVectorType<T>&Rhs)
168
		CMatrixType<T>& operator=(const CVectorType<T>&Rhs)
204
		{
169
		{
205
			Resize(Rhs.Lenght(),1);
170
			Resize(Rhs.Lenght(),1);
206
			memcpy(Data,Rhs.Dat,nElems*sizeof(T));
171
			memcpy(Data,Rhs.Dat,nElems*sizeof(T));
207
			return *this;
172
			return *this;
208
		}
173
		}
209
		//@}
174
		//@}
210
 
175
 
211
 
176
 
212
		/*!
177
		/*!
213
			\name Dimension functions.
178
			\name Dimension functions.
214
			Functions dealing with the dimension of the matrix.
179
			Functions dealing with the dimension of the matrix.
215
		*/
180
		*/
216
		//@{
181
		//@{
217
		/// Returns the number of rows in the matrix
182
		/// Returns the number of rows in the matrix
218
		const int Rows(void) const {return nRows;};
183
		const int Rows(void) const {return nRows;};
219
		///Retruns the number of columns in the matrix. 
184
		///Retruns the number of columns in the matrix. 
220
		const int Cols(void) const {return nCols;};
185
		const int Cols(void) const {return nCols;};
221
		/// Resizes the matrix IF it does not already have the desired dimensions.
186
		/// Resizes the matrix IF it does not already have the desired dimensions.
222
		void Resize(const int Row,const int Col)
187
		void Resize(const int Row,const int Col)
223
		{
188
		{
224
			if(Row!=nRows || Col!=nCols)
189
			if(Row!=nRows || Col!=nCols)
225
				{
190
				{
226
					CleanUp();
191
					CleanUp();
227
					nRows=Row;
192
					nRows=Row;
228
					nCols=Col;
193
					nCols=Col;
229
					nElems=Row*Col;
194
					nElems=Row*Col;
230
					Data= new T[nElems];
195
					Data= new T[nElems];
231
					Ilife=new T*[nRows];
196
					Ilife=new T*[nRows];
232
					for(int cRow=0;cRow<nRows;cRow++)
197
					for(int cRow=0;cRow<nRows;cRow++)
233
						{
198
						{
234
							Ilife[cRow]=&Data[cRow*nCols];
199
							Ilife[cRow]=&Data[cRow*nCols];
235
						}
200
						}
236
				}
201
				}
237
		}
202
		}
238
		//@}
203
		//@}
239
	
204
	
240
		/*!
205
		/*!
241
			\name Acces functions and operators.
206
			\name Acces functions and operators.
242
			The [] operators are the ones intaended for usual use. The get 
207
			The [] operators are the ones intaended for usual use. The get 
243
			and set functions are added to allow for genral Matrix function 
208
			and set functions are added to allow for genral Matrix function 
244
			templates.
209
			templates.
245
		*/
210
		*/
246
		//@{
211
		//@{
247
		T* operator[](const int Row) 
212
		T* operator[](const int Row) 
248
		{
213
		{
249
			assert(Row>=0);
214
			assert(Row>=0);
250
			assert(Row<nRows);
215
			assert(Row<nRows);
251
		
216
		
252
			return Ilife[Row];
217
			return Ilife[Row];
253
		}
218
		}
254
	
219
	
255
		const T* operator[](const int Row) const 
220
		const T* operator[](const int Row) const 
256
		{
221
		{
257
			assert(Row>=0);
222
			assert(Row>=0);
258
			assert(Row<nRows);
223
			assert(Row<nRows);
259
		
224
		
260
			return Ilife[Row];
225
			return Ilife[Row];
261
		}
226
		}
262
 
227
 
263
		const T& get(const int Row,const int Col) const
228
		const T& get(const int Row,const int Col) const
264
		{
229
		{
265
			assert(Row>=0 && Row<nRows);
230
			assert(Row>=0 && Row<nRows);
266
			assert(Col>=0 && Col<nCols);
231
			assert(Col>=0 && Col<nCols);
267
			return Ilife[Row][Col];
232
			return Ilife[Row][Col];
268
		}
233
		}
269
 
234
 
270
		void set(const int Row,const int Col,const T val) 
235
		void set(const int Row,const int Col,const T val) 
271
		{
236
		{
272
			assert(Row>=0 && Row<nRows);
237
			assert(Row>=0 && Row<nRows);
273
			assert(Col>=0 && Col<nCols);
238
			assert(Col>=0 && Col<nCols);
274
			Ilife[Row][Col]=val;
239
			Ilife[Row][Col]=val;
275
		}
240
		}
276
		//@}
241
		//@}
277
	
242
	
278
		/*! 
243
		/*! 
279
			\name Arithmetic operators.
244
			\name Arithmetic operators.
280
			The aritmic operators of the CMatrixType class.
245
			The aritmic operators of the CMatrixType class.
281
		*/
246
		*/
282
		//@{
247
		//@{
283
		CMatrixType<T> operator+(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
248
		CMatrixType<T> operator+(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
284
		CMatrixType<T> operator-(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
249
		CMatrixType<T> operator-(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
285
		CMatrixType<T> operator*(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret*=Rhs;};
250
		CMatrixType<T> operator*(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret*=Rhs;};
286
		CMatrixType<T> operator/(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret/=Rhs;};
251
		CMatrixType<T> operator/(const T& Rhs) const {CMatrixType<T>Ret(*this); return Ret/=Rhs;};
287
		CMatrixType<T>& operator+=(const T& Rhs)
252
		CMatrixType<T>& operator+=(const T& Rhs)
288
		{
253
		{
289
 
254
 
290
			T* Itt=Data;
255
			T* Itt=Data;
291
			T* Stop=&(Data[nElems]);
256
			T* Stop=&(Data[nElems]);
292
			while(Itt!=Stop)
257
			while(Itt!=Stop)
293
				{
258
				{
294
					(*Itt)+=Rhs;
259
					(*Itt)+=Rhs;
295
					++Itt;
260
					++Itt;
296
				}
261
				}
297
		
262
		
298
			return *this; 
263
			return *this; 
299
		}
264
		}
300
	
265
	
301
		CMatrixType<T>& operator-=(const T& Rhs)
266
		CMatrixType<T>& operator-=(const T& Rhs)
302
		{
267
		{
303
			T* Itt=Data;
268
			T* Itt=Data;
304
			T* Stop=&(Data[nElems]);
269
			T* Stop=&(Data[nElems]);
305
			while(Itt!=Stop)
270
			while(Itt!=Stop)
306
				{
271
				{
307
					(*Itt)-=Rhs;
272
					(*Itt)-=Rhs;
308
					++Itt;
273
					++Itt;
309
				}
274
				}
310
		
275
		
311
			return *this; 
276
			return *this; 
312
		}
277
		}
313
	
278
	
314
		CMatrixType<T>& operator*=(const T& Rhs)
279
		CMatrixType<T>& operator*=(const T& Rhs)
315
		{
280
		{
316
			T* Itt=Data;
281
			T* Itt=Data;
317
			T* Stop=&(Data[nElems]);
282
			T* Stop=&(Data[nElems]);
318
			while(Itt!=Stop)
283
			while(Itt!=Stop)
319
				{
284
				{
320
					(*Itt)*=Rhs;
285
					(*Itt)*=Rhs;
321
					++Itt;
286
					++Itt;
322
				}
287
				}
323
		
288
		
324
			return *this; 
289
			return *this; 
325
		}
290
		}
326
	
291
	
327
		CMatrixType<T>& operator/=(const T& Rhs)
292
		CMatrixType<T>& operator/=(const T& Rhs)
328
		{
293
		{
329
			T* Itt=Data;
294
			T* Itt=Data;
330
			T* Stop=&(Data[nElems]);
295
			T* Stop=&(Data[nElems]);
331
			while(Itt!=Stop)
296
			while(Itt!=Stop)
332
				{
297
				{
333
					(*Itt)/=Rhs;
298
					(*Itt)/=Rhs;
334
					++Itt;
299
					++Itt;
335
				}
300
				}
336
		
301
		
337
			return *this; 
302
			return *this; 
338
		}
303
		}
339
 
304
 
340
		CMatrixType<T> operator+(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
305
		CMatrixType<T> operator+(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret+=Rhs;};
341
		CMatrixType<T> operator-(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
306
		CMatrixType<T> operator-(const CMatrixType<T>& Rhs) const {CMatrixType<T>Ret(*this); return Ret-=Rhs;};
342
 
307
 
343
		CMatrixType<T>& operator+=(const CMatrixType<T>& Rhs)
308
		CMatrixType<T>& operator+=(const CMatrixType<T>& Rhs)
344
		{
309
		{
345
			assert(nRows==Rhs.nRows);
310
			assert(nRows==Rhs.nRows);
346
			assert(nCols==Rhs.nCols);
311
			assert(nCols==Rhs.nCols);
347
 
312
 
348
			T* IttRhs=Rhs.Data;
313
			T* IttRhs=Rhs.Data;
349
			T* Itt=Data;
314
			T* Itt=Data;
350
			T* Stop=&(Data[nElems]);
315
			T* Stop=&(Data[nElems]);
351
			while(Itt!=Stop)
316
			while(Itt!=Stop)
352
				{
317
				{
353
					(*Itt)+=(*IttRhs);
318
					(*Itt)+=(*IttRhs);
354
					++Itt;
319
					++Itt;
355
					++IttRhs;
320
					++IttRhs;
356
				}
321
				}
357
 
322
 
358
			return *this; 
323
			return *this; 
359
		}
324
		}
360
	
325
	
361
		CMatrixType<T>& operator-=(const CMatrixType<T>& Rhs)
326
		CMatrixType<T>& operator-=(const CMatrixType<T>& Rhs)
362
		{
327
		{
363
			assert(nRows==Rhs.nRows);
328
			assert(nRows==Rhs.nRows);
364
			assert(nCols==Rhs.nCols);
329
			assert(nCols==Rhs.nCols);
365
			T* IttRhs=Rhs.Data;
330
			T* IttRhs=Rhs.Data;
366
			T* Itt=Data;
331
			T* Itt=Data;
367
			T* Stop=&(Data[nElems]);
332
			T* Stop=&(Data[nElems]);
368
			while(Itt!=Stop)
333
			while(Itt!=Stop)
369
				{
334
				{
370
					(*Itt)-=(*IttRhs);
335
					(*Itt)-=(*IttRhs);
371
					++Itt;
336
					++Itt;
372
					++IttRhs;
337
					++IttRhs;
373
				}
338
				}
374
			return *this; 
339
			return *this; 
375
		}
340
		}
376
 
341
 
377
		CMatrixType<T> operator* (const CMatrixType<T>& Rhs) const
342
		CMatrixType<T> operator* (const CMatrixType<T>& Rhs) const
378
		{
343
		{
379
			assert(nCols==Rhs.nRows);
344
			assert(nCols==Rhs.nRows);
380
			CMatrixType<T> Ret(nRows,Rhs.nCols);
345
			CMatrixType<T> Ret(nRows,Rhs.nCols);
381
 
346
 
382
			for(int cRow=0;cRow<nRows;cRow++)
347
			for(int cRow=0;cRow<nRows;cRow++)
383
				{
348
				{
384
					for(int cCol=0;cCol<Rhs.nCols;cCol++)
349
					for(int cCol=0;cCol<Rhs.nCols;cCol++)
385
						{
350
						{
386
							T* Ret_ij=&(Ret[cRow][cCol]);
351
							T* Ret_ij=&(Ret[cRow][cCol]);
387
							*Ret_ij=0;
352
							*Ret_ij=0;
388
							for(int cI=0;cI<nCols;cI++)
353
							for(int cI=0;cI<nCols;cI++)
389
								{
354
								{
390
									(*Ret_ij)+=(Ilife[cRow])[cI]*Rhs[cI][cCol];
355
									(*Ret_ij)+=(Ilife[cRow])[cI]*Rhs[cI][cCol];
391
								}
356
								}
392
						}
357
						}
393
				}
358
				}
394
			return Ret;
359
			return Ret;
395
		}
360
		}
396
 
361
 
397
		CVectorType<T> operator* (const CVectorType<T>& Rhs) const 
362
		CVectorType<T> operator* (const CVectorType<T>& Rhs) const 
398
		{
363
		{
399
			assert(nCols==Rhs.nElems);
364
			assert(nCols==Rhs.nElems);
400
			CVectorType<T> Ret(nRows,0);
365
			CVectorType<T> Ret(nRows,0);
401
 
366
 
402
			T* ThisItt=Data;
367
			T* ThisItt=Data;
403
			T* Stop=&(Data[nElems]);
368
			T* Stop=&(Data[nElems]);
404
			T* RhsItt;
369
			T* RhsItt;
405
			T* RetItt=Ret.Data;
370
			T* RetItt=Ret.Data;
406
			while(ThisItt!=Stop)
371
			while(ThisItt!=Stop)
407
				{
372
				{
408
					RhsItt=Rhs.Data;
373
					RhsItt=Rhs.Data;
409
					for(int cCol=nCols;cCol>0;--cCol)
374
					for(int cCol=nCols;cCol>0;--cCol)
410
						{
375
						{
411
							(*RetItt)+=(*RhsItt)*(*ThisItt);
376
							(*RetItt)+=(*RhsItt)*(*ThisItt);
412
							++ThisItt;
377
							++ThisItt;
413
							++RhsItt;
378
							++RhsItt;
414
						}
379
						}
415
					++RetItt;
380
					++RetItt;
416
				}
381
				}
417
			return Ret;
382
			return Ret;
418
		}
383
		}
419
		//@}
384
		//@}
420
	
385
	
421
		/*!
386
		/*!
422
			\name Matrix Transpose.
387
			\name Matrix Transpose.
423
			Functions to transpose the matrix
388
			Functions to transpose the matrix
424
		*/
389
		*/
425
		//@{
390
		//@{
426
		///Transposes the matrix itself.
391
		///Transposes the matrix itself.
427
		CMatrixType<T>& Transpose(void)
392
		CMatrixType<T>& Transpose(void)
428
		{
393
		{
429
			T* NewData =new T[nElems];
394
			T* NewData =new T[nElems];
430
			T*RowP;
395
			T*RowP;
431
			int cRow;
396
			int cRow;
432
			for(cRow=0;cRow<nRows;cRow++)
397
			for(cRow=0;cRow<nRows;cRow++)
433
				{
398
				{
434
					RowP=Ilife[cRow];
399
					RowP=Ilife[cRow];
435
					for(int cCol=0;cCol<nCols;cCol++)
400
					for(int cCol=0;cCol<nCols;cCol++)
436
						{
401
						{
437
							NewData[cCol*nRows+cRow]=RowP[cCol];
402
							NewData[cCol*nRows+cRow]=RowP[cCol];
438
						}
403
						}
439
				}
404
				}
440
		
405
		
441
			CleanUp();
406
			CleanUp();
442
		
407
		
443
			Data=NewData;
408
			Data=NewData;
444
			int temp=nRows;
409
			int temp=nRows;
445
			nRows=nCols;
410
			nRows=nCols;
446
			nCols=temp;
411
			nCols=temp;
447
			Ilife=new T*[nRows];	
412
			Ilife=new T*[nRows];	
448
			for(cRow=0;cRow<nRows;cRow++) 
413
			for(cRow=0;cRow<nRows;cRow++) 
449
				{
414
				{
450
					Ilife[cRow]=&Data[cRow*nCols];
415
					Ilife[cRow]=&Data[cRow*nCols];
451
				}
416
				}
452
		
417
		
453
			return *this;
418
			return *this;
454
		}
419
		}
455
 
420
 
456
		///Returns the Transpose of the matrix is returned in AT.
421
		///Returns the Transpose of the matrix is returned in AT.
457
		void Transposed(CMatrixType<T>& AT) const
422
		void Transposed(CMatrixType<T>& AT) const
458
		{
423
		{
459
			AT.Resize(nCols,nRows);
424
			AT.Resize(nCols,nRows);
460
			for(int cRow=nRows-1;cRow>=0;--cRow)
425
			for(int cRow=nRows-1;cRow>=0;--cRow)
461
				{
426
				{
462
					for(int cCol=nCols-1;cCol>=0;--cCol)
427
					for(int cCol=nCols-1;cCol>=0;--cCol)
463
						{
428
						{
464
							AT[cCol][cRow]=Ilife[cRow][cCol];
429
							AT[cCol][cRow]=Ilife[cRow][cCol];
465
						}
430
						}
466
				}
431
				}
467
		}
432
		}
468
 
433
 
469
		///Returns the Transpose of the matrix is returned.
434
		///Returns the Transpose of the matrix is returned.
470
		CMatrixType<T> Transposed(void) const
435
		CMatrixType<T> Transposed(void) const
471
		{
436
		{
472
			CMatrixType<T> Ret(nCols,nRows);
437
			CMatrixType<T> Ret(nCols,nRows);
473
			Transposed(Ret);
438
			Transposed(Ret);
474
			return Ret;
439
			return Ret;
475
		}
440
		}
476
		//@}
441
		//@}
477
 
442
 
478
 
443
 
479
		/*!
444
		/*!
480
			\name Elementwise functions.
445
			\name Elementwise functions.
481
			Functions the perform some elementary operation on each 
446
			Functions the perform some elementary operation on each 
482
			of the elements of the matrix.
447
			of the elements of the matrix.
483
		*/
448
		*/
484
		//@{
449
		//@{
485
		///Pairwise multipling the elemtns of the two matrices. Equvivalent to MatLAb's .*
450
		///Pairwise multipling the elemtns of the two matrices. Equvivalent to MatLAb's .*
486
		void ElemMult(const CMatrixType<T>& Rhs)
451
		void ElemMult(const CMatrixType<T>& Rhs)
487
		{
452
		{
488
			T*Itt=Data;
453
			T*Itt=Data;
489
			T*Stop=&(Data[nElems]);
454
			T*Stop=&(Data[nElems]);
490
			T*RhsItt=Rhs.Data;
455
			T*RhsItt=Rhs.Data;
491
			while(Itt!=Stop)
456
			while(Itt!=Stop)
492
				{
457
				{
493
					(*Itt)*=(*RhsItt);
458
					(*Itt)*=(*RhsItt);
494
					++Itt;
459
					++Itt;
495
					++RhsItt;
460
					++RhsItt;
496
				}
461
				}
497
		}
462
		}
498
 
463
 
499
		///Pairwise dividnig the the elemtns of the two matrices. Equvivalent to MatLAb's ./
464
		///Pairwise dividnig the the elemtns of the two matrices. Equvivalent to MatLAb's ./
500
		void ElemDiv(const CMatrixType<T>& Rhs)
465
		void ElemDiv(const CMatrixType<T>& Rhs)
501
		{
466
		{
502
			T*Itt=Data;
467
			T*Itt=Data;
503
			T*Stop=&(Data[nElems]);
468
			T*Stop=&(Data[nElems]);
504
			T*RhsItt=Rhs.Data;
469
			T*RhsItt=Rhs.Data;
505
			while(Itt!=Stop)
470
			while(Itt!=Stop)
506
				{
471
				{
507
					(*Itt)/=(*RhsItt);
472
					(*Itt)/=(*RhsItt);
508
					++Itt;
473
					++Itt;
509
					++RhsItt;
474
					++RhsItt;
510
				}
475
				}
511
		}
476
		}
512
 
477
 
513
		///The elements of the matrix squared. Equvivalent to MatLAb's .^2
478
		///The elements of the matrix squared. Equvivalent to MatLAb's .^2
514
		void ElemSqr(void)
479
		void ElemSqr(void)
515
		{
480
		{
516
			T*Itt=Data;
481
			T*Itt=Data;
517
			T*Stop=&(Data[nElems]);
482
			T*Stop=&(Data[nElems]);
518
			while(Itt!=Stop)
483
			while(Itt!=Stop)
519
				{
484
				{
520
					(*Itt)*=(*Itt);
485
					(*Itt)*=(*Itt);
521
					++Itt;
486
					++Itt;
522
				}
487
				}
523
		}
488
		}
524
 
489
 
525
		///The square root of the elements. Equvivalent to MatLAb's .^0.5
490
		///The square root of the elements. Equvivalent to MatLAb's .^0.5
526
		void ElemSqrt(void)
491
		void ElemSqrt(void)
527
		{
492
		{
528
			T*Itt=Data;
493
			T*Itt=Data;
529
			T*Stop=&(Data[nElems]);
494
			T*Stop=&(Data[nElems]);
530
			while(Itt!=Stop)
495
			while(Itt!=Stop)
531
				{
496
				{
532
					(*Itt)=sqrt(*Itt);
497
					(*Itt)=sqrt(*Itt);
533
					++Itt;
498
					++Itt;
534
				}
499
				}
535
		}
500
		}
536
		//@}
501
		//@}
537
 
502
 
538
		/*!
503
		/*!
539
			\name Norms.
504
			\name Norms.
540
			Computes various norms of the matrix.
505
			Computes various norms of the matrix.
541
		*/
506
		*/
542
		//@{
507
		//@{
543
		///The Max norm returns the maximum absolute value
508
		///The Max norm returns the maximum absolute value
544
		const T NormMax(void) const
509
		const T NormMax(void) const
545
		{
510
		{
546
			T Ret=0;
511
			T Ret=0;
547
			T Abs;
512
			T Abs;
548
			const T*Itt=Data;
513
			const T*Itt=Data;
549
			const T*Stop=&(Data[nElems]);
514
			const T*Stop=&(Data[nElems]);
550
			while(Itt!=Stop)
515
			while(Itt!=Stop)
551
				{
516
				{
552
					Abs=(*Itt)>0?(*Itt):-(*Itt);
517
					Abs=(*Itt)>0?(*Itt):-(*Itt);
553
					if(Ret<Abs)
518
					if(Ret<Abs)
554
						Ret=Abs;
519
						Ret=Abs;
555
 
520
 
556
					++Itt;
521
					++Itt;
557
				}
522
				}
558
			return Ret;
523
			return Ret;
559
		}
524
		}
560
 
525
 
561
		/// The Frobenius norm returns the square root of the element sum of squares.
526
		/// The Frobenius norm returns the square root of the element sum of squares.
562
		const T NormFrobenius(void) const
527
		const T NormFrobenius(void) const
563
		{
528
		{
564
			T Ret=0;
529
			T Ret=0;
565
			const T*Itt=Data;
530
			const T*Itt=Data;
566
			const T*Stop=&(Data[nElems]);
531
			const T*Stop=&(Data[nElems]);
567
			while(Itt!=Stop)
532
			while(Itt!=Stop)
568
				{
533
				{
569
					Ret+=(*Itt)*(*Itt);
534
					Ret+=(*Itt)*(*Itt);
570
					++Itt;
535
					++Itt;
571
				}
536
				}
572
			return sqrt(Ret);
537
			return sqrt(Ret);
573
		}
538
		}
574
		//@}
539
		//@}
575
 
540
 
576
 
541
 
577
		/*!
542
		/*!
578
			\name Sub-part acces functions
543
			\name Sub-part acces functions
579
			These functions are used to acces sub parts of the matrix.
544
			These functions are used to acces sub parts of the matrix.
580
		*/
545
		*/
581
		//@{
546
		//@{
582
		///Get the cRow'th row and set it equal to Row. Equvivalent to Row=this(cRow,:) in Matlab.
547
		///Get the cRow'th row and set it equal to Row. Equvivalent to Row=this(cRow,:) in Matlab.
583
		void GetRow(CVectorType<T>& Row,const int cRow) const
548
		void GetRow(CVectorType<T>& Row,const int cRow) const
584
		{
549
		{
585
			Row.Resize(nCols);
550
			Row.Resize(nCols);
586
			memcpy(Row.Data,Ilife[cRow],nCols*sizeof(T));
551
			memcpy(Row.Data,Ilife[cRow],nCols*sizeof(T));
587
		}
552
		}
588
 
553
 
589
		///Sets the cRow'th row of the matrix equal to Row. Equvivalent to this(cRow,:)=Row in Matlab.
554
		///Sets the cRow'th row of the matrix equal to Row. Equvivalent to this(cRow,:)=Row in Matlab.
590
		void SetRow(CVectorType<T>& Row,const int cRow)
555
		void SetRow(CVectorType<T>& Row,const int cRow)
591
		{
556
		{
592
			assert(Row.Length()==nCols);
557
			assert(Row.Length()==nCols);
593
			memcpy(Ilife[cRow],Row.Data,nCols*sizeof(T));
558
			memcpy(Ilife[cRow],Row.Data,nCols*sizeof(T));
594
		}
559
		}
595
 
560
 
596
		///Copies row 'from' of this matrix to row 'to' of matrix A. Equvivalent to A(to,:)=this(from,:) in Matlab.
561
		///Copies row 'from' of this matrix to row 'to' of matrix A. Equvivalent to A(to,:)=this(from,:) in Matlab.
597
		void RowTransfere(CMatrixType<T>& A, const int from,const int to) const
562
		void RowTransfere(CMatrixType<T>& A, const int from,const int to) const
598
		{
563
		{
599
			assert(A.Cols()==nCols);
564
			assert(A.Cols()==nCols);
600
			memcpy(A.Ilife[to],Ilife[from],nCols*sizeof(T));
565
			memcpy(A.Ilife[to],Ilife[from],nCols*sizeof(T));
601
		}
566
		}
602
 
567
 
603
		void GetCol(CVectorType<T>&Col, const int nCol) const
568
		void GetCol(CVectorType<T>&Col, const int nCol) const
604
		{
569
		{
605
			Col.Resize(nRows);
570
			Col.Resize(nRows);
606
			const T* Itt=&Data[nCol];
571
			const T* Itt=&Data[nCol];
607
			T* VecItt=&Col[0];
572
			T* VecItt=&Col[0];
608
			for(int cRow=0;cRow<nRows;cRow++)
573
			for(int cRow=0;cRow<nRows;cRow++)
609
				{
574
				{
610
					*VecItt=*Itt;
575
					*VecItt=*Itt;
611
					++VecItt;
576
					++VecItt;
612
					Itt+=nCols;
577
					Itt+=nCols;
613
				}
578
				}
614
		}
579
		}
615
 
580
 
616
		void SetCol(CVectorType<T>&Col, const int nCol)
581
		void SetCol(CVectorType<T>&Col, const int nCol)
617
		{
582
		{
618
			assert(nRows==Col.Length());
583
			assert(nRows==Col.Length());
619
			assert(nCol<nCols);
584
			assert(nCol<nCols);
620
 
585
 
621
			T* Itt=&Data[nCol];
586
			T* Itt=&Data[nCol];
622
			T* VecItt=&Col[0];
587
			T* VecItt=&Col[0];
623
			for(int cRow=0;cRow<nRows;cRow++)
588
			for(int cRow=0;cRow<nRows;cRow++)
624
				{
589
				{
625
					*Itt=*VecItt;
590
					*Itt=*VecItt;
626
					++VecItt;
591
					++VecItt;
627
					Itt+=nCols;
592
					Itt+=nCols;
628
				}
593
				}
629
		}
594
		}
630
 
595
 
631
		void GetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol, const int RowDim, const int ColDim) const
596
		void GetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol, const int RowDim, const int ColDim) const
632
		{
597
		{
633
			assert(StartRow+RowDim<=nRows);
598
			assert(StartRow+RowDim<=nRows);
634
			assert(StartCol+ColDim<=nCols);
599
			assert(StartCol+ColDim<=nCols);
635
			A.Resize(RowDim,ColDim);
600
			A.Resize(RowDim,ColDim);
636
			const T* Itt=&(Ilife[StartRow][StartCol]);
601
			const T* Itt=&(Ilife[StartRow][StartCol]);
637
 
602
 
638
			for(int cRow=0;cRow<A.Rows();cRow++)
603
			for(int cRow=0;cRow<A.Rows();cRow++)
639
				{
604
				{
640
					memcpy(A[cRow],Itt,A.Cols()*sizeof(T));
605
					memcpy(A[cRow],Itt,A.Cols()*sizeof(T));
641
					Itt+=nCols;
606
					Itt+=nCols;
642
				}
607
				}
643
		}
608
		}
644
 
609
 
645
		void SetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol)
610
		void SetSubMatrix(CMatrixType<T>& A, const int StartRow, const int StartCol)
646
		{
611
		{
647
			assert(A.Rows()+StartRow<=nRows);
612
			assert(A.Rows()+StartRow<=nRows);
648
			assert(A.Cols()+StartCol<=nCols);
613
			assert(A.Cols()+StartCol<=nCols);
649
			T* Itt=&(Ilife[StartRow][StartCol]);
614
			T* Itt=&(Ilife[StartRow][StartCol]);
650
 
615
 
651
			for(int cRow=0;cRow<A.Rows();cRow++)
616
			for(int cRow=0;cRow<A.Rows();cRow++)
652
				{
617
				{
653
					memcpy(Itt,A[cRow],A.Cols()*sizeof(T));
618
					memcpy(Itt,A[cRow],A.Cols()*sizeof(T));
654
					Itt+=nCols;
619
					Itt+=nCols;
655
				}
620
				}
656
		}
621
		}
657
 
622
 
658
		//@}
623
		//@}
659
 
624
 
660
 
625
 
661
 
626
 
662
	};
627
	};
663
 
628
 
664
	/*!
629
	/*!
665
		\name Additional matrix operators
630
		\name Additional matrix operators
666
		These are operators heavily associated with CMAtrixType, but not included
631
		These are operators heavily associated with CMAtrixType, but not included
667
		in the class definition it self.
632
		in the class definition it self.
668
	*/
633
	*/
669
	//@{
634
	//@{
670
	template<class T>
635
	template<class T>
671
	inline CMatrixType<T> operator+(const T& Lhs,const CMatrixType<T>&Rhs ) 
636
	inline CMatrixType<T> operator+(const T& Lhs,const CMatrixType<T>&Rhs ) 
672
	{
637
	{
673
		return Rhs+Lhs;
638
		return Rhs+Lhs;
674
	}
639
	}
675
 
640
 
676
	template<class T>
641
	template<class T>
677
	inline CMatrixType<T> operator*(const T& Lhs,const CMatrixType<T>&Rhs ) 
642
	inline CMatrixType<T> operator*(const T& Lhs,const CMatrixType<T>&Rhs ) 
678
	{
643
	{
679
		return Rhs*Lhs;
644
		return Rhs*Lhs;
680
	}
645
	}
681
 
646
 
682
	template <class T>
647
	template <class T>
683
	std::ostream& operator<<(std::ostream &s, const CMatrixType<T> &A)
648
	std::ostream& operator<<(std::ostream &s, const CMatrixType<T> &A)
684
	{
649
	{
685
    int nRows=A.Rows();
650
    int nRows=A.Rows();
686
    int nCols=A.Cols();
651
    int nCols=A.Cols();
687
	
652
	
688
    for (int cRow=0; cRow<nRows; cRow++)
653
    for (int cRow=0; cRow<nRows; cRow++)
689
			{
654
			{
690
        for (int cCol=0; cCol<nCols; cCol++)
655
        for (int cCol=0; cCol<nCols; cCol++)
691
					{
656
					{
692
            s << A[cRow][cCol] << " ";
657
            s << A[cRow][cCol] << " ";
693
					}
658
					}
694
        s << "\n";
659
        s << "\n";
695
			}
660
			}
696
    return s;
661
    return s;
697
	}
662
	}
698
 
663
 
699
	template <class T>
664
	template <class T>
700
	std::istream& operator>>(std::istream &s, CMatrixType<T> &A)
665
	std::istream& operator>>(std::istream &s, CMatrixType<T> &A)
701
	{
666
	{
702
    int nRows;
667
    int nRows;
703
		int nCols;
668
		int nCols;
704
 
669
 
705
    s >> nRows >> nCols;
670
    s >> nRows >> nCols;
706
 
671
 
707
    if ( nRows!=A.Rows() || nCols!=A.Cols() )
672
    if ( nRows!=A.Rows() || nCols!=A.Cols() )
708
			A.Resize(nRows,nCols);
673
			A.Resize(nRows,nCols);
709
 
674
 
710
		T* RowP;
675
		T* RowP;
711
 
676
 
712
 
677
 
713
    for (int cRow=0; cRow<nRows;cRow++)
678
    for (int cRow=0; cRow<nRows;cRow++)
714
			{
679
			{
715
				RowP=A[cRow];
680
				RowP=A[cRow];
716
        for (int cCol=0;cCol<nCols;cCol++)
681
        for (int cCol=0;cCol<nCols;cCol++)
717
					{
682
					{
718
            s >>  RowP[cCol];
683
            s >>  RowP[cCol];
719
					}
684
					}
720
			}
685
			}
721
 
686
 
722
    return s;
687
    return s;
723
	}
688
	}
724
	//@}
689
	//@}
725
 
690
 
726
	/// The Matrix annotation intended for use.
691
	/// The Matrix annotation intended for use.
727
	typedef CMatrixType<double> CMatrix;
692
	typedef CMatrixType<double> CMatrix;
728
}
693
}
729
#endif // !defined(MATRIX_H_HAA_AGUST_2001)
694
#endif // !defined(MATRIX_H_HAA_AGUST_2001)
730
 
695
 
731
 
696