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