Subversion Repositories gelsvn

Rev

Rev 3 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3 Rev 9
Line 2... Line 2...
2
#define __CGLA_ARITHVEC_H__
2
#define __CGLA_ARITHVEC_H__
3
 
3
 
4
#include <iostream>
4
#include <iostream>
5
#include "CGLA.h"
5
#include "CGLA.h"
6
 
6
 
-
 
7
#include <numeric>
-
 
8
#include <algorithm>
-
 
9
#include <functional>
-
 
10
#include <memory>
7
 
11
 
8
namespace CGLA {
12
namespace CGLA {
9
 
13
 
10
	/** The ArithVec class template represents a generic arithmetic
14
	/** The ArithVec class template represents a generic arithmetic
11
			vector.  The three parameters to the template are
15
			vector.  The three parameters to the template are
Line 50... Line 54...
50
		}
54
		}
51
 
55
 
52
		/// Construct a vector where all coordinates are identical
56
		/// Construct a vector where all coordinates are identical
53
		explicit ArithVec(T _a)
57
		explicit ArithVec(T _a)
54
		{
58
		{
55
			for_all_i(data[i] = _a);
59
			std::fill_n(data, N, _a);
56
		}
60
		}
57
 
61
 
58
		/// Construct a 2D vector 
62
		/// Construct a 2D vector 
59
		ArithVec(T _a, T _b)
63
		ArithVec(T _a, T _b)
60
		{
64
		{
Line 122... Line 126...
122
		}
126
		}
123
 
127
 
124
		/// Const index operator
128
		/// Const index operator
125
		const T& operator [] ( int i ) const
129
		const T& operator [] ( int i ) const
126
		{
130
		{
127
			assert(i<N);
131
		  //assert(i<N);
128
			return data[i];
132
			return data[i];
129
		}
133
		}
130
 
134
 
131
		/// Non-const index operator
135
		/// Non-const index operator
132
		T& operator [] ( int i ) 
136
		T& operator [] ( int i ) 
133
		{
137
		{
134
			assert(i<N);
138
		  //assert(i<N);
135
			return data[i];
139
			return data[i];
136
		}
140
		}
137
 
141
 
138
		/** Get a pointer to first element in data array.
142
		/** Get a pointer to first element in data array.
139
				This function may be useful when interfacing with some other API 
143
				This function may be useful when interfacing with some other API 
Line 150... Line 154...
150
		//----------------------------------------------------------------------
154
		//----------------------------------------------------------------------
151
 
155
 
152
		/// Equality operator
156
		/// Equality operator
153
		bool operator==(const V& v) const 
157
		bool operator==(const V& v) const 
154
		{
158
		{
155
			for_all_i(if (data[i] != v[i]) return false)
159
		  return std::inner_product(data, &data[N], v.get(), true,
156
				return true;
160
					    std::logical_and<bool>(), std::equal_to<T>());
157
		}
161
		}
158
 
162
 
159
		/// Equality wrt scalar. True if all coords are equal to scalar
163
		/// Equality wrt scalar. True if all coords are equal to scalar
160
		bool operator==(T k) const 
164
		bool operator==(T k) const 
161
		{ 
165
		{ 
Line 164... Line 168...
164
		}
168
		}
165
 
169
 
166
		/// Inequality operator
170
		/// Inequality operator
167
		bool operator!=(const V& v) const 
171
		bool operator!=(const V& v) const 
168
		{
172
		{
169
			return !(*this==v);
173
		  return std::inner_product(data, &data[N], v.get(), false,
-
 
174
					    std::logical_or<bool>(), std::not_equal_to<T>());
170
		}
175
		}
171
 
176
 
172
		/// Inequality wrt scalar. True if any coord not equal to scalar
177
		/// Inequality wrt scalar. True if any coord not equal to scalar
173
		bool operator!=(T k) const 
178
		bool operator!=(T k) const 
174
		{ 
179
		{ 
Line 182... Line 187...
182
 
187
 
183
		/** Compare all coordinates against other vector. ( < )
188
		/** Compare all coordinates against other vector. ( < )
184
				Similar to testing whether we are on one side of three planes. */
189
				Similar to testing whether we are on one side of three planes. */
185
		bool  all_l  (const V& v) const
190
		bool  all_l  (const V& v) const
186
		{
191
		{
187
			for_all_i(if (data[i] >= v[i]) return false)
192
		  return std::inner_product(data, &data[N], v.get(), true, 
188
				return true;
193
					    std::logical_and<bool>(), std::less<T>());
189
		}
194
		}
190
 
195
 
191
		/** Compare all coordinates against other vector. ( <= )
196
		/** Compare all coordinates against other vector. ( <= )
192
				Similar to testing whether we are on one side of three planes. */
197
				Similar to testing whether we are on one side of three planes. */
193
		bool  all_le (const V& v) const
198
		bool  all_le (const V& v) const
194
		{
199
		{
195
			for_all_i(if (data[i] > v[i]) return false)
200
		  return std::inner_product(data, &data[N], v.get(), true, 
196
				return true;
201
					    std::logical_and<bool>(), std::less_equal<T>());
197
		}
202
		}
198
 
203
 
199
		/** Compare all coordinates against other vector. ( > )
204
		/** Compare all coordinates against other vector. ( > )
200
				Similar to testing whether we are on one side of three planes. */
205
				Similar to testing whether we are on one side of three planes. */
201
		bool  all_g  (const V& v) const
206
		bool  all_g  (const V& v) const
202
		{
207
		{
203
			for_all_i(if (data[i] <= v[i]) return false)
208
		  return std::inner_product(data, &data[N], v.get(), true, 
204
				return true;
209
					    std::logical_and<bool>(), std::greater<T>());
205
		}
210
		}
206
 
211
 
207
		/** Compare all coordinates against other vector. ( >= )
212
		/** Compare all coordinates against other vector. ( >= )
208
				Similar to testing whether we are on one side of three planes. */
213
				Similar to testing whether we are on one side of three planes. */
209
		bool  all_ge (const V& v) const
214
		bool  all_ge (const V& v) const
210
		{
215
		{
211
			for_all_i(if (data[i] < v[i]) return false);
216
		  return std::inner_product(data, &data[N], v.get(), true, 
212
			return true;
217
					    std::logical_and<bool>(), std::greater_equal<T>());
213
		}
218
		}
214
 
219
 
215
 
220
 
216
		//----------------------------------------------------------------------
221
		//----------------------------------------------------------------------
217
		// Assignment operators
222
		// Assignment operators
218
		//----------------------------------------------------------------------
223
		//----------------------------------------------------------------------
219
 
224
 
220
		/// Assigment multiplication with scalar.
225
		/// Assigment multiplication with scalar.
221
		const V& operator *=(T k) 
226
		const V& operator *=(T k) 
222
			{ 
227
		{ 
223
				for_all_i(data[i] *= k); 
228
		  std::transform(data, &data[N], data, std::bind2nd(std::multiplies<T>(), k));
224
				return static_cast<const V&>(*this);
229
		  return static_cast<const V&>(*this);
225
			}
230
		}
226
 
231
 
227
		/// Assignment division with scalar.
232
		/// Assignment division with scalar.
228
		const V& operator /=(T k)
233
		const V& operator /=(T k)
229
			{ 
234
		{ 
230
				for_all_i(data[i] /= k); 
235
		  std::transform(data, &data[N], data, std::bind2nd(std::divides<T>(), k));
231
				return static_cast<const V&>(*this);
236
		  return static_cast<const V&>(*this);
232
			}
237
		}
233
 
238
 
234
		/// Assignment addition with scalar. Adds scalar to each coordinate.
239
		/// Assignment addition with scalar. Adds scalar to each coordinate.
235
		const V& operator +=(T k) 
240
		const V& operator +=(T k) 
236
			{
241
		{
237
				for_all_i(data[i] += k); 
242
		  std::transform(data, &data[N], data, std::bind2nd(std::plus<T>(), k));
238
				return  static_cast<const V&>(*this);
243
		  return  static_cast<const V&>(*this);
239
			}
244
		}
240
 
245
 
241
		/// Assignment subtraction with scalar. Subtracts scalar from each coord.
246
		/// Assignment subtraction with scalar. Subtracts scalar from each coord.
242
		const V& operator -=(T k) 
247
		const V& operator -=(T k) 
243
			{ 
248
		{ 
244
				for_all_i(data[i] -= k); 
249
		  std::transform(data, &data[N], data, std::bind2nd(std::minus<T>(), k));
245
				return  static_cast<const V&>(*this);
250
		  return  static_cast<const V&>(*this);
246
			}
251
		}
247
 
252
 
248
		/** Assignment multiplication with vector. 
253
		/** Assignment multiplication with vector. 
249
				Multiply each coord independently. */
254
				Multiply each coord independently. */
250
		const V& operator *=(const V& v) 
255
		const V& operator *=(const V& v) 
251
			{ 
256
		{ 
252
				for_all_i(data[i] *= v[i]); 
257
		  std::transform(data, &data[N], v.get(), data, std::multiplies<T>());
253
				return  static_cast<const V&>(*this);
258
		  return  static_cast<const V&>(*this);
254
			}
259
		}
255
 
260
 
256
		/// Assigment division with vector. Each coord divided independently.
261
		/// Assigment division with vector. Each coord divided independently.
257
		const V& operator /=(const V& v)
262
		const V& operator /=(const V& v)
258
			{
263
		{
259
				for_all_i(data[i] /= v[i]); 
264
		  std::transform(data, &data[N], v.get(), data, std::divides<T>());
260
				return  static_cast<const V&>(*this);
265
		  return  static_cast<const V&>(*this);
261
			}
266
		}
262
 
267
 
263
		/// Assignmment addition with vector.
268
		/// Assignmment addition with vector.
264
		const V& operator +=(const V& v) 
269
		const V& operator +=(const V& v) 
265
			{
270
		  {
266
				for_all_i(data[i] += v[i]); 
271
		    std::transform(data, &data[N], v.get(), data, std::plus<T>());
267
				return  static_cast<const V&>(*this);
272
		    return  static_cast<const V&>(*this);
268
			}
273
		  }
269
		
274
		
270
		/// Assignment subtraction with vector.
275
		/// Assignment subtraction with vector.
271
			const V& operator -=(const V& v) 
276
		const V& operator -=(const V& v) 
272
				{ 
277
		{ 
273
					for_all_i(data[i] -= v[i]); 
278
		  std::transform(data, &data[N], v.get(), data, std::minus<T>());
274
					return  static_cast<const V&>(*this);
279
		  return  static_cast<const V&>(*this);
275
				}
280
		}
276
 
281
 
277
 
282
 
278
		//----------------------------------------------------------------------
283
		//----------------------------------------------------------------------
Line 281... Line 286...
281
 
286
 
282
		/// Negate vector.
287
		/// Negate vector.
283
		const V operator - () const
288
		const V operator - () const
284
		{
289
		{
285
			V v_new;
290
			V v_new;
286
			for_all_i(v_new[i] = - data[i]);
291
			std::transform(data, &data[N], v_new.get(), std::negate<T>());
287
			return v_new;
292
			return v_new;
288
		}
293
		}
289
 
294
 
290
		//----------------------------------------------------------------------
295
		//----------------------------------------------------------------------
291
		// Binary operators on vectors
296
		// Binary operators on vectors
292
		//----------------------------------------------------------------------
297
		//----------------------------------------------------------------------
293
 
298
 
294
		/** Multiply vector with vector. Each coord multiplied independently
299
		/** Multiply vector with vector. Each coord multiplied independently
295
				Do not confuse this operation with dot product. */
300
				Do not confuse this operation with dot product. */
296
		const V operator * (const V& v1) const
301
		const V operator * (const V& v) const
297
		{
302
		{
298
			V v_new;
303
		  V v_new;
299
			for_all_i(v_new[i] = data[i] * v1[i]);
304
		  std::transform(data, &data[N], v.get(), v_new.get(), std::multiplies<T>());
300
			return v_new;
305
		  return v_new;
301
		}
306
		}
302
 
307
 
303
		/// Add two vectors
308
		/// Add two vectors
304
		const V operator + (const V& v1) const
309
		const V operator + (const V& v) const
305
		{
310
		{
306
			V v_new;
311
		  V v_new;
307
			for_all_i(v_new[i] = data[i] + v1[i]);
312
		  std::transform(data, &data[N], v.get(), v_new.get(), std::plus<T>());
308
			return v_new;
313
		  return v_new;
309
		}
314
		}
310
 
315
 
311
		/// Subtract two vectors. 
316
		/// Subtract two vectors. 
312
		const V operator - (const V& v1) const
317
		const V operator - (const V& v) const
313
		{
318
		{
314
			V v_new;
319
		  V v_new;
315
			for_all_i(v_new[i] = data[i] - v1[i]);
320
		  std::transform(data, &data[N], v.get(), v_new.get(), std::minus<T>());
316
			return v_new;
321
		  return v_new;
317
		}
322
		}
318
 
323
 
319
		/// Divide two vectors. Each coord separately
324
		/// Divide two vectors. Each coord separately
320
		const V operator / (const V& v1) const
325
		const V operator / (const V& v1) const
321
		{
326
		{
322
			V v_new;
327
		  V v_new;
323
			for_all_i(v_new[i] = data[i] / v1[i]);
328
		  std::transform(data, &data[N], v.get(), v_new.get(), std::divides<T>());
324
			return v_new;
329
		  return v_new;
325
		}
330
		}
326
 
331
 
327
		//----------------------------------------------------------------------
332
		//----------------------------------------------------------------------
328
		// Binary operators on vector and scalar
333
		// Binary operators on vector and scalar
Line 330... Line 335...
330
 
335
 
331
		/// Multiply scalar onto vector.
336
		/// Multiply scalar onto vector.
332
		const V operator * (T k) const
337
		const V operator * (T k) const
333
		{
338
		{
334
			V v_new;
339
		  V v_new;
335
			for_all_i(v_new[i] = data[i] * k);
340
		  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::multiplies<T>(), k));
336
			return v_new;
341
		  return v_new;
337
		}
342
		}
338
  
343
  
339
 
344
 
340
		/// Divide vector by scalar.
345
		/// Divide vector by scalar.
341
		const V operator / (T k) const
346
		const V operator / (T k) const
342
		{
347
		{
343
			V v_new;
348
		  V v_new;
344
			for_all_i(v_new[i] = data[i] / k);
349
		  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::divides<T>(), k));
345
			return v_new;      
350
		  return v_new;      
346
		}
351
		}
347
 
352
 
348
 
353
 
349
		/// Return the smallest coordinate of the vector
354
		/// Return the smallest coordinate of the vector
Line 364... Line 369...
364
 
369
 
365
#undef for_all_i  
370
#undef for_all_i  
366
	};
371
	};
367
 
372
 
368
	template <class T, class V, int N> 
373
	template <class T, class V, int N> 
369
	inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
374
	std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
370
	{
375
	{
371
		os << "[ ";
376
		os << "[ ";
372
		for(int i=0;i<N;i++) os << v[i] << " ";
377
		for(int i=0;i<N;i++) os << v[i] << " ";
373
		os << "]";
378
		os << "]";
374
		return os;
379
		return os;
375
	}
380
	}
376
 
381
 
377
	/// Get from operator for ArithVec descendants. 
382
	/// Get from operator for ArithVec descendants. 
378
	template <class T,class V, int N>
383
	template <class T,class V, int N>
379
	inline std::istream& operator>>(std::istream&is, ArithVec<T,V,N>& v)
384
	std::istream& operator>>(std::istream&is, ArithVec<T,V,N>& v)
380
	{
385
	{
381
		for(int i=0;i<N;i++) is>>v[i];
386
		for(int i=0;i<N;i++) is>>v[i];
382
		return is;
387
		return is;
383
	}
388
	}
384
 
389
 
Line 386... Line 391...
386
	/** Dot product for two vectors. The `*' operator is 
391
	/** Dot product for two vectors. The `*' operator is 
387
			reserved for coordinatewise	multiplication of vectors. */
392
			reserved for coordinatewise	multiplication of vectors. */
388
	template <class T,class V, int N>
393
	template <class T,class V, int N>
389
	inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
394
	inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
390
	{
395
	{
391
		T x = 0;
-
 
392
		for(int i=0;i<N;i++) x += v0[i]*v1[i];
396
	  return std::inner_product(v0.get(), &v0[N], v1.get(), 0);
393
		return x;
-
 
394
	}
397
	}
395
 
398
 
396
	/** Compute the sqr length by taking dot product of vector with itself. */
399
	/** Compute the sqr length by taking dot product of vector with itself. */
397
	template <class T,class V, int N>
400
	template <class T,class V, int N>
398
	inline T sqr_length(const ArithVec<T,V,N>& v)
401
	inline T sqr_length(const ArithVec<T,V,N>& v)
Line 444... Line 447...
444
	inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
447
	inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
445
	{
448
	{
446
		V v;
449
		V v;
447
		for(int i=0;i<N;i++)
450
		for(int i=0;i<N;i++)
448
		v[i] = s_min(v0[i],v1[i]);
451
		v[i] = s_min(v0[i],v1[i]);
-
 
452
      //std::transform(v0.get(), &v0[N], v1.get(), v_new.get(), std::ptr_fun(std::min));
449
		return v;
453
		return v;
450
	}
454
	}
451
 
455
 
452
	/** Returns the vector containing for each coordinate the largest 
456
	/** Returns the vector containing for each coordinate the largest 
453
			value from two vectors. */
457
			value from two vectors. */
Line 455... Line 459...
455
	inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
459
	inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
456
	{
460
	{
457
		V v;
461
		V v;
458
		for(int i=0;i<N;i++) 
462
		for(int i=0;i<N;i++) 
459
		v[i] = s_max(v0[i],v1[i]);
463
		v[i] = s_max(v0[i],v1[i]);
-
 
464
      //std::transform(v0.get(), &v0[N], v1.get(), v_new.get(), std::ptr_fun(std::max));
460
		return v;
465
		return v;
461
	}
466
	}
462
 
467
 
463
 
468
 
464
}
469
}