Subversion Repositories gelsvn

Rev

Rev 595 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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