Subversion Repositories gelsvn

Rev

Rev 12 | Rev 45 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 12 Rev 43
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>
7
 
8
 
8
namespace CGLA 
9
namespace CGLA 
9
{
10
{
10
 
11
 
11
  /** The ArithVec class template represents a generic arithmetic
12
  /** The ArithVec class template represents a generic arithmetic
Line 29... Line 30...
29
  */
30
  */
30
 
31
 
31
  template <class T, class V, int N> 
32
  template <class T, class V, int N> 
32
    class ArithVec
33
    class ArithVec
33
    {
34
    {
34
#define for_all_i(expr) for(int i=0;i<N;i++) {expr;}
-
 
35
 
35
 
36
    protected:
36
    protected:
37
 
37
 
38
      /// The actual contents of the vector.
38
      /// The actual contents of the vector.
39
      T data[N];
39
      T data[N];
Line 50... Line 50...
50
	}
50
	}
51
 
51
 
52
      /// Construct a vector where all coordinates are identical
52
      /// Construct a vector where all coordinates are identical
53
      explicit ArithVec(T _a)
53
      explicit ArithVec(T _a)
54
	{
54
	{
55
	  for_all_i(data[i] = _a);
55
	  std::fill_n(data, N, _a);
56
	}
56
	}
57
 
57
 
58
      /// Construct a 2D vector 
58
      /// Construct a 2D vector 
59
      ArithVec(T _a, T _b)
59
      ArithVec(T _a, T _b)
60
	{
60
	{
Line 150... Line 150...
150
      //----------------------------------------------------------------------
150
      //----------------------------------------------------------------------
151
 
151
 
152
      /// Equality operator
152
      /// Equality operator
153
      bool operator==(const V& v) const 
153
      bool operator==(const V& v) const 
154
	{
154
	{
155
	  for_all_i(if (data[i] != v[i]) return false)
155
	  return std::inner_product(data, &data[N], v.get(), true,
156
	    return true;
156
				    std::logical_and<bool>(), std::equal_to<T>());
157
	}
157
	}
158
 
158
 
-
 
159
#define for_all_i(expr) for(int i=0;i<N;i++) {expr;}
159
      /// Equality wrt scalar. True if all coords are equal to scalar
160
      /// Equality wrt scalar. True if all coords are equal to scalar
160
      bool operator==(T k) const 
161
      bool operator==(T k) const 
161
	{ 
162
	{ 
162
	  for_all_i(if (data[i] != k) return false)
163
	  for_all_i(if (data[i] != k) return false)
163
	    return true;
164
	    return true;
164
	}
165
	}
-
 
166
#undef for_all_i  
165
 
167
 
166
      /// Inequality operator
168
      /// Inequality operator
167
      bool operator!=(const V& v) const 
169
      bool operator!=(const V& v) const 
168
	{
170
	{
169
	  return !(*this==v);
171
	  return std::inner_product(data, &data[N], v.get(), false,
-
 
172
				    std::logical_or<bool>(), std::not_equal_to<T>());
170
	}
173
	}
171
 
174
 
172
      /// Inequality wrt scalar. True if any coord not equal to scalar
175
      /// Inequality wrt scalar. True if any coord not equal to scalar
173
      bool operator!=(T k) const 
176
      bool operator!=(T k) const 
174
	{ 
177
	{ 
Line 182... Line 185...
182
 
185
 
183
      /** Compare all coordinates against other vector. ( < )
186
      /** Compare all coordinates against other vector. ( < )
184
	  Similar to testing whether we are on one side of three planes. */
187
	  Similar to testing whether we are on one side of three planes. */
185
      bool  all_l  (const V& v) const
188
      bool  all_l  (const V& v) const
186
	{
189
	{
187
	  for_all_i(if (data[i] >= v[i]) return false)
190
	  return std::inner_product(data, &data[N], v.get(), true, 
188
	    return true;
191
				    std::logical_and<bool>(), std::less<T>());
189
	}
192
	}
190
 
193
 
191
      /** Compare all coordinates against other vector. ( <= )
194
      /** Compare all coordinates against other vector. ( <= )
192
	  Similar to testing whether we are on one side of three planes. */
195
	  Similar to testing whether we are on one side of three planes. */
193
      bool  all_le (const V& v) const
196
      bool  all_le (const V& v) const
194
	{
197
	{
195
	  for_all_i(if (data[i] > v[i]) return false)
198
	  return std::inner_product(data, &data[N], v.get(), true, 
196
	    return true;
199
				    std::logical_and<bool>(), std::less_equal<T>());
197
	}
200
	}
198
 
201
 
199
      /** Compare all coordinates against other vector. ( > )
202
      /** Compare all coordinates against other vector. ( > )
200
	  Similar to testing whether we are on one side of three planes. */
203
	  Similar to testing whether we are on one side of three planes. */
201
      bool  all_g  (const V& v) const
204
      bool  all_g  (const V& v) const
202
	{
205
	{
203
	  for_all_i(if (data[i] <= v[i]) return false)
206
	  return std::inner_product(data, &data[N], v.get(), true, 
204
	    return true;
207
				    std::logical_and<bool>(), std::greater<T>());
205
	}
208
	}
206
 
209
 
207
      /** Compare all coordinates against other vector. ( >= )
210
      /** Compare all coordinates against other vector. ( >= )
208
	  Similar to testing whether we are on one side of three planes. */
211
	  Similar to testing whether we are on one side of three planes. */
209
      bool  all_ge (const V& v) const
212
      bool  all_ge (const V& v) const
210
	{
213
	{
211
	  for_all_i(if (data[i] < v[i]) return false);
214
	  return std::inner_product(data, &data[N], v.get(), true, 
212
	  return true;
215
				    std::logical_and<bool>(), std::greater_equal<T>());
213
	}
216
	}
214
 
217
 
215
 
218
 
216
      //----------------------------------------------------------------------
219
      //----------------------------------------------------------------------
217
      // Assignment operators
220
      // Assignment operators
218
      //----------------------------------------------------------------------
221
      //----------------------------------------------------------------------
219
 
222
 
220
      /// Assigment multiplication with scalar.
223
      /// Assignment multiplication with scalar.
221
      const V& operator *=(T k) 
224
      const V& operator *=(T k) 
222
	{ 
225
	{ 
223
	  for_all_i(data[i] *= k); 
226
	  std::transform(data, &data[N], data, std::bind2nd(std::multiplies<T>(), k));
224
	  return static_cast<const V&>(*this);
227
	  return static_cast<const V&>(*this);
225
	}
228
	}
226
 
229
 
227
      /// Assignment division with scalar.
230
      /// Assignment division with scalar.
228
      const V& operator /=(T k)
231
      const V& operator /=(T k)
229
	{ 
232
	{ 
230
	  for_all_i(data[i] /= k); 
233
	  std::transform(data, &data[N], data, std::bind2nd(std::divides<T>(), k));
231
	  return static_cast<const V&>(*this);
234
	  return static_cast<const V&>(*this);
232
	}
235
	}
233
 
236
 
234
      /// Assignment addition with scalar. Adds scalar to each coordinate.
237
      /// Assignment addition with scalar. Adds scalar to each coordinate.
235
      const V& operator +=(T k) 
238
      const V& operator +=(T k) 
236
	{
239
	{
237
	  for_all_i(data[i] += k); 
240
	  std::transform(data, &data[N], data, std::bind2nd(std::plus<T>(), k));
238
	  return  static_cast<const V&>(*this);
241
	  return  static_cast<const V&>(*this);
239
	}
242
	}
240
 
243
 
241
      /// Assignment subtraction with scalar. Subtracts scalar from each coord.
244
      /// Assignment subtraction with scalar. Subtracts scalar from each coord.
242
      const V& operator -=(T k) 
245
      const V& operator -=(T k) 
243
	{ 
246
	{ 
244
	  for_all_i(data[i] -= k); 
247
	  std::transform(data, &data[N], data, std::bind2nd(std::minus<T>(), k));
245
	  return  static_cast<const V&>(*this);
248
	  return  static_cast<const V&>(*this);
246
	}
249
	}
247
 
250
 
248
      /** Assignment multiplication with vector. 
251
      /** Assignment multiplication with vector. 
249
	  Multiply each coord independently. */
252
	  Multiply each coord independently. */
250
      const V& operator *=(const V& v) 
253
      const V& operator *=(const V& v) 
251
	{ 
254
	{ 
252
	  for_all_i(data[i] *= v[i]); 
255
	  std::transform(data, &data[N], v.get(), data, std::multiplies<T>());
253
	  return  static_cast<const V&>(*this);
256
	  return  static_cast<const V&>(*this);
254
	}
257
	}
255
 
258
 
256
      /// Assigment division with vector. Each coord divided independently.
259
      /// Assigment division with vector. Each coord divided independently.
257
      const V& operator /=(const V& v)
260
      const V& operator /=(const V& v)
258
	{
261
	{
259
	  for_all_i(data[i] /= v[i]); 
262
	  std::transform(data, &data[N], v.get(), data, std::divides<T>());
260
	  return  static_cast<const V&>(*this);
263
	  return  static_cast<const V&>(*this);
261
	}
264
	}
262
 
265
 
263
      /// Assignmment addition with vector.
266
      /// Assignmment addition with vector.
264
      const V& operator +=(const V& v) 
267
      const V& operator +=(const V& v) 
265
	{
268
	{
266
	  for_all_i(data[i] += v[i]); 
269
	  std::transform(data, &data[N], v.get(), data, std::plus<T>());
267
	  return  static_cast<const V&>(*this);
270
	  return  static_cast<const V&>(*this);
268
	}
271
	}
269
		
272
		
270
      /// Assignment subtraction with vector.
273
      /// Assignment subtraction with vector.
271
      const V& operator -=(const V& v) 
274
      const V& operator -=(const V& v) 
272
	{ 
275
	{ 
273
	  for_all_i(data[i] -= v[i]); 
276
	  std::transform(data, &data[N], v.get(), data, std::minus<T>());
274
	  return  static_cast<const V&>(*this);
277
	  return  static_cast<const V&>(*this);
275
	}
278
	}
276
 
279
 
277
 
280
 
278
      //----------------------------------------------------------------------
281
      //----------------------------------------------------------------------
Line 281... Line 284...
281
 
284
 
282
      /// Negate vector.
285
      /// Negate vector.
283
      const V operator - () const
286
      const V operator - () const
284
	{
287
	{
285
	  V v_new;
288
	  V v_new;
286
	  for_all_i(v_new[i] = - data[i]);
289
	  std::transform(data, &data[N], v_new.get(), std::negate<T>());
287
	  return v_new;
290
	  return v_new;
288
	}
291
	}
289
 
292
 
290
      //----------------------------------------------------------------------
293
      //----------------------------------------------------------------------
291
      // Binary operators on vectors
294
      // Binary operators on vectors
Line 294... Line 297...
294
      /** Multiply vector with vector. Each coord multiplied independently
297
      /** Multiply vector with vector. Each coord multiplied independently
295
	  Do not confuse this operation with dot product. */
298
	  Do not confuse this operation with dot product. */
296
      const V operator * (const V& v1) const
299
      const V operator * (const V& v1) const
297
	{
300
	{
298
	  V v_new;
301
	  V v_new;
299
	  for_all_i(v_new[i] = data[i] * v1[i]);
302
	  std::transform(data, &data[N], v1.get(), v_new.get(), std::multiplies<T>());
300
	  return v_new;
303
	  return v_new;
301
	}
304
	}
302
 
305
 
303
      /// Add two vectors
306
      /// Add two vectors
304
      const V operator + (const V& v1) const
307
      const V operator + (const V& v1) const
305
	{
308
	{
306
	  V v_new;
309
	  V v_new;
307
	  for_all_i(v_new[i] = data[i] + v1[i]);
310
	  std::transform(data, &data[N], v1.get(), v_new.get(), std::plus<T>());
308
	  return v_new;
311
	  return v_new;
309
	}
312
	}
310
 
313
 
311
      /// Subtract two vectors. 
314
      /// Subtract two vectors. 
312
      const V operator - (const V& v1) const
315
      const V operator - (const V& v1) const
313
	{
316
	{
314
	  V v_new;
317
	  V v_new;
315
	  for_all_i(v_new[i] = data[i] - v1[i]);
318
	  std::transform(data, &data[N], v1.get(), v_new.get(), std::minus<T>());
316
	  return v_new;
319
	  return v_new;
317
	}
320
	}
318
 
321
 
319
      /// Divide two vectors. Each coord separately
322
      /// Divide two vectors. Each coord separately
320
      const V operator / (const V& v1) const
323
      const V operator / (const V& v1) const
321
	{
324
	{
322
	  V v_new;
325
	  V v_new;
323
	  for_all_i(v_new[i] = data[i] / v1[i]);
326
	  std::transform(data, &data[N], v1.get(), v_new.get(), std::divides<T>());
324
	  return v_new;
327
	  return v_new;
325
	}
328
	}
326
 
329
 
327
      //----------------------------------------------------------------------
330
      //----------------------------------------------------------------------
328
      // Binary operators on vector and scalar
331
      // Binary operators on vector and scalar
Line 330... Line 333...
330
 
333
 
331
      /// Multiply scalar onto vector.
334
      /// Multiply scalar onto vector.
332
      const V operator * (T k) const
335
      const V operator * (T k) const
333
	{
336
	{
334
	  V v_new;
337
	  V v_new;
335
	  for_all_i(v_new[i] = data[i] * k);
338
	  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::multiplies<T>(), k));
336
	  return v_new;
339
	  return v_new;
337
	}
340
	}
338
  
341
  
339
 
342
 
340
      /// Divide vector by scalar.
343
      /// Divide vector by scalar.
341
      const V operator / (T k) const
344
      const V operator / (T k) const
342
	{
345
	{
343
	  V v_new;
346
	  V v_new;
344
	  for_all_i(v_new[i] = data[i] / k);
347
	  std::transform(data, &data[N], v_new.get(), std::bind2nd(std::divides<T>(), k));
345
	  return v_new;      
348
	  return v_new;      
346
	}
349
	}
347
 
350
 
348
 
351
 
349
      /// Return the smallest coordinate of the vector
352
      /// Return the smallest coordinate of the vector
350
      const T min_coord() const 
353
      const T min_coord() const 
351
	{
354
	{
352
	  T t = data[0];
-
 
353
	  for_all_i(t = s_min(t, data[i]));
355
	  return *std::min_element(data, &data[N]);
354
	  return t;
-
 
355
	}
356
	}
356
 
357
 
357
      /// Return the largest coordinate of the vector
358
      /// Return the largest coordinate of the vector
358
      const T max_coord() const
359
      const T max_coord() const
359
	{
360
	{
360
	  T t = data[0];
-
 
361
	  for_all_i(t = s_max(t, data[i]));
361
	  return *std::max_element(data, &data[N]);
362
	  return t;
-
 
363
	}
362
	}
364
 
363
 
365
#undef for_all_i  
-
 
366
    };
364
    };
367
 
365
 
368
  template <class T, class V, int N> 
366
  template <class T, class V, int N> 
369
    inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
367
    inline std::ostream& operator<<(std::ostream&os, const ArithVec<T,V,N>& v)
370
    {
368
    {
Line 386... Line 384...
386
  /** Dot product for two vectors. The `*' operator is 
384
  /** Dot product for two vectors. The `*' operator is 
387
      reserved for coordinatewise	multiplication of vectors. */
385
      reserved for coordinatewise	multiplication of vectors. */
388
  template <class T,class V, int N>
386
  template <class T,class V, int N>
389
    inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
387
    inline T dot(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
390
    {
388
    {
391
      T x = 0;
-
 
392
      for(int i=0;i<N;i++) x += v0[i]*v1[i];
389
      return std::inner_product(v0.get(), v0.get() + N, v1.get(), T(0));
393
      return x;
-
 
394
    }
390
    }
395
 
391
 
396
  /** Compute the sqr length by taking dot product of vector with itself. */
392
  /** Compute the sqr length by taking dot product of vector with itself. */
397
  template <class T,class V, int N>
393
  template <class T,class V, int N>
398
    inline T sqr_length(const ArithVec<T,V,N>& v)
394
    inline T sqr_length(const ArithVec<T,V,N>& v)
Line 442... Line 438...
442
      value from two vectors. */
438
      value from two vectors. */
443
  template <class T,class V, int N>
439
  template <class T,class V, int N>
444
    inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
440
    inline V v_min(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
445
    {
441
    {
446
      V v;
442
      V v;
447
      for(int i=0;i<N;i++)
443
      std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_min<T>));
448
	v[i] = s_min(v0[i],v1[i]);
-
 
449
      return v;
444
      return v;
450
    }
445
    }
451
 
446
 
452
  /** Returns the vector containing for each coordinate the largest 
447
  /** Returns the vector containing for each coordinate the largest 
453
      value from two vectors. */
448
      value from two vectors. */
454
  template <class T,class V, int N>
449
  template <class T,class V, int N>
455
    inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
450
    inline V v_max(const ArithVec<T,V,N>& v0, const ArithVec<T,V,N>& v1)
456
    {
451
    {
457
      V v;
452
      V v;
458
      for(int i=0;i<N;i++) 
453
      std::transform(v0.get(), v0.get() + N, v1.get(), v.get(), std::ptr_fun(s_max<T>));
459
	v[i] = s_max(v0[i],v1[i]);
-
 
460
      return v;
454
      return v;
461
    }
455
    }
462
 
456
 
463
 
457
 
464
}
458
}