Subversion Repositories gelsvn

Rev

Rev 18 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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