Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vector.cpp
1 
2 /***************************************************************************
3  * vector.cpp - Column Vector
4  *
5  * Created: Wed April 02 14:11:03 2008
6  * Copyright 2008 Daniel Beck
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include "vector.h"
25 #include <exception>
26 #include <core/exceptions/software.h>
27 #include <cstdlib>
28 #include <cstdio>
29 
30 namespace fawkes {
31 
32 /** @class Vector <geometry/vector.h>
33  * A simple column vector.
34  *
35  * @fn float* Vector::data_ptr()
36  * Get pointer to the internal data container.
37  * @return pointer to the internal data container
38  *
39  * @fn const float* Vector::data_ptr() const
40  * Get pointer to the internal data container.
41  * @return pointer to the internal data container
42  *
43  * @fn friend std::ostream& Vector::operator<<(std::ostream& stream, const Vector &v)
44  * Appends the components of the Vector to the ostream.
45  * @param stream the input stream
46  * @param v the vector to be appended
47  * @return the resulting stream
48  *
49  * @author Daniel Beck
50  */
51 
52 
53 /** Constructor.
54  * @param size the dimension of the vector
55  * @param data pointer to a float array
56  * @param manage_memory if true, the Vector will manage its memory on
57  * its own, else it will not allocate new memory but works with the
58  * provided array
59  */
60 Vector::Vector(unsigned int size, float* data, bool manage_memory)
61 {
62  m_size = size;
63  m_manage_memory = manage_memory;
64 
65  if (m_manage_memory)
66  {
67  m_data = new float[m_size];
68 
69  for (unsigned int i = 0; i < m_size; ++i)
70  {
71  if (data)
72  { m_data[i] = data[i]; }
73  else
74  { m_data[i] = 0.0; }
75  }
76  }
77  else
78  {
79  m_data = data;
80  }
81 }
82 
83 /** Copy constructor.
84  * @param v another Vector
85  */
87 {
88  m_size = v.m_size;
89  m_manage_memory = true;
90  m_data = new float[m_size];
91 
92  for (unsigned int i = 0; i < m_size; ++i)
93  {
94  m_data[i] = v.m_data[i];
95  }
96 }
97 
98 /** Destructor. */
100 {
101  if (m_manage_memory)
102  {
103  delete[] m_data;
104  }
105 }
106 
107 /** Get the number of elements.
108  * @return number of elements
109  */
110 unsigned int
112 {
113  return m_size;
114 }
115 
116 /** Set a new size.
117  * @param size the new size
118  */
119 void
120 Vector::set_size(unsigned int size)
121 {
122  float* t = new float[size];
123 
124  unsigned int i = 0;
125  while( i < size && i < m_size)
126  {
127  t[i] = m_data[i];
128  ++i;
129  }
130 
131  m_size = size;
132 
133  if (m_manage_memory) //I'm not supposed to delete foreign buffers
134  { delete[] m_data; }
135  else
136  { m_manage_memory = true;}
137 
138  m_data = t;
139 }
140 
141 /** Get a certain element.
142  * @param d index of the requested element
143  * @return element at position d
144  */
145 float
146 Vector::get(unsigned int d) const
147 {
148  if (m_size <= d)
149  { return 0.0; }
150 
151  return m_data[d];
152 }
153 
154 /** Get a reference to a certain element.
155  * @param d index of the requested element
156  * @return reference to element at position d
157  */
158 float&
159 Vector::get(unsigned int d)
160 {
161  if (m_size <= d)
162  {
163  printf("This column vector has %u elements -- element %u not "
164  "available", m_size, d);
165  throw std::exception();
166  }
167 
168  return m_data[d];
169 }
170 
171 /** Set a certain element.
172  * @param d index of the element
173  * @param f the new value
174  */
175 void
176 Vector::set(unsigned int d, float f)
177 {
178  if (m_size <= d)
179  {
180  printf("This column vector has %u elements -- element %u not "
181  "available", m_size, d);
182  throw std::exception();
183  }
184 
185  m_data[d] = f;
186 }
187 
188 /** Convenience getter to obtain the first element.
189  * @return the first element
190  */
191 float
192 Vector::x() const
193 {
194  return get(0);
195 }
196 
197 /** Convenience getter to obtain a reference to the first element.
198  * @return reference to the first element
199  */
200 float&
202 {
203  float& ret = get(0);
204  return ret;
205 }
206 
207 /** Convenience setter to set the first element.
208  * @param x the new value of the first element
209  */
210 void
211 Vector::x(float x)
212 {
213  set(0, x);
214 }
215 
216 /** Convenience getter to obtain the second element.
217  * @return the second element
218  */
219 float
220 Vector::y() const
221 {
222  return get(1);
223 }
224 
225 /** Convenience getter to obtain a reference to the second element.
226  * @return reference to the second element
227  */
228 float&
230 {
231  float& ret = get(1);
232  return ret;
233 }
234 
235 /** Convenience setter to set the second element.
236  * @param y the new value of the second element
237  */
238 void
239 Vector::y(float y)
240 {
241  set(1, y);
242 }
243 
244 /** Convenience getter to obtain the third element.
245  * @return the third element
246  */
247 float
248 Vector::z() const
249 {
250  return get(2);
251 }
252 
253 /** Convenience getter to obtain a reference to the third element.
254  * @return reference to the third element
255  */
256 float&
258 {
259  float& ret = get(2);
260  return ret;
261 }
262 
263 /** Convenience setter to set the third element.
264  * @param z the new value of the third element
265  */
266 void
267 Vector::z(float z)
268 {
269  set(2, z);
270 }
271 
272 /** Access operator.
273  * @param d index of the requested element
274  * @return the value at the given position
275  */
276 float
277 Vector::operator[](unsigned int d) const
278 {
279  if (m_size <= d)
280  { return 0.0; }
281 
282  return m_data[d];
283 }
284 
285 /** Access operator.
286  * @param d index of the requested element
287  * @return reference to the value at the given position
288  */
289 float&
290 Vector::operator[](unsigned int d)
291 {
292  if (m_size <= d)
293  {
294  printf("This column vector has %u elements -- element %u not "
295  "available", m_size, d);
296  throw std::exception();
297  }
298 
299  return m_data[d];
300 }
301 
302 /** Multiply the vector with a scalar.
303  * @param f the scalar
304  * @return scaled vector
305  */
306 Vector
307 Vector::operator*(const float& f) const
308 {
309  Vector result(m_size, m_data);
310 
311  for (unsigned int i = 0; i < m_size; ++i)
312  { result.m_data[i] *= f; }
313 
314  return result;
315 }
316 
317 /** In-place scalar multiplication.
318  * @param f the scalar
319  * @return reference to the scaled vector
320  */
321 Vector&
322 Vector::operator*=(const float& f)
323 {
324  for (unsigned int i = 0; i < m_size; ++i)
325  { m_data[i] *= f; }
326 
327  return *this;
328 }
329 
330 /** Divide every element of the vector by a scalar.
331  * @param f the scalar
332  * @return scaled vector
333  */
334 Vector
335 Vector::operator/(const float& f) const
336 {
337  Vector result(m_size, m_data);
338 
339  for (unsigned int i = 0; i < m_size; ++i)
340  { result.m_data[i] /= f; }
341 
342  return result;
343 }
344 
345 /** In-place scalar division.
346  * @param f the scalar
347  * @return reference to the scaled vector
348  */
349 Vector&
350 Vector::operator/=(const float& f)
351 {
352  for (unsigned int i = 0; i < m_size; ++i)
353  { m_data[i] /= f; }
354 
355  return *this;
356 }
357 
358 /** Adds two vectors.
359  * @param cv the vector to be added
360  * @return sum vector
361  */
362 Vector
363 Vector::operator+(const Vector& cv) const
364 {
365  if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
366 
367  Vector result(m_size, m_data);
368 
369  for (unsigned int i = 0; i < m_size; ++i)
370  {
371  result.m_data[i] += cv[i];
372  }
373 
374  return result;
375 }
376 
377 /** In-place vector addition.
378  * @param cv the vector to be added
379  * @return reference to the sum vector
380  */
381 Vector&
383 {
384  if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
385 
386  for (unsigned int i = 0; i < m_size; ++i)
387  {
388  m_data[i] += cv[i];
389  }
390 
391  return *this;
392 }
393 
394 /** Substract two vectors.
395  * @param cv the vector to be substracted
396  * @return diff vector
397  */
398 Vector
399 Vector::operator-(const Vector& cv) const
400 {
401  if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
402 
403  Vector result(m_size, m_data);
404 
405  for (unsigned int i = 0; i < m_size; ++i)
406  {
407  result.m_data[i] -= cv[i];
408  }
409 
410  return result;
411 }
412 
413 /** In-place vector substraction.
414  * @param cv the vector to be substracted
415  * @return reference to the diff vector
416  */
417 Vector&
419 {
420  if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
421 
422  for (unsigned int i = 0; i < m_size; ++i)
423  {
424  m_data[i] -= cv[i];
425  }
426 
427  return *this;
428 }
429 
430 /** Assignment operator.
431  * @param v the rhs vector
432  * @return reference to the lhs vector
433  */
434 Vector&
436 {
437  if (m_size != v.m_size)
438  {
439  if (m_manage_memory)
440  { delete[] m_data; }
441 
442  m_size = v.m_size;
443  m_manage_memory = true;
444 
445  m_data = new float[m_size];
446  }
447 
448  for (unsigned int i = 0; i < m_size; ++i)
449  { m_data[i] = v.m_data[i]; }
450 
451  return *this;
452 }
453 
454 /** Comparison operator.
455  * @param v the other vector
456  * @return true, if both vectors are equal
457  */
458 bool
460 {
461  if (m_size != v.m_size)
462  { return false; }
463 
464  for (unsigned int i = 0; i < m_size; ++i)
465  {
466  if (m_data[i] != v.m_data[i])
467  { return false; }
468  }
469 
470  return true;
471 }
472 
473 
474 /** Prints the vector data to standard out.
475  * @param name a string that is printed prior to the vector data
476  */
477 void
478 Vector::print_info(const char* name) const
479 {
480  if (name)
481  { printf("%s: [ ", name); }
482  else
483  { printf("[ "); }
484 
485  for (unsigned int i = 0; i < m_size; ++i)
486  {
487  printf("%f ", get(i));
488  }
489  printf("]T\n");
490 }
491 
492 /** Calculates the dot product of two vectors.
493  * @param v the rhs Vector
494  * @return the scalar product
495  */
496 float
497 Vector::operator*(const Vector& v) const
498 {
499  float res = 0;
500 
501  for (unsigned int i = 0; i < m_size; ++i)
502  res += this->get(i) * v.get(i);
503 
504  return res;
505 }
506 
507 /** Appends the components of the Vector to the ostream.
508  * @param stream the input stream
509  * @param v the vector to be appended
510  * @return the resulting stream
511  */
512 std::ostream&
513 operator<<(std::ostream& stream, const Vector &v)
514 {
515  stream << "[";
516 
517  for (unsigned int i = 0; i < v.m_size; ++i)
518  {
519  stream << v.get(i);
520 
521  if (i + 1 < v.m_size)
522  stream << ",";
523  }
524 
525  return stream << "]";
526 }
527 
528 } // end namespace fawkes
529