Fawkes API Fawkes Development Version
|
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