namespace ewalena
0.2.15
ewalena is not an acronym
|
00001 // ------------------------------------------------------------------- 00002 // @author Toby D. Young 00003 // @version $Id: vector.h 1002 2012-12-04 15:01:40Z oneliefleft $ 00004 // 00005 // Copyright 2012 namespace ewalena authors. All rights reserved. 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions 00009 // are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above 00015 // copyright notice, this list of conditions and the following 00016 // disclaimer in the documentation and/or other materials provided 00017 // with the distribution. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE NAMEPSACE EWALENA AUTHORS ``AS 00020 // IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00022 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00023 // NAMESPACE EWALENA AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00024 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00025 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00026 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00027 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00028 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00030 // OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // The views and conclusions contained in the software and 00033 // documentation are those of the authors and should not be 00034 // interpreted as representing official policies, either expressed or 00035 // implied, of the namespace ewalena authors. 00036 // ------------------------------------------------------------------- 00037 00038 #include <cassert> 00039 #include <cmath> 00040 #include <cstring> 00041 #include <iostream> 00042 00043 #ifndef __ewalena_vector_h 00044 #define __ewalena_vector_h 00045 00046 #ifdef EWALENA_HAVE_CONFIG_H 00047 #include <ewalena/base/config.h> 00048 #endif 00049 00050 #include <ewalena/lac/matrix.h> 00051 #include <ewalena/lac/vector_basis.h> 00052 00053 00054 namespace ewalena 00055 { 00056 00065 template <typename ValueType = double> 00066 class Vector 00067 { 00068 public: 00069 00073 Vector (); 00074 00078 ~Vector (); 00079 00086 explicit Vector (const unsigned int m, 00087 const bool zero = true); 00088 00093 Vector (const Vector<ValueType> &v); 00094 00104 Vector (std::initializer_list<ValueType> list); 00105 00109 void reinit (); 00110 00114 unsigned int size () const; 00115 00119 void reinit (const unsigned int m, 00120 const bool zero = true); 00121 00125 ValueType l1_norm (); 00126 00130 ValueType l2_norm (); 00131 00136 ValueType lp_norm (unsigned int p); 00137 00141 void l2_normalize (); 00142 00147 void lp_normalize (const unsigned int p); 00148 00152 ValueType& operator () (const unsigned int i); 00153 00157 const ValueType& operator () (const unsigned int i) const; 00158 00164 void operator = (const Vector<ValueType> &v); 00165 00170 void operator += (const Vector<ValueType> &v); 00171 00176 void operator -= (const Vector<ValueType> &v); 00177 00182 void operator *= (const ValueType &scalar); 00183 00188 void operator /= (const ValueType &scalar); 00189 00194 bool operator == (const Vector<ValueType> &v) const; 00195 00199 friend std::ostream& operator << (std::ostream& output, 00200 const Vector<ValueType> &v) 00201 { 00202 for (unsigned int i=0; i<v.__n_rows; ++i) 00203 00204 /* Try to pretty print */ 00205 (v.data[i]<(ValueType) 0) 00206 ? 00207 output << v.data[i] << " " 00208 : 00209 output << " " 00210 << v.data[i] << " "; 00211 00212 return output; 00213 } 00214 00215 00219 unsigned int n_rows () const; 00220 00224 void diag (const Matrix<ValueType> &M); 00225 00229 void sadd (const ValueType a, 00230 const Vector<ValueType> &v); 00231 00235 void sadd (const ValueType a, 00236 const Vector<ValueType> &v, 00237 const ValueType b, 00238 const Vector<ValueType> &w); 00239 00240 protected: 00241 00246 inline 00247 const 00248 ValueType* operator* () const 00249 { 00250 return (*this).data; 00251 } 00252 00257 inline 00258 ValueType* operator* () 00259 { 00260 return (*this).data; 00261 } 00262 00263 private: 00264 00269 unsigned int __n_rows; 00270 00275 ValueType *data; 00276 00277 00278 }; /* Vector */ 00279 00280 /*-------------- Inline and Other Functions -----------------------*/ 00281 00282 template <typename ValueType> 00283 inline 00284 const ValueType& 00285 Vector<ValueType>::operator () (const unsigned int i) const 00286 { 00287 assert (i < __n_rows); 00288 return data[i]; 00289 } 00290 00291 template <typename ValueType> 00292 inline 00293 ValueType& 00294 Vector<ValueType>::operator () (const unsigned int i) 00295 { 00296 assert (i < __n_rows); 00297 return data[i]; 00298 } 00299 00300 template <typename ValueType> 00301 inline 00302 void 00303 Vector<ValueType>::operator += (const Vector<ValueType> &v) 00304 { 00305 assert (v.__n_rows == this->__n_rows); 00306 for (unsigned int i=0; i<__n_rows; ++i) 00307 data[i] += v.data[i]; 00308 } 00309 00310 template <typename ValueType> 00311 inline 00312 void 00313 Vector<ValueType>::operator = (const Vector<ValueType> &v) 00314 { 00315 if (this->__n_rows != v.__n_rows) 00316 this->reinit (v.__n_rows); 00317 00318 std::memcpy (this->data, v.data, sizeof (ValueType)*__n_rows); 00319 } 00320 00321 template <typename ValueType> 00322 inline 00323 void 00324 Vector<ValueType>::operator -= (const Vector<ValueType> &v) 00325 { 00326 assert (v.__n_rows == __n_rows); 00327 for (unsigned int i=0; i<__n_rows; ++i) 00328 data[i] -= v.data[i]; 00329 } 00330 00331 template <typename ValueType> 00332 inline 00333 void 00334 Vector<ValueType>::operator *= (const ValueType &scalar) 00335 { 00336 for (unsigned int i=0; i<__n_rows; ++i) 00337 data[i] *= scalar; 00338 } 00339 00340 template <typename ValueType> 00341 inline 00342 void 00343 Vector<ValueType>::operator /= (const ValueType &scalar) 00344 { 00345 for (unsigned int i=0; i<__n_rows; ++i) 00346 data[i] /= scalar; 00347 } 00348 00349 template <typename ValueType> 00350 inline 00351 bool 00352 Vector<ValueType>::operator == (const Vector<ValueType> &v) const 00353 { 00354 assert (v.__n_rows == this->__n_rows); 00355 00356 return static_cast<bool> (!std::memcmp (this->data, v.data, sizeof (ValueType)*__n_rows)); 00357 } 00358 00359 template <typename ValueType> 00360 inline 00361 unsigned int 00362 Vector<ValueType>::n_rows () const 00363 { 00364 return __n_rows; 00365 } 00366 00367 template <typename ValueType> 00368 ValueType 00369 Vector<ValueType>::l1_norm () 00370 { 00371 ValueType l1_norm = (ValueType) 0; 00372 00373 for (unsigned int i=0; i<__n_rows; ++i) 00374 l1_norm += std::fabs (data[i]); 00375 00376 return l1_norm; 00377 } 00378 00379 template <typename ValueType> 00380 ValueType 00381 Vector<ValueType>::l2_norm () 00382 { 00383 ValueType l2_norm = (ValueType) 0; 00384 00385 for (unsigned int i=0; i<__n_rows; ++i) 00386 l2_norm += data[i] * data[i]; 00387 00388 return std::sqrt (l2_norm); 00389 } 00390 00391 template <typename ValueType> 00392 ValueType 00393 Vector<ValueType>::lp_norm (const unsigned int p) 00394 { 00395 assert (p>0); 00396 00397 ValueType lp_norm = (ValueType) 0; 00398 00399 for (unsigned int i=0; i<__n_rows; ++i) 00400 lp_norm += std::pow (data[i], static_cast<ValueType> (p)); 00401 00402 return std::pow (lp_norm, (ValueType) 1./(ValueType) p); 00403 } 00404 00405 00406 template <typename ValueType> 00407 inline 00408 void 00409 Vector<ValueType>::l2_normalize () 00410 { 00411 ValueType l2_norm = this->l2_norm (); 00412 assert (l2_norm != (ValueType) 0); 00413 00414 for (unsigned int i=0; i<__n_rows; ++i) 00415 data[i] /= l2_norm; 00416 } 00417 00418 template <typename ValueType> 00419 inline 00420 void 00421 Vector<ValueType>::lp_normalize (const unsigned int p) 00422 { 00423 ValueType lp_norm = this->lp_norm (p); 00424 00425 for (unsigned int i=0; i<__n_rows; ++i) 00426 data[i] /= lp_norm; 00427 } 00428 00429 template <typename ValueType> 00430 inline 00431 void 00432 Vector<ValueType>::diag (const Matrix<ValueType> &M) 00433 { 00434 assert (M.n_rows () == M.n_cols ()); 00435 assert (__n_rows == M.n_rows ()); 00436 00437 if (__n_rows == 0) return; 00438 00439 for (unsigned int i=0; i<__n_rows; ++i) 00440 data[i] = M(i, i); 00441 } 00442 00443 template <typename ValueType> 00444 inline 00445 void 00446 Vector<ValueType>::sadd (const ValueType a, 00447 const Vector<ValueType> &v) 00448 { 00449 assert (__n_rows != 0); 00450 assert (v.__n_rows == __n_rows); 00451 00452 for (unsigned int i=0; i<__n_rows; ++i) 00453 data[i] = a*v(i); 00454 } 00455 00456 template <typename ValueType> 00457 inline 00458 void 00459 Vector<ValueType>::sadd (const ValueType a, 00460 const Vector<ValueType> &v, 00461 const ValueType b, 00462 const Vector<ValueType> &w) 00463 { 00464 assert (__n_rows != 0); 00465 assert (v.__n_rows == __n_rows); 00466 00467 for (unsigned int i=0; i<__n_rows; ++i) 00468 data[i] = a*v(i) + b*w(i); 00469 } 00470 00471 } /* namespace ewalena */ 00472 00473 #endif /* __ewalena_vector_h */ 00474