KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
m_vector_d.impl.h
Go to the documentation of this file.
1 /* $Id: m_vector_d.impl.h 18975 2015-04-30 18:10:29Z ernesto $ */
2 /* {{{=========================================================================== *
3  |
4  | Copyright (c) 1994-2011 by Kobus Barnard (author)
5  |
6  | Personal and educational use of this code is granted, provided that this
7  | header is kept intact, and that the authorship is not misrepresented, that
8  | its use is acknowledged in publications, and relevant papers are cited.
9  |
10  | For other use contact the author (kobus AT cs DOT arizona DOT edu).
11  |
12  | Please note that the code in this file has not necessarily been adequately
13  | tested. Naturally, there is no guarantee of performance, support, or fitness
14  | for any particular task. Nonetheless, I am interested in hearing about
15  | problems that you encounter.
16  |
17  | Author: Kyle Simek
18  * =========================================================================== }}}*/
19 
20 // vim: tabstop=4 shiftwidth=4 foldmethod=marker
21 
22 #ifndef KJB_M_VECTOR_D_IMPL_H
23 #define KJB_M_VECTOR_D_IMPL_H
24 
25 #include <l_cpp/l_exception.h>
26 #include <l/l_sys_rand.h> /* for kjb_rand() */
27 #include <sample/sample_gauss.h> /* for kjb_rand() */
28 #include <boost/array.hpp>
29 #include <algorithm>
30 #include <numeric>
31 #include <iterator>
32 
33 #include <iomanip>
34 
35 #include <m_cpp/m_vector.h>
36 #include <m_cpp/m_matrix.h>
37 
38 #ifdef KJB_HAVE_BST_SERIAL
39 #include <boost/serialization/array.hpp>
40 #endif
41 
42 namespace kjb
43 {
44 
45 template <size_t D>
47  Base()
48 {}
49 
50 template <size_t D>
52  Base()
53 {
54  std::copy(v.begin(), v.end(), this->begin());
55 }
56 
57 template <size_t D>
58 Vector_d<D>::Vector_d(const Vector_d<D-1>& v, double fill1) :
59  Base()
60 {
61  std::copy(v.begin(), v.end(), this->begin());
62  this->operator[](D-1) = fill1;
63 }
64 
65 template <size_t D>
66 Vector_d<D>::Vector_d(const Vector_d<D-1>& v, double fill1, double fill2) :
67  Base()
68 {
69  std::copy(v.begin(), v.end(), this->begin());
70  this->operator[](D-2) = fill1;
71  this->operator[](D-1) = fill2;
72 }
73 
75 template <size_t D>
77  Base()
78 {
79  if (v.size() != D)
80  {
81  KJB_THROW_3(Illegal_argument, "Cannot construct Vector_d<%d> from Vector of length %d", (D)(v.size()));
82  }
83 
84  std::copy(v.begin(), v.end(), this->begin());
85 }
86 
87 template <size_t D>
89  Base()
90 {
91  this->assign(x);
92 }
93 
94 template <size_t D>
95 Vector_d<D>::Vector_d(double x, double y) :
96  Base()
97 {
98  assert(D == 2);
99  this->operator[](0) = x;
100  this->operator[](1) = y;
101 }
102 
106 template <size_t D>
107 Vector_d<D>::Vector_d(double x, double y, double z) :
108  Base()
109 {
110  assert(D == 3);
111  this->operator[](0) = x;
112  this->operator[](1) = y;
113  this->operator[](2) = z;
114 }
115 
119 template <size_t D>
120 Vector_d<D>::Vector_d( double x, double y, double z, double w)
121 {
122  assert(D == 4);
123  this->operator[](0) = x;
124  this->operator[](1) = y;
125  this->operator[](2) = z;
126  this->operator[](3) = w;
127 }
128 
133 template <size_t D>
134 double Vector_d<D>::x() const
135 {
136  if (D < 1)
137  {
138  KJB_THROW_2(Runtime_error, "Can't get x: vector dimension < 1");
139  }
140 
141  return this->operator[](0);
142 }
143 
148 template <size_t D>
149 double& Vector_d<D>::x()
150 {
151  if (D < 1)
152  {
153  KJB_THROW_2(Runtime_error, "Can't set x: vector dimension < 1");
154  }
155  return this->operator[](0);
156 }
157 
158 template <size_t D>
159 void Vector_d<D>::set_x(double xv)
160 {
161  x() = xv;
162 }
163 
168 template <size_t D>
169 double Vector_d<D>::y() const
170 {
171  if (D < 2)
172  {
173  KJB_THROW_2(Runtime_error, "Can't get y: vector dimension < 1");
174  }
175 
176  return this->operator[](1);
177 }
178 
183 template <size_t D>
184 double& Vector_d<D>::y()
185 {
186  if (D < 2)
187  {
188  KJB_THROW_2(Runtime_error, "Can't set y: vector dimension < 1");
189  }
190 
191  return this->operator[](1);
192 }
193 
195 template <size_t D>
196 void Vector_d<D>::set_y(double yv)
197 {
198  y() = yv;
199 }
200 
204 template <size_t D>
205 double Vector_d<D>::z() const
206 {
207  if (D < 3)
208  {
209  KJB_THROW_2(Runtime_error, "Can't get z: vector dimension < 3");
210  }
211  return this->operator[](2);
212 }
213 
218 template <size_t D>
219 double& Vector_d<D>::z()
220 {
221  if (D < 3)
222  {
223  KJB_THROW_2(Runtime_error, "Can't set z: vector dimension < 3");
224  }
225  return this->operator[](2);
226 }
227 
229 template <size_t D>
230 void Vector_d<D>::set_z(double zv)
231 {
232  z() = zv;
233 }
234 
240 template <size_t D>
241 double Vector_d<D>::w() const
242 {
243  return this->operator[](3);
244 }
245 
250 template <size_t D>
251 double& Vector_d<D>::w()
252 {
253  if (D < 4)
254  {
255  KJB_THROW_2(Runtime_error, "Can't set w: vector dimension < 4");
256  }
257  return this->operator[](3);
258 }
259 
261 template <size_t D>
262 void Vector_d<D>::set_w(double wv) { w() = wv; }
263 
264 
266 template <size_t D>
268 {
269  Base::operator=(other);
270  return *this;
271 }
272 
274 template <size_t D>
276 {
277  if (other.size() != D)
278  {
280  }
281 
282  std::copy(other.begin(), other.end(), this->begin());
283 
284  return *this;
285 }
286 
287 
288 template <size_t D>
290 {
291  std::transform(this->begin(), this->end(), second.begin(), this->begin(), std::minus<double>());
292 
293  return *this;
294 }
295 
296 template <size_t D>
298 {
299  std::transform(this->begin(), this->end(), this->begin(), std::bind2nd(std::minus<double>(), second));
300 
301  return *this;
302 }
303 
304 template <size_t D>
306 {
307  std::transform(this->begin(), this->end(), second.begin(), this->begin(), std::plus<double>());
308 
309  return *this;
310 }
311 
312 template <size_t D>
314 {
315  std::transform(this->begin(), this->end(), this->begin(), std::bind2nd(std::plus<double>(), second));
316 
317  return *this;
318 }
319 
320 template <size_t D>
322 {
323  for (size_t i = 0; i < D; i++)
324  {
325  this->operator[](i) *= s;
326  }
327 
328  return *this;
329 }
330 
331 template <size_t D>
333 {
334  return (*this) *= 1/s;
335 }
336 
338 template <size_t D>
339 void Vector_d<D>::resize(size_t n)
340 {
341  if (n != D)
342  {
343  KJB_THROW_2(Illegal_argument, "Can't resize Vector_d.");
344  }
345 }
346 
347 template <size_t D>
348 double Vector_d<D>::norm1() const
349 {
350  double total = 0;
351 
352  for (typename Base::const_iterator it = this->begin(); it != this->end(); ++it)
353  {
354  total += fabs(*it);
355  }
356 
357  return total;
358 }
359 
361 template <size_t D>
363 {
364  return std::inner_product(this->begin(), this->end(), this->begin(), 0.0);
365 }
366 
368 template <size_t D>
370 {
371  return sqrt(magnitude_squared());
372 }
373 
375 template <size_t D>
377 {
378  *this /= this->magnitude();
379  return *this;
380 }
381 
383 template <size_t D>
385 {
386  return Vector_d<D>(*this).normalize();
387 }
388 
389 template <size_t D>
391 {
392  for (size_t i = 0; i < this->size(); ++i)
393  {
394  this->operator[](i) = -this->operator[](i);
395  }
396 
397  return *this;
398 }
399 
400 #ifdef KJB_HAVE_BST_SERIAL
401 template <size_t D>
402 template <class Archive>
403 void Vector_d<D>::serialize(Archive &ar, const unsigned int /* version */)
404 {
405  ar & ::boost::serialization::base_object<boost::array<double, D> >(*this);
406 }
407 #endif
408 
410 
412 template <std::size_t D>
414 {
415  return multiply_matrix_and_vector_d_dispatch_(m, &v[0], D);
416 }
417 
419 Vector multiply_matrix_and_vector_d_dispatch_(const Matrix& m, const double* v, size_t size);
420 
421 
422 
423 #if 0
424 // Static matrix not implemented yet
426 template <std::size_t D_out, std::size_t D_in>
427 Vector_d<D_out> operator*(const Matrix_d<D_out, D_in>& m, const Vector_d<D_in> v)
428 {
429  Vector_d<D_out> result();
430 
431  for (int row = 0; row < D_out; row++)
432  {
433  double x = 0;
434 
435  for (size_t col = 0; col < D_in; col++)
436  {
437  x += m(row, col) * v[col];
438  }
439 
440  result[row] = x;
441  }
442 
443  return result;
444 }
445 #endif
446 
447 //
449 //Vector operator*(const Vector_d<D> v, const Matrix& m)
450 //{
451 // return m.transpose() * v;
452 //}
453 
454 template <std::size_t D>
455 Vector_d<D> operator-(const Vector_d<D>& first, const Vector_d<D>& second)
456 {
457  return Vector_d<D>(first) -= second;
458 }
459 
460 template <std::size_t D>
461 Vector_d<D> operator-(const Vector_d<D>& first, double second)
462 {
463  return Vector_d<D>(first) -= second;
464 }
465 
466 template <std::size_t D>
467 Vector_d<D> operator-(double first, const Vector_d<D>& second)
468 {
469  return -second + first;
470 }
471 
472 template <std::size_t D>
474 {
475  Vector_d<D> result = first;
476  for (size_t i = 0; i < D; i++)
477  {
478  result[i] = -result[i];
479  }
480 
481  return result;
482 }
483 
484 template <std::size_t D>
485 Vector_d<D> operator+(const Vector_d<D>& first, const Vector_d<D>& second)
486 {
487  return Vector_d<D>(first) += second;
488 }
489 
490 template <std::size_t D>
491 Vector_d<D> operator+(const Vector_d<D>& first, double second)
492 {
493  return Vector_d<D>(first) += second;
494 }
495 
496 template <std::size_t D>
497 Vector_d<D> operator+(double first, const Vector_d<D>& second)
498 {
499  return second + first;
500 }
501 
502 template <std::size_t D>
503 Vector_d<D> operator*(const Vector_d<D>& v, double s)
504 {
505  return Vector_d<D>(v) *= s;
506 }
507 
508 template <std::size_t D>
509 Vector_d<D> operator*(double s, const Vector_d<D>& v)
510 {
511  return Vector_d<D>(v) *= s;
512 }
513 
514 template <std::size_t D>
515 Vector_d<D> operator/(const Vector_d<D>& v, double s)
516 {
517  return Vector_d<D>(v) /= s;
518 }
519 
520 template<std::size_t N>
521 void swap(Vector_d<N>& first, Vector_d<N>& second)
522 {
523  first.swap(second);
524 }
525 
526 // COMPARATORS
527 template<std::size_t N>
528 bool operator==(const Vector_d<N>& first, const Vector_d<N>& second)
529 {
530  // Call boost-provided operator
531  return boost::operator==<double, N>(first, second);
532 }
533 
534 template<std::size_t N>
535 bool operator!=(const Vector_d<N>& first, const Vector_d<N>& second)
536 {
537  // Call boost-provided operator
538  return boost::operator!= <double, N>(first, second);
539 }
540 
541 template<std::size_t N>
542 bool operator<(const Vector_d<N>& first, const Vector_d<N>& second)
543 {
544  // Call boost-provided operator
545  return boost::operator< <double, N>(first, second);
546 }
547 
548 template<std::size_t N>
549 bool operator>(const Vector_d<N>& first, const Vector_d<N>& second)
550 {
551  // Call boost-provided operator
552  return boost::operator> <double, N>(first, second);
553 }
554 
555 template<std::size_t N>
556 bool operator<=(const Vector_d<N>& first, const Vector_d<N>& second)
557 {
558  // Call boost-provided operator
559  return boost::operator<= <double, N>(first, second);
560 }
561 
562 template<std::size_t N>
563 bool operator>=(const Vector_d<N>& first, const Vector_d<N>& second)
564 {
565  // Call boost-provided operator
566  return boost::operator>= <double, N>(first, second);
567 }
568 
569 // TYPEDEFS
570 typedef Vector_d<2> Vector2;
571 typedef Vector_d<3> Vector3;
572 typedef Vector_d<4> Vector4;
573 
574 // MATH FUNCTIONS
575 template <size_t D>
576 double norm1(const kjb::Vector_d<D>& v)
577 {
578  return v.norm1();
579 }
580 
581 template <size_t D>
582 double norm2(const kjb::Vector_d<D>& v)
583 {
584  return v.magnitude();
585 }
586 
587 
588 // UTILITY FUNCTIONS
589 template <size_t D>
591 {
592  Vector_d<D> result;
593  std::generate(result.begin(), result.end(), kjb_c::kjb_rand);
594  return result;
595 }
596 
597 template <size_t D>
599 {
600  Vector_d<D> result;
601  std::generate(result.begin(), result.end(), kjb_c::gauss_rand);
602  return result;
603 }
604 
605 template <size_t D>
607 {
608  assert(d < D);
609  Vector_d<D> result(0.0);
610  result[d] = 1.0;
611  return result;
612 }
613 
614 template <std::size_t D>
615 std::ostream& operator<<(std::ostream& out, const Vector_d<D>& v)
616 {
617 
618  std::streamsize w = out.width();
619  std::streamsize p = out.precision();
620  std::ios::fmtflags f = out.flags();
621 
622  out << std::scientific;
623  for (size_t i = 0; i < v.size(); i++)
624  {
625  out << std::setw(16) << std::setprecision(8) << v[i];
626  }
627 
628  out.width( w );
629  out.precision( p );
630  out.flags( f );
631  return out;
632 }
633 
634 template <std::size_t D>
635 std::istream& operator>>(std::istream& ist, Vector_d<D>& v)
636 {
637  ist >> std::skipws;
638  for (size_t i = 0; i < v.size(); i++)
639  {
640  ist >> v[i];
641  }
642 
643  return ist;
644 }
645 
646 template <std::size_t D>
647 double dot(const Vector_d<D>& op1, const Vector_d<D>& op2)
648 {
649  return std::inner_product(op1.begin(), op1.end(), op2.begin(), 0.0);
650 }
651 
657 template <std::size_t D>
658 double vector_distance(const Vector_d<D>& op1, const Vector_d<D>& op2)
659 {
660  return (op2 - op1).magnitude();
661 }
662 
668 template <std::size_t D>
669 double vector_distance_squared(const Vector_d<D>& op1, const Vector_d<D>& op2)
670 {
671  return (op2 - op1).magnitude_squared();
672 }
673 
676 } // namespace kjb
677 
678 #endif /* KJB_M_VECTOR_D_IMPL_H */
Vector_d()
default constructor
Definition: m_vector_d.impl.h:46
void set_z(double zv)
Changes the third element of a vector (if it exists).
Definition: m_vector_d.impl.h:230
double vector_distance(const Int_vector &op1, const Int_vector &op2)
Compute the Euclidian distance between two vectors.
Definition: l_int_vector.h:1569
Vector_d< 4 > Vector4
Definition: gr_opengl.h:38
double magnitude() const
return the l2-norm of this vector
Definition: m_vector_d.impl.h:369
double vector_distance_squared(const Int_vector &op1, const Int_vector &op2)
Compute the square of the Euclidian distance between two vectors.
Definition: l_int_vector.h:1581
Definition for the Matrix class, a thin wrapper on the KJB Matrix struct and its related functionalit...
Vector create_random_vector(int length)
Construct a vector with values drawn from a uniform distribution over [0,1].
Definition: m_vector.h:1643
size_type size() const
Alias to get_length(). Required to comply with stl Container concept.
Definition: m_vector.h:510
Vector_d< 3 > Vector3
Definition: g_quaternion.h:37
Object thrown when an argument is of the wrong size or dimensions.
Definition: l_exception.h:426
void set_x(double xv)
Definition: m_vector_d.impl.h:159
Vector_d< D > & operator/=(double s)
Definition: m_vector_d.impl.h:332
void swap(Perspective_camera &cam1, Perspective_camera &cam2)
Swap two cameras.
Definition: perspective_camera.h:599
double y() const
Definition: m_vector_d.impl.h:169
double z() const
Definition: m_vector_d.impl.h:205
Vector_d< D > normalized() const
Non-mutating (functionally pure) version of normalize()
Definition: m_vector_d.impl.h:384
Image operator-(const Image &im1, const Image &im2)
Subtract two images.
Definition: i_image.h:843
#define KJB_THROW(ex)
Definition: l_exception.h:46
This class implements vectors, in the linear-algebra sense, with real-valued elements.
Definition: m_vector.h:87
void set_w(double wv)
Changes the fourth element of a vector (if it exists).
Definition: m_vector_d.impl.h:262
bool operator>=(const Int_vector &op1, const Int_vector &op2)
Test lexicographic ordering between vectors.
Definition: l_int_vector.h:1494
Vector_d< D > & operator*=(double s)
Definition: m_vector_d.impl.h:321
std::istream & operator>>(std::istream &ist, Detection_type &type)
Stream in an detection.
Definition: d_type.cpp:91
void resize(size_t n)
Definition: m_vector_d.impl.h:339
Image operator+(const Image &op1, const Image &op2)
Add two images.
Definition: i_image.h:834
double x() const
Definition: m_vector_d.impl.h:134
Vector_d< D > & operator-=(const Vector_d< D > &second)
Definition: m_vector_d.impl.h:289
iterator end()
Definition: m_vector.h:557
double w() const
read fourth element (i.e., index 3) of vector, if it exists.
Definition: m_vector_d.impl.h:241
Vector_d< D > & operator+=(const Vector_d< D > &second)
Definition: m_vector_d.impl.h:305
iterator begin()
Definition: m_vector.h:537
x
Definition: APPgetLargeConnectedEdges.m:100
Vector_d< D > & normalize()
normalize this vector to have l2-norm of 1.0
Definition: m_vector_d.impl.h:376
bool operator>(const Int_vector &op1, const Int_vector &op2)
Test lexicographic ordering between vectors.
Definition: l_int_vector.h:1485
double norm1() const
Definition: m_vector_d.impl.h:348
Image operator/(const Image &op1, double op2)
Scale an image in channel space, yielding a new image.
Definition: i_image.h:825
Vector multiply_matrix_and_vector_d_dispatch_(const Matrix &m, const double *v, size_t size)
dispatch for operator*(Matrix, Vector_d). This deals with a circular dependency between matrix...
Definition: m_vector_d.cpp:97
#define KJB_THROW_2(ex, msg)
Definition: l_exception.h:48
bool operator!=(const Int_matrix &op1, const Int_matrix::Impl_type &op2)
Test for any difference between two matrices.
Definition: l_int_matrix.h:1274
#define KJB_THROW_3(ex, fmt, params)
Definition: l_exception.h:56
Vector_d & operator=(const Vector_d &other)
assignment
Definition: m_vector_d.impl.h:267
bool operator==(const Int_matrix &op1, const Int_matrix::Impl_type &op2)
Test for exact equality between two matrices.
Definition: l_int_matrix.cpp:218
Vector create_gauss_random_vector(int length)
Construct a vector with values drawn from a standard Gaussian distribution (mean 0, variance 1);.
Definition: m_vector.cpp:390
double norm1(const Vector &op)
Compute L1-norm of vector.
Definition: m_vector.h:2020
Object thrown when an argument to a function is not acceptable.
Definition: l_exception.h:377
Vector_d< D > create_unit_vector(size_t d)
Definition: m_vector_d.impl.h:606
Definition: g_quaternion.h:37
double norm2(const Int_vector &op1)
Compute l2-norm of vector.
Definition: l_int_vector.h:1558
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
void set_y(double yv)
Changes the second element of a vector (if it exists).
Definition: m_vector_d.impl.h:196
This class implements matrices, in the linear-algebra sense, with real-valued elements.
Definition: m_matrix.h:94
long int dot(const Int_vector &op1, const Int_vector &op2)
Returns dot product of this and op2.
Definition: l_int_vector.h:1532
for m
Definition: APPgetLargeConnectedEdges.m:64
D
Definition: APPgetLargeConnectedEdges.m:106
Support for error handling exception classes in libKJB.
Vector_d< D > & negate()
Definition: m_vector_d.impl.h:390
Vector_d< 2 > Vector2
Definition: gr_opengl.h:35
Gsl_Vector operator*(double scalar, const Gsl_Vector &vector)
multiply scalar and vector, scalar written on the left side
Definition: gsl_vector.h:661
Definition for the Vector class, a thin wrapper on the KJB Vector struct and its related functionalit...
double magnitude_squared() const
return the squared l2-norm of this vector
Definition: m_vector_d.impl.h:362
Object thrown when computation fails somehow during execution.
Definition: l_exception.h:321