Subversion Repositories gelsvn

Rev

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

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