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
/*!
7
/*!
8
	\file Vector.h
8
	\file Vector.h
9
	\brief The Vector type
9
	\brief The Vector type
10
*/
10
*/
11
#if !defined(VECTOR_H__HAA_AGUST_2001)
11
#if !defined(VECTOR_H__HAA_AGUST_2001)
12
#define VECTOR_H__HAA_AGUST_2001
12
#define VECTOR_H__HAA_AGUST_2001
13
 
13
 
14
#include <cassert>
14
#include <cassert>
15
#include <iostream>
15
#include <iostream>
16
#include <cmath>
16
#include <cmath>
17
#include "CGLA/Vec2f.h"
17
#include "../CGLA/Vec2f.h"
18
#include "CGLA/Vec3f.h"
18
#include "../CGLA/Vec3f.h"
19
 
19
 
20
namespace LinAlg
20
namespace LinAlg
21
{
21
{
22
	template <class T> class CMatrixType;  
22
	template <class T> class CMatrixType;  
23
 
23
 
24
	/*!
24
	/*!
25
		\brief The Vector type.
25
		\brief The Vector type.
26
	
26
	
27
		This vector teplate is one of the basic linear algebra types. In 
27
		This vector teplate is one of the basic linear algebra types. In 
28
		principle it an overloaded Array of type T. The typedef Vector with 
28
		principle it an overloaded Array of type T. The typedef Vector with 
29
		T set to double
29
		T set to double
30
 
30
 
31
		typedef CVectorType<double> CVector;
31
		typedef CVectorType<double> CVector;
32
	
32
	
33
		is the delclaration intended to be used as the matrix type outside 
33
		is the delclaration intended to be used as the matrix type outside 
34
		the this and related files. The reson for making a template is 
34
		the this and related files. The reson for making a template is 
35
		twofold, first it allows for an esay change of precision in this
35
		twofold, first it allows for an esay change of precision in this
36
		linear algebre package. Secondly it allows for other Vector types 
36
		linear algebre package. Secondly it allows for other Vector types 
37
		in special cases.
37
		in special cases.
38
	
38
	
39
		The pointer to the data area can be obtained by operator [] (int i) 
39
		The pointer to the data area can be obtained by operator [] (int i) 
40
		with i=0, e.g. 
40
		with i=0, e.g. 
41
	
41
	
42
		CVector A;
42
		CVector A;
43
	
43
	
44
		T* pData=A[0];  
44
		T* pData=A[0];  
45
	
45
	
46
		will  make pData point to the data.
46
		will  make pData point to the data.
47
	
47
	
48
		\see LapackFunc.h
48
		\see LapackFunc.h
49
		\see CMatrixType  
49
		\see CMatrixType  
50
		\see Additional vector operators (located in this file Vector.h)
50
		\see Additional vector operators (located in this file Vector.h)
51
		\see CMatrix
51
		\see CMatrix
52
		\see CVector
52
		\see CVector
53
		\author Henrik Aanæs
53
		\author Henrik Aanæs
54
		\version Aug 2001
54
		\version Aug 2001
55
	*/
55
	*/
56
 
56
 
57
	template <class T>
57
	template <class T>
58
	class CVectorType  
58
	class CVectorType  
59
	{
59
	{
60
 
60
 
61
		friend class CMatrixType<T>;
61
		friend class CMatrixType<T>;
62
 
62
 
63
	private:
63
	private:
64
 
64
 
65
		///The number of elements in the vector
65
		///The number of elements in the vector
66
		int nElems;
66
		int nElems;
67
 
67
 
68
		///The pointer to the vector data
68
		///The pointer to the vector data
69
		T*Data;
69
		T*Data;
70
 
70
 
71
		///Sets all the elements in the vector to a scalar
71
		///Sets all the elements in the vector to a scalar
72
		void SetScalar(const T& Scalar) 
72
		void SetScalar(const T& Scalar) 
73
		{
73
		{
74
			T* Itt=Data;
74
			T* Itt=Data;
75
			T* Stop=&(Data[nElems]);
75
			T* Stop=&(Data[nElems]);
76
			while(Itt!=Stop)
76
			while(Itt!=Stop)
77
				{
77
				{
78
					*Itt=Scalar;
78
					*Itt=Scalar;
79
					++Itt;
79
					++Itt;
80
				}
80
				}
81
		}; 
81
		}; 
82
 
82
 
83
		///Frees the used memory
83
		///Frees the used memory
84
		void CleanUp(void)  {if(Data!=NULL) delete [] Data;};
84
		void CleanUp(void)  {if(Data!=NULL) delete [] Data;};
85
		///Allocate the needed memory. Note that nElems should be initialized correctly first.
85
		///Allocate the needed memory. Note that nElems should be initialized correctly first.
86
 
86
 
87
		void Allocate(void) { Data= new T[nElems];};
87
		void Allocate(void) { Data= new T[nElems];};
88
 
88
 
89
 
89
 
90
	public:
90
	public:
91
 
91
 
92
		/// \name Constructurs and Destructors
92
		/// \name Constructurs and Destructors
93
		//@{
93
		//@{
94
		///Creats a vector a size 0.
94
		///Creats a vector a size 0.
95
		CVectorType<T>():nElems(0),Data(NULL) {};
95
		CVectorType<T>():nElems(0),Data(NULL) {};
96
 
96
 
97
		///Creates a vector of the specified Length
97
		///Creates a vector of the specified Length
98
		explicit CVectorType<T>(const int Length): nElems(Length) {Allocate();}
98
		explicit CVectorType<T>(const int Length): nElems(Length) {Allocate();}
99
 
99
 
100
		///Creates a vector of the specified Length, and sets all the values to a scalar.
100
		///Creates a vector of the specified Length, and sets all the values to a scalar.
101
		CVectorType<T>(const int Length,const T& Scalar): nElems(Length) {Allocate();SetScalar(Scalar);}
101
		CVectorType<T>(const int Length,const T& Scalar): nElems(Length) {Allocate();SetScalar(Scalar);}
102
 
102
 
103
		///Copy constructor
103
		///Copy constructor
104
		CVectorType<T>(const CVectorType<T>& Rhs): nElems(Rhs.nElems)
104
		CVectorType<T>(const CVectorType<T>& Rhs): nElems(Rhs.nElems)
105
		{
105
		{
106
			Allocate();
106
			Allocate();
107
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
107
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
108
		}
108
		}
109
 
109
 
110
		///Copy constructor from Vec2Type
110
		///Copy constructor from Vec2Type
111
		template <class TT, class V, unsigned int N> 
111
		template <class TT, class V, unsigned int N> 
112
		CVectorType<T>(const CGLA::ArithVec<TT,V,N>& Rhs):nElems(N)
112
		CVectorType<T>(const CGLA::ArithVec<TT,V,N>& Rhs):nElems(N)
113
		{
113
		{
114
			Allocate(); 
114
			Allocate(); 
115
			for(int i=0;i<N;++i)
115
			for(int i=0;i<N;++i)
116
				Data[i]=Rhs[i];
116
				Data[i]=Rhs[i];
117
		}
117
		}
118
 
118
 
119
		///
119
		///
120
		virtual ~CVectorType<T>(){ CleanUp();};
120
		virtual ~CVectorType<T>(){ CleanUp();};
121
		//@}
121
		//@}
122
 
122
 
123
 
123
 
124
		/*!\name Asignment operators. 
124
		/*!\name Asignment operators. 
125
			Note that the vector is resized if it does not have the correct size.
125
			Note that the vector is resized if it does not have the correct size.
126
		*/
126
		*/
127
		//@{
127
		//@{
128
		CVectorType<T>& operator=(const T& Rhs) {SetScalar(Rhs);return *this;}
128
		CVectorType<T>& operator=(const T& Rhs) {SetScalar(Rhs);return *this;}
129
 
129
 
130
		template <class TT, class V, unsigned int N> 
130
		template <class TT, class V, unsigned int N> 
131
		CVectorType<T>& operator=(const CGLA::ArithVec<TT,V,N>& Rhs)
131
		CVectorType<T>& operator=(const CGLA::ArithVec<TT,V,N>& Rhs)
132
		{
132
		{
133
			Resize(N);
133
			Resize(N);
134
			for(int i=0;i<N;++i)
134
			for(int i=0;i<N;++i)
135
				Data[i]=Rhs[i];
135
				Data[i]=Rhs[i];
136
		}
136
		}
137
 
137
 
138
 
138
 
139
		CVectorType<T>& operator=(const CVectorType<T>& Rhs)
139
		CVectorType<T>& operator=(const CVectorType<T>& Rhs)
140
		{
140
		{
141
			Resize(Rhs.nElems);
141
			Resize(Rhs.nElems);
142
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
142
			memcpy(Data,Rhs.Data,nElems*sizeof(T));
143
			return *this;
143
			return *this;
144
		}
144
		}
145
		//@}
145
		//@}
146
 
146
 
147
		/// \name Dimension functions
147
		/// \name Dimension functions
148
		//@{
148
		//@{
149
		///Returns the length of the vector.
149
		///Returns the length of the vector.
150
		const int Length(void) const {return nElems;}
150
		const int Length(void) const {return nElems;}
151
		///Realocates memory IF the vector does not already hve the correct size.
151
		///Realocates memory IF the vector does not already hve the correct size.
152
		void Resize(const int Length)
152
		void Resize(const int Length)
153
		{
153
		{
154
			if(Length!=nElems)
154
			if(Length!=nElems)
155
				{
155
				{
156
					CleanUp();
156
					CleanUp();
157
					nElems=Length;
157
					nElems=Length;
158
					Data= new T[nElems];
158
					Data= new T[nElems];
159
				}
159
				}
160
		}
160
		}
161
		//@}
161
		//@}
162
 
162
 
163
		/*!
163
		/*!
164
			\name Acces functions and operators.
164
			\name Acces functions and operators.
165
			The [] operators are the ones intaended for usual use. The get 
165
			The [] operators are the ones intaended for usual use. The get 
166
			and set functions are added to allow for genral vector function 
166
			and set functions are added to allow for genral vector function 
167
			templates.
167
			templates.
168
		*/
168
		*/
169
		//@{
169
		//@{
170
		const T& get(const int i)const 
170
		const T& get(const int i)const 
171
		{
171
		{
172
			assert(i>=0);
172
			assert(i>=0);
173
			assert(i<nElems);
173
			assert(i<nElems);
174
 
174
 
175
			return Data[i];
175
			return Data[i];
176
		}
176
		}
177
 
177
 
178
		void set(const int i,const T& val)
178
		void set(const int i,const T& val)
179
		{
179
		{
180
			assert(i>=0);
180
			assert(i>=0);
181
			assert(i<nElems);
181
			assert(i<nElems);
182
 
182
 
183
			Data[i]=val;
183
			Data[i]=val;
184
		}
184
		}
185
 
185
 
186
		T& operator[](const int i) 
186
		T& operator[](const int i) 
187
		{
187
		{
188
			assert(i>=0);
188
			assert(i>=0);
189
			assert(i<nElems);
189
			assert(i<nElems);
190
		
190
		
191
			return Data[i];
191
			return Data[i];
192
		}
192
		}
193
 
193
 
194
		const T& operator[](const int i) const 
194
		const T& operator[](const int i) const 
195
		{
195
		{
196
			assert(i>=0);
196
			assert(i>=0);
197
			assert(i<nElems);
197
			assert(i<nElems);
198
		
198
		
199
			return Data[i];
199
			return Data[i];
200
		}
200
		}
201
		//@}
201
		//@}
202
 
202
 
203
		/// \name aritmethic operators
203
		/// \name aritmethic operators
204
		//@{
204
		//@{
205
		CVectorType<T> operator+(const CVectorType<T>& Rhs) const {CVectorType<T>Ret(*this); return Ret+=Rhs;};
205
		CVectorType<T> operator+(const CVectorType<T>& Rhs) const {CVectorType<T>Ret(*this); return Ret+=Rhs;};
206
		CVectorType<T> operator-(const CVectorType<T>& Rhs) const {CVectorType<T>Ret(*this); return Ret-=Rhs;};
206
		CVectorType<T> operator-(const CVectorType<T>& Rhs) const {CVectorType<T>Ret(*this); return Ret-=Rhs;};
207
		CVectorType<T> operator+(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret+=Rhs;};
207
		CVectorType<T> operator+(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret+=Rhs;};
208
		CVectorType<T> operator-(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret-=Rhs;};
208
		CVectorType<T> operator-(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret-=Rhs;};
209
		CVectorType<T> operator*(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret*=Rhs;};
209
		CVectorType<T> operator*(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret*=Rhs;};
210
		CVectorType<T> operator/(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret/=Rhs;};
210
		CVectorType<T> operator/(const T& Rhs) const {CVectorType<T>Ret(*this); return Ret/=Rhs;};
211
 
211
 
212
		CVectorType<T>& operator+=(const CVectorType<T>& Rhs)
212
		CVectorType<T>& operator+=(const CVectorType<T>& Rhs)
213
		{
213
		{
214
			assert(nElems==Rhs.nElems);
214
			assert(nElems==Rhs.nElems);
215
 
215
 
216
			T* IttRhs=Rhs.Data;
216
			T* IttRhs=Rhs.Data;
217
			T* Itt=Data;
217
			T* Itt=Data;
218
			T* Stop=&(Data[nElems]);
218
			T* Stop=&(Data[nElems]);
219
			while(Itt!=Stop)
219
			while(Itt!=Stop)
220
				{
220
				{
221
					(*Itt)+=(*IttRhs);
221
					(*Itt)+=(*IttRhs);
222
					++Itt;
222
					++Itt;
223
					++IttRhs;
223
					++IttRhs;
224
				}
224
				}
225
			return *this; 
225
			return *this; 
226
		}
226
		}
227
 
227
 
228
		CVectorType<T>& operator-=(const CVectorType<T>& Rhs)
228
		CVectorType<T>& operator-=(const CVectorType<T>& Rhs)
229
		{
229
		{
230
			assert(nElems==Rhs.nElems);
230
			assert(nElems==Rhs.nElems);
231
 
231
 
232
			T* IttRhs=Rhs.Data;
232
			T* IttRhs=Rhs.Data;
233
			T* Itt=Data;
233
			T* Itt=Data;
234
			T* Stop=&(Data[nElems]);
234
			T* Stop=&(Data[nElems]);
235
			while(Itt!=Stop)
235
			while(Itt!=Stop)
236
				{
236
				{
237
					(*Itt)-=(*IttRhs);
237
					(*Itt)-=(*IttRhs);
238
					++Itt;
238
					++Itt;
239
					++IttRhs;
239
					++IttRhs;
240
				}
240
				}
241
			return *this; 
241
			return *this; 
242
		}
242
		}
243
 
243
 
244
		CVectorType<T>& operator+=(const T& Rhs)
244
		CVectorType<T>& operator+=(const T& Rhs)
245
		{
245
		{
246
			T* Itt=Data;
246
			T* Itt=Data;
247
			T* Stop=&(Data[nElems]);
247
			T* Stop=&(Data[nElems]);
248
			while(Itt!=Stop)
248
			while(Itt!=Stop)
249
				{
249
				{
250
					(*Itt)+=Rhs;
250
					(*Itt)+=Rhs;
251
					++Itt;
251
					++Itt;
252
				}
252
				}
253
			return *this; 
253
			return *this; 
254
		}
254
		}
255
 
255
 
256
		CVectorType<T>& operator-=(const T& Rhs)
256
		CVectorType<T>& operator-=(const T& Rhs)
257
		{
257
		{
258
			T* Itt=Data;
258
			T* Itt=Data;
259
			T* Stop=&(Data[nElems]);
259
			T* Stop=&(Data[nElems]);
260
			while(Itt!=Stop)
260
			while(Itt!=Stop)
261
				{
261
				{
262
					(*Itt)-=Rhs;
262
					(*Itt)-=Rhs;
263
					++Itt;
263
					++Itt;
264
				}
264
				}
265
			return *this; 
265
			return *this; 
266
		}
266
		}
267
 
267
 
268
		CVectorType<T>& operator*=(const T& Rhs)
268
		CVectorType<T>& operator*=(const T& Rhs)
269
		{
269
		{
270
			T* Itt=Data;
270
			T* Itt=Data;
271
			T* Stop=&(Data[nElems]);
271
			T* Stop=&(Data[nElems]);
272
			while(Itt!=Stop)
272
			while(Itt!=Stop)
273
				{
273
				{
274
					(*Itt)*=Rhs;
274
					(*Itt)*=Rhs;
275
					++Itt;
275
					++Itt;
276
				}
276
				}
277
			return *this; 
277
			return *this; 
278
		}
278
		}
279
 
279
 
280
		CVectorType<T>& operator/=(const T& Rhs)
280
		CVectorType<T>& operator/=(const T& Rhs)
281
		{
281
		{
282
			T* Itt=Data;
282
			T* Itt=Data;
283
			T* Stop=&(Data[nElems]);
283
			T* Stop=&(Data[nElems]);
284
			while(Itt!=Stop)
284
			while(Itt!=Stop)
285
				{
285
				{
286
					(*Itt)/=Rhs;
286
					(*Itt)/=Rhs;
287
					++Itt;
287
					++Itt;
288
				}
288
				}
289
			return *this; 
289
			return *this; 
290
		}
290
		}
291
 
291
 
292
		T operator*(const CVectorType<T>& Rhs) const
292
		T operator*(const CVectorType<T>& Rhs) const
293
		{
293
		{
294
			assert(nElems==Rhs.nElems);
294
			assert(nElems==Rhs.nElems);
295
			T Ret=0;
295
			T Ret=0;
296
 
296
 
297
			T* IttRhs=Rhs.Data;
297
			T* IttRhs=Rhs.Data;
298
			T* Itt=Data;
298
			T* Itt=Data;
299
			T* Stop=&(Data[nElems]);
299
			T* Stop=&(Data[nElems]);
300
			while(Itt!=Stop)
300
			while(Itt!=Stop)
301
				{
301
				{
302
					Ret+=(*Itt)*(*IttRhs);
302
					Ret+=(*Itt)*(*IttRhs);
303
					++Itt;
303
					++Itt;
304
					++IttRhs;
304
					++IttRhs;
305
				}
305
				}
306
			return Ret; 
306
			return Ret; 
307
		}
307
		}
308
 
308
 
309
		CVectorType<T> operator*(const CMatrixType<T>& Rhs) const
309
		CVectorType<T> operator*(const CMatrixType<T>& Rhs) const
310
		{
310
		{
311
			assert(nElems==Rhs.Rows());
311
			assert(nElems==Rhs.Rows());
312
			CVectorType<T> Ret(Rhs.Cols(),0);
312
			CVectorType<T> Ret(Rhs.Cols(),0);
313
 
313
 
314
			T* ThisItt=Data;
314
			T* ThisItt=Data;
315
			const T* RhsItt=Rhs.Data;
315
			const T* RhsItt=Rhs.Data;
316
			const T* Stop=&(Rhs.Data[Rhs.nElems]);
316
			const T* Stop=&(Rhs.Data[Rhs.nElems]);
317
			T* RetItt;
317
			T* RetItt;
318
 
318
 
319
			while(RhsItt!=Stop)
319
			while(RhsItt!=Stop)
320
				{
320
				{
321
					RetItt=Ret.Data;
321
					RetItt=Ret.Data;
322
					for(int cCol=Rhs.Cols()-1;cCol>=0;--cCol)
322
					for(int cCol=Rhs.Cols()-1;cCol>=0;--cCol)
323
						{
323
						{
324
							(*RetItt)+=(*ThisItt)*(*RhsItt);
324
							(*RetItt)+=(*ThisItt)*(*RhsItt);
325
							++RetItt;
325
							++RetItt;
326
							++RhsItt;
326
							++RhsItt;
327
						}
327
						}
328
					++ThisItt;
328
					++ThisItt;
329
				}
329
				}
330
			return Ret;
330
			return Ret;
331
		}
331
		}
332
		//@}
332
		//@}
333
 
333
 
334
		/// \name Norms
334
		/// \name Norms
335
		//@{
335
		//@{
336
		const T Norm(void) const {return sqrt((*this)*(*this));}
336
		const T Norm(void) const {return sqrt((*this)*(*this));}
337
		const T NormMax(void) const
337
		const T NormMax(void) const
338
		{
338
		{
339
			T Ret=0;
339
			T Ret=0;
340
			T Abs;
340
			T Abs;
341
			const T* Itt=Data;
341
			const T* Itt=Data;
342
			const T* Stop=&(Data[nElems]);
342
			const T* Stop=&(Data[nElems]);
343
			while(Itt!=Stop)
343
			while(Itt!=Stop)
344
				{
344
				{
345
					Abs=(*Itt)>0?(*Itt):-(*Itt);
345
					Abs=(*Itt)>0?(*Itt):-(*Itt);
346
					if(Ret<Abs)
346
					if(Ret<Abs)
347
						Ret=Abs;
347
						Ret=Abs;
348
 
348
 
349
					++Itt;
349
					++Itt;
350
				}
350
				}
351
			return Ret;
351
			return Ret;
352
		}
352
		}
353
		//@}
353
		//@}
354
 
354
 
355
		/// Sum of all the elements in the vector
355
		/// Sum of all the elements in the vector
356
		const T Sum(void) const
356
		const T Sum(void) const
357
		{
357
		{
358
			T Ret=0;
358
			T Ret=0;
359
			const T* Itt=Data;
359
			const T* Itt=Data;
360
			const T* Stop=&(Data[nElems]);
360
			const T* Stop=&(Data[nElems]);
361
			while(Itt!=Stop)
361
			while(Itt!=Stop)
362
				{
362
				{
363
					Ret+=(*Itt);
363
					Ret+=(*Itt);
364
					++Itt;
364
					++Itt;
365
				}
365
				}
366
		}
366
		}
367
 
367
 
368
 
368
 
369
		/*!
369
		/*!
370
			\name Elementwise functions.
370
			\name Elementwise functions.
371
			Functions the perform some elementary operation on each 
371
			Functions the perform some elementary operation on each 
372
			of the elements of the vector.
372
			of the elements of the vector.
373
		*/
373
		*/
374
		//@{
374
		//@{
375
		///The elements of the vector squared. Equvivalent to MatLAb's .^2
375
		///The elements of the vector squared. Equvivalent to MatLAb's .^2
376
		void ElemSqr(void)
376
		void ElemSqr(void)
377
		{
377
		{
378
			T* Itt=Data;
378
			T* Itt=Data;
379
			T* Stop=&(Data[nElems]);
379
			T* Stop=&(Data[nElems]);
380
			while(Itt!=Stop)
380
			while(Itt!=Stop)
381
				{
381
				{
382
					(*Itt)*=(*Itt);
382
					(*Itt)*=(*Itt);
383
					++Itt;
383
					++Itt;
384
				}
384
				}
385
		}
385
		}
386
 
386
 
387
 
387
 
388
	};
388
	};
389
 
389
 
390
 
390
 
391
	/*!
391
	/*!
392
		\name Additional vector operators
392
		\name Additional vector operators
393
		These are operators heavily associated with CVectorType, but not included
393
		These are operators heavily associated with CVectorType, but not included
394
		in the class definition it self.
394
		in the class definition it self.
395
	*/
395
	*/
396
	//@{
396
	//@{
397
	template<class T>
397
	template<class T>
398
	inline CVectorType<T> operator+(const T& Lhs,const CVectorType<T>&Rhs ) 
398
	inline CVectorType<T> operator+(const T& Lhs,const CVectorType<T>&Rhs ) 
399
	{
399
	{
400
		return Rhs+Lhs;
400
		return Rhs+Lhs;
401
	}
401
	}
402
 
402
 
403
	template<class T>
403
	template<class T>
404
	inline CVectorType<T> operator*(const T& Lhs,const CVectorType<T>&Rhs ) 
404
	inline CVectorType<T> operator*(const T& Lhs,const CVectorType<T>&Rhs ) 
405
	{
405
	{
406
		return Rhs*Lhs;
406
		return Rhs*Lhs;
407
	}
407
	}
408
 
408
 
409
	template <class T>
409
	template <class T>
410
	std::ostream& operator<<(std::ostream &s, const CVectorType<T> &a)
410
	std::ostream& operator<<(std::ostream &s, const CVectorType<T> &a)
411
	{
411
	{
412
		int nElems=a.Length();
412
		int nElems=a.Length();
413
	
413
	
414
		for (int cElem=0; cElem<nElems; cElem++)
414
		for (int cElem=0; cElem<nElems; cElem++)
415
			{
415
			{
416
				s << a[cElem] << " ";
416
				s << a[cElem] << " ";
417
			}
417
			}
418
		s << "\n";
418
		s << "\n";
419
	
419
	
420
		return s;
420
		return s;
421
	}
421
	}
422
 
422
 
423
 
423
 
424
	template <class T>
424
	template <class T>
425
	std::istream& operator>>(std::istream &s, CVectorType<T> &a)
425
	std::istream& operator>>(std::istream &s, CVectorType<T> &a)
426
	{
426
	{
427
		int nElems;
427
		int nElems;
428
 
428
 
429
		s >> nElems;
429
		s >> nElems;
430
 
430
 
431
		if ( nElems!=a.Length())
431
		if ( nElems!=a.Length())
432
			a.Resize(nElems);
432
			a.Resize(nElems);
433
 
433
 
434
 
434
 
435
		for (int cElem=0; cElem<a.Length();cElem++)
435
		for (int cElem=0; cElem<a.Length();cElem++)
436
			{
436
			{
437
				s >>  a[cElem];
437
				s >>  a[cElem];
438
			}
438
			}
439
 
439
 
440
		return s;
440
		return s;
441
	}
441
	}
442
	//@}
442
	//@}
443
 
443
 
444
	/// The Vector annotation intended for use.
444
	/// The Vector annotation intended for use.
445
	typedef CVectorType<double> CVector;
445
	typedef CVectorType<double> CVector;
446
}
446
}
447
#endif // !defined(VECTOR_H__HAA_AGUST_2001)
447
#endif // !defined(VECTOR_H__HAA_AGUST_2001)
448
 
448