Fawkes API Fawkes Development Version

vector.cpp

00001 
00002 /***************************************************************************
00003  *  vector.cpp - Column Vector
00004  *
00005  *  Created: Wed April 02 14:11:03 2008
00006  *  Copyright  2008  Daniel Beck
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include "vector.h"
00025 #include <exception>
00026 #include <core/exceptions/software.h>
00027 #include <cstdlib>
00028 #include <cstdio>
00029 
00030 namespace fawkes {
00031 
00032 /** @class Vector <geometry/vector.h>
00033  * A simple column vector.
00034  *
00035  * @fn float* Vector::data_ptr()
00036  * Get pointer to the internal data container.
00037  * @return pointer to the internal data container
00038  *
00039  * @fn const float* Vector::data_ptr() const
00040  * Get pointer to the internal data container.
00041  * @return pointer to the internal data container
00042  *
00043  * @fn friend std::ostream& Vector::operator<<(std::ostream& stream, const Vector &v)
00044  * Appends the components of the Vector to the ostream.
00045  * @param stream the input stream
00046  * @param v the vector to be appended
00047  * @return the resulting stream
00048  *
00049  * @author Daniel Beck
00050  */
00051 
00052 
00053 /** Constructor.
00054  * @param size the dimension of the vector
00055  * @param data pointer to a float array
00056  * @param manage_memory if true, the Vector will manage its memory on
00057  * its own, else it will not allocate new memory but works with the
00058  * provided array
00059  */
00060 Vector::Vector(unsigned int size, float* data, bool manage_memory)
00061 {
00062   m_size = size;
00063   m_manage_memory = manage_memory;
00064 
00065   if (m_manage_memory)
00066     {
00067       m_data = new float[m_size];
00068 
00069       for (unsigned int i = 0; i < m_size; ++i)
00070         {
00071           if (data)
00072             { m_data[i] = data[i]; }
00073           else
00074             { m_data[i] = 0.0; }
00075         }
00076     }
00077   else
00078     {
00079       m_data = data;
00080     }
00081 }
00082 
00083 /** Copy constructor.
00084  * @param v another Vector
00085  */
00086 Vector::Vector(const Vector& v)
00087 {
00088   m_size = v.m_size;
00089   m_manage_memory = true;
00090   m_data = new float[m_size];
00091 
00092   for (unsigned int i = 0; i < m_size; ++i)
00093     {
00094       m_data[i] = v.m_data[i];
00095     }
00096 }
00097 
00098 /** Destructor. */
00099 Vector::~Vector()
00100 {
00101   if (m_manage_memory)
00102     {
00103       delete[] m_data;
00104     }
00105 }
00106 
00107 /** Get the number of elements.
00108  * @return number of elements
00109  */
00110 unsigned int
00111 Vector::size() const
00112 {
00113   return m_size;
00114 }
00115 
00116 /** Set a new size.
00117  * @param size the new size
00118  */
00119 void
00120 Vector::set_size(unsigned int size)
00121 {
00122   float* t = new float[size];
00123 
00124   unsigned int i = 0;
00125   while( i < size && i < m_size)
00126     {
00127       t[i] = m_data[i];
00128       ++i;
00129     }
00130 
00131   m_size = size;
00132 
00133   if (m_manage_memory) //I'm not supposed to delete foreign buffers
00134     { delete[] m_data; }
00135   else
00136     { m_manage_memory = true;}
00137 
00138   m_data = t;
00139 }
00140 
00141 /** Get a certain element.
00142  * @param d index of the requested element
00143  * @return element at position d
00144  */
00145 float
00146 Vector::get(unsigned int d) const
00147 {
00148   if (m_size <= d)
00149     { return 0.0; }
00150 
00151   return m_data[d];
00152 }
00153 
00154 /** Get a reference to a certain element.
00155  * @param d index of the requested element
00156  * @return reference to element at position d
00157  */
00158 float&
00159 Vector::get(unsigned int d)
00160 {
00161   if (m_size <= d)
00162     {
00163       printf("This column vector has %u elements -- element %u not "
00164              "available", m_size, d);
00165       throw std::exception();
00166     }
00167 
00168   return m_data[d];
00169 }
00170 
00171 /** Set a certain element.
00172  * @param d index of the element
00173  * @param f the new value
00174  */
00175 void
00176 Vector::set(unsigned int d, float f)
00177 {
00178   if (m_size <= d)
00179     {
00180       printf("This column vector has %u elements -- element %u not "
00181              "available", m_size, d);
00182       throw std::exception();
00183     }
00184 
00185   m_data[d] = f;
00186 }
00187 
00188 /** Convenience getter to obtain the first element.
00189  * @return the first element
00190  */
00191 float
00192 Vector::x() const
00193 {
00194   return get(0);
00195 }
00196 
00197 /** Convenience getter to obtain a reference to the first element.
00198  * @return reference to the first element
00199  */
00200 float&
00201 Vector::x()
00202 {
00203   float& ret = get(0);
00204   return ret;
00205 }
00206 
00207 /** Convenience setter to set the first element.
00208  * @param x the new value of the first element
00209  */
00210 void
00211 Vector::x(float x)
00212 {
00213   set(0, x);
00214 }
00215 
00216 /** Convenience getter to obtain the second element.
00217  * @return the second element
00218  */
00219 float
00220 Vector::y() const
00221 {
00222   return get(1);
00223 }
00224 
00225 /** Convenience getter to obtain a reference to the second element.
00226  * @return reference to the second element
00227  */
00228 float&
00229 Vector::y()
00230 {
00231   float& ret = get(1);
00232   return ret;
00233 }
00234 
00235 /** Convenience setter to set the second element.
00236  * @param y the new value of the second element
00237  */
00238 void
00239 Vector::y(float y)
00240 {
00241   set(1, y);
00242 }
00243 
00244 /** Convenience getter to obtain the third element.
00245  * @return the third element
00246  */
00247 float
00248 Vector::z() const
00249 {
00250   return get(2);
00251 }
00252 
00253 /** Convenience getter to obtain a reference to the third element.
00254  * @return reference to the third element
00255  */
00256 float&
00257 Vector::z()
00258 {
00259   float& ret = get(2);
00260   return ret;
00261 }
00262 
00263 /** Convenience setter to set the third element.
00264  * @param z the new value of the third element
00265  */
00266 void
00267 Vector::z(float z)
00268 {
00269   set(2, z);
00270 }
00271 
00272 /** Access operator.
00273  * @param d index of the requested element
00274  * @return the value at the given position
00275  */
00276 float
00277 Vector::operator[](unsigned int d) const
00278 {
00279   if (m_size <= d)
00280     { return 0.0; }
00281 
00282   return m_data[d];
00283 }
00284 
00285 /** Access operator.
00286  * @param d index of the requested element
00287  * @return reference to the value at the given position
00288  */
00289 float&
00290 Vector::operator[](unsigned int d)
00291 {
00292   if (m_size <= d)
00293     {
00294       printf("This column vector has %u elements -- element %u not "
00295              "available", m_size, d);
00296       throw std::exception();
00297     }
00298 
00299   return m_data[d];
00300 }
00301 
00302 /** Multiply the vector with a scalar.
00303  * @param f the scalar
00304  * @return scaled vector
00305  */
00306 Vector
00307 Vector::operator*(const float& f) const
00308 {
00309   Vector result(m_size, m_data);
00310 
00311   for (unsigned int i = 0; i < m_size; ++i)
00312     { result.m_data[i] *= f; }
00313 
00314   return result;
00315 }
00316 
00317 /** In-place scalar multiplication.
00318  * @param f the scalar
00319  * @return reference to the scaled vector
00320  */
00321 Vector&
00322 Vector::operator*=(const float& f)
00323 {
00324   for (unsigned int i = 0; i < m_size; ++i)
00325     { m_data[i] *= f; }
00326 
00327   return *this;
00328 }
00329 
00330 /** Divide every element of the vector by a scalar.
00331  * @param f the scalar
00332  * @return scaled vector
00333  */
00334 Vector
00335 Vector::operator/(const float& f) const
00336 {
00337   Vector result(m_size, m_data);
00338 
00339   for (unsigned int i = 0; i < m_size; ++i)
00340     { result.m_data[i] /= f; }
00341 
00342   return result;
00343 }
00344 
00345 /** In-place scalar division.
00346  * @param f the scalar
00347  * @return reference to the scaled vector
00348  */
00349 Vector&
00350 Vector::operator/=(const float& f)
00351 {
00352   for (unsigned int i = 0; i < m_size; ++i)
00353     { m_data[i] /= f; }
00354 
00355   return *this;
00356 }
00357 
00358 /** Adds two vectors.
00359  * @param cv the vector to be added
00360  * @return sum vector
00361  */
00362 Vector
00363 Vector::operator+(const Vector& cv) const
00364 {
00365   if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
00366 
00367   Vector result(m_size, m_data);
00368 
00369   for (unsigned int i = 0; i < m_size; ++i)
00370     {
00371       result.m_data[i] += cv[i];
00372     }
00373 
00374   return result;
00375 }
00376 
00377 /** In-place vector addition.
00378  * @param cv the vector to be added
00379  * @return reference to the sum vector
00380  */
00381 Vector&
00382 Vector::operator+=(const Vector& cv)
00383 {
00384   if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
00385 
00386   for (unsigned int i = 0; i < m_size; ++i)
00387     {
00388       m_data[i] += cv[i];
00389     }
00390 
00391   return *this;
00392 }
00393 
00394 /** Substract two vectors.
00395  * @param cv the vector to be substracted
00396  * @return diff vector
00397  */
00398 Vector
00399 Vector::operator-(const Vector& cv) const
00400 {
00401   if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
00402 
00403   Vector result(m_size, m_data);
00404 
00405   for (unsigned int i = 0; i < m_size; ++i)
00406     {
00407       result.m_data[i] -= cv[i];
00408     }
00409 
00410   return result;
00411 }
00412 
00413 /** In-place vector substraction.
00414  * @param cv the vector to be substracted
00415  * @return reference to the diff vector
00416  */
00417 Vector&
00418 Vector::operator-=(const Vector& cv)
00419 {
00420   if (m_size != cv.size()) throw fawkes::TypeMismatchException("The two vectors have to be of equal size");
00421 
00422   for (unsigned int i = 0; i < m_size; ++i)
00423     {
00424       m_data[i] -= cv[i];
00425     }
00426 
00427   return *this;
00428 }
00429 
00430 /** Assignment operator.
00431  * @param v the rhs vector
00432  * @return reference to the lhs vector
00433  */
00434 Vector&
00435 Vector::operator=(const Vector& v)
00436 {
00437   if (m_size != v.m_size)
00438     {
00439       if (m_manage_memory)
00440         { delete[] m_data; }
00441 
00442       m_size = v.m_size;
00443       m_manage_memory = true;
00444 
00445       m_data = new float[m_size];
00446     }
00447 
00448   for (unsigned int i = 0; i < m_size; ++i)
00449     { m_data[i] =  v.m_data[i]; }
00450 
00451   return *this;
00452 }
00453 
00454 /** Comparison operator.
00455  * @param v the other vector
00456  * @return true, if both vectors are equal
00457  */
00458 bool
00459 Vector::operator==(const Vector& v)
00460 {
00461   if (m_size != v.m_size)
00462     { return false; }
00463 
00464   for (unsigned int i = 0; i < m_size; ++i)
00465     {
00466       if (m_data[i] != v.m_data[i])
00467         { return false; }
00468     }
00469 
00470   return true;
00471 }
00472 
00473 
00474 /** Prints the vector data to standard out.
00475  * @param name a string that is printed prior to the vector data
00476  */
00477 void
00478 Vector::print_info(const char* name) const
00479 {
00480   if (name)
00481     { printf("%s: [ ", name); }
00482   else
00483     { printf("[ "); }
00484 
00485   for (unsigned int i = 0; i < m_size; ++i)
00486     {
00487       printf("%f ", get(i));
00488     }
00489   printf("]T\n");
00490 }
00491 
00492 /** Calculates the dot product of two vectors.
00493  * @param v the rhs Vector
00494  * @return the scalar product
00495  */
00496 float
00497 Vector::operator*(const Vector& v) const
00498 {
00499   float res = 0;
00500 
00501   for (unsigned int i = 0; i < m_size; ++i)
00502     res += this->get(i) * v.get(i);
00503 
00504   return res;
00505 }
00506 
00507 /** Appends the components of the Vector to the ostream.
00508  * @param stream the input stream
00509  * @param v the vector to be appended
00510  * @return the resulting stream
00511  */
00512 std::ostream&
00513 operator<<(std::ostream& stream, const Vector &v)
00514 {
00515   stream << "[";
00516 
00517   for (unsigned int i = 0; i < v.m_size; ++i)
00518     {
00519       stream << v.get(i);
00520 
00521       if (i + 1 < v.m_size)
00522         stream << ",";
00523     }
00524 
00525   return stream << "]";
00526 }
00527 
00528 } // end namespace fawkes
00529 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends