library of assembled shared sources

http://lass.cocamware.com

vector.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 
00044 
00045 #ifndef LASS_GUARDIAN_OF_INCLUSION_NUM_VECTOR_INL
00046 #define LASS_GUARDIAN_OF_INCLUSION_NUM_VECTOR_INL
00047 
00048 #include "num_common.h"
00049 #include "vector.h"
00050 #include "../meta/is_integral.h"
00051 
00052 #define LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(a, b)\
00053     LASS_UTIL_IMPL_MAKE_ENFORCER(\
00054         ::lass::util::impl::EqualPredicate,\
00055         ::lass::util::impl::DefaultRaiser,\
00056         (a).size(), \
00057         (b).size(), \
00058         "Vectors '" LASS_STRINGIFY(a) "' and '" LASS_STRINGIFY(b) "' have different dimensions in '" LASS_HERE "'.")
00059 
00060 namespace lass
00061 {
00062 namespace num
00063 {
00064 
00065 // --- public --------------------------------------------------------------------------------------
00066 
00067 /** constructs an empty vector
00068  *  
00069  *  @par Exception safety: 
00070  *      strong guarentee.
00071  */
00072 template <typename T, typename S>
00073 Vector<T, S>::Vector():
00074     storage_()
00075 {
00076     LASS_ASSERT(size() == 0);
00077 }
00078 
00079 
00080 
00081 /** Construct a vector of dimension @a iDimension.
00082  *  @param iDimension the dimension of the vector to be created.  You can pass zero, but you
00083  *         shouldn't pass negative dimensions though.
00084  *  @param iInitialValue the initial value of all vector components, zero by default.
00085  *
00086  *  @par Complexity: 
00087  *      O(iDimension)
00088  *
00089  *  @par Exception safety: 
00090  *      strong guarentee.
00091  */
00092 template <typename T, typename S>
00093 Vector<T, S>::Vector(TSize iDimension, TParam iInitialValue):
00094     storage_(iDimension, iInitialValue)
00095 {
00096 }
00097 
00098 
00099 
00100 /** construct vector from storage type
00101  *
00102  *  @par Complexity: 
00103  *      O(iStorage.size())
00104  *
00105  *  @par Exception safety: 
00106  *      strong guarentee.
00107  */
00108 template <typename T, typename S>
00109 Vector<T, S>::Vector(const TStorage& iStorage):
00110     storage_(iStorage)
00111 {
00112 }
00113 
00114 
00115 
00116 /** contruct by any particular type supporting [] and size().
00117  *  Should only be used with writable storage type (like std::vector which is the default).
00118  *
00119  *  @par Complexity: 
00120  *      O(iVector.size())
00121  *
00122  *  @par Exception safety: 
00123  *      strong guarentee.
00124  */
00125 template <typename T, typename S>
00126 template <typename VectorType>
00127 Vector<T, S>::Vector(const VectorType& iVector)
00128 {
00129     init(iVector, meta::Wrap<typename meta::IsIntegral<VectorType>::Type>());
00130 }
00131 
00132 
00133 
00134 /** construct storage/expression vector to this (this should be a storage vector).
00135  *
00136  *  @pre @c this must be an l-value.
00137  *
00138  *  @par Complexity: 
00139  *      O(iOther.size())
00140  *
00141  *  @par Exception safety: 
00142  *      strong guarentee.
00143  */
00144 template <typename T, typename S>
00145 template <typename T2, typename S2>
00146 Vector<T, S>::Vector(const Vector<T2, S2>& iOther)
00147 {
00148     TSize n = iOther.storage_.size();
00149     storage_.resize(n);
00150     for (TSize i = 0; i < n; ++i)
00151     {
00152         storage_[i] = iOther.storage_[i];
00153     }
00154 }
00155 
00156 
00157 
00158 /** assign storage/expression vector to this (this should be a storage vector).
00159  *
00160  *  @pre @c this must be an l-value.
00161  *
00162  *  @par Complexity: 
00163  *      O(iOther.size())
00164  *
00165  *  @par Exception safety: 
00166  *      basic guarentee.
00167  */
00168 template <typename T, typename S>
00169 template <typename T2, typename S2>
00170 Vector<T, S>& Vector<T, S>::operator=(const Vector<T2, S2>& iOther)
00171 {
00172     TSize n = iOther.storage_.size();
00173     storage_.resize(n);
00174     for (TSize i = 0; i < n; ++i)
00175     {
00176         storage_[i] = iOther.storage_[i];
00177     }
00178     return *this;
00179 }
00180 
00181 
00182 
00183 /** return dimension of vector.
00184  *  this should never be a negative value.
00185  *
00186  *  @par Exception safety: 
00187  *      nofail.
00188  */
00189 template <typename T, typename S> inline
00190 const typename Vector<T, S>::TSize
00191 Vector<T, S>::size() const
00192 {
00193     return storage_.size();
00194 }
00195 
00196 
00197 
00198 /** return the iIndex'th component value.
00199  *
00200  *  @pre @a iIndex must be in [0, this->size()), unless you're asking for trouble.
00201  *
00202  *  @par Exception safety: 
00203  *      strong guarentee.
00204  */
00205 template <typename T, typename S> inline
00206 const typename Vector<T, S>::TValue
00207 Vector<T, S>::operator[](TSize iIndex) const
00208 {
00209     LASS_ASSERT(iIndex < size());
00210     return storage_[iIndex];
00211 }
00212 
00213 
00214 
00215 /** access the iIndex'th component value.
00216  *
00217  *  @pre 
00218  *      @arg @a iIndex must be in [0, this->size()), unless you're asking for trouble.
00219  *      @arg @c this must be an l-value.
00220  *
00221  *  @par Exception safety: 
00222  *      strong guarentee.
00223  */
00224 template <typename T, typename S> inline
00225 typename util::CallTraits<T>::TReference
00226 Vector<T, S>::operator[](TSize iIndex)
00227 {
00228     LASS_ASSERT(iIndex < size());
00229     return storage_[iIndex];
00230 }
00231 
00232 
00233 /** return the iIndex'th component value and wrap index if necessary.
00234  *  if iIndex is out of the range [0, this->size()), it will be wrapped to map in this range.
00235  *  This is simply a modulus operation: mod(iIndex, this->size()).
00236  *
00237  *  @par Exception safety: 
00238  *      strong guarentee.
00239  */
00240 template <typename T, typename S> inline
00241 const typename Vector<T, S>::TValue
00242 Vector<T, S>::at(TSize iIndex) const
00243 {
00244     return storage_[mod(iIndex, storage_.size())];
00245 }
00246 
00247 
00248 
00249 /** access the iIndex'th component value and wrap index if necessary.
00250  *  if iIndex is out of the range [0, this->size()), it will be wrapped to map in this range.
00251  *  This is simply a modulus operation: mod(iIndex, this->size()).
00252  *
00253  *  @pre @c this must be an l-value.
00254  *
00255  *  @par Exception safety: 
00256  *      strong guarentee.
00257  */
00258 template <typename T, typename S> inline
00259 typename util::CallTraits<T>::TReference
00260 Vector<T, S>::at(TSize iIndex)
00261 {
00262     return storage_[num::mod(iIndex, storage_.size())];
00263 }
00264 
00265 
00266 
00267 /** A weird way to get back the same object
00268  *
00269  *  @par Complexity: 
00270  *      O(1)
00271  *
00272  *  @par Exception safety: 
00273  *      nofail guarentee.
00274  */
00275 template <typename T, typename S> inline
00276 const Vector<T, S>&
00277 Vector<T, S>::operator+() const
00278 {
00279     return *this;
00280 }
00281 
00282 
00283 
00284 /** return a vector with all components negated
00285  *  (-v)[i] == -(v[i]).
00286  *
00287  *  @par Complexity: 
00288  *      O(1)
00289  *
00290  *  @par Exception safety: 
00291  *      nofail.
00292  */
00293 template <typename T, typename S>
00294 const Vector<T, impl::VNeg<T, S> >
00295 Vector<T, S>::operator-() const
00296 {
00297     typedef impl::VNeg<T, S> TExpression;
00298     return Vector<T, TExpression>(TExpression(storage_));
00299 }
00300 
00301 
00302 
00303 /** add storage/expression vector to this (this should be a storage vector).
00304  *
00305  *  @pre 
00306  *      @arg this->size() == iB.size()
00307  *      @arg @c this must be an l-value.
00308  *
00309  *  @par Complexity: 
00310  *      O(this->size())
00311  *
00312  *  @par Exception safety: 
00313  *      basic guarentee.
00314  */
00315 template <typename T, typename S>
00316 template <typename T2, typename S2>
00317 Vector<T, S>& Vector<T, S>::operator+=(const Vector<T2, S2>& iB)
00318 {
00319     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
00320     const TSize n = storage_.size();
00321     for (TSize i = 0; i < n; ++i)
00322     {
00323         storage_[i] += iB[i];
00324     }
00325     return *this;
00326 }
00327 
00328 
00329 
00330 /** subtract storage/expression vector from this (this should be a storage vector).
00331  *
00332  *  @pre 
00333  *      @arg this->size() == iB.size()
00334  *      @arg @c this must be an l-value.
00335  *
00336  *  @par Complexity: 
00337  *      O(this->size())
00338  *
00339  *  @par Exception safety: 
00340  *      basic guarentee.
00341  */
00342 template <typename T, typename S>
00343 template <typename T2, typename S2>
00344 Vector<T, S>& Vector<T, S>::operator-=(const Vector<T2, S2>& iB)
00345 {
00346     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
00347     const TSize n = storage_.size();
00348     for (TSize i = 0; i < n; ++i)
00349     {
00350         storage_[i] -= iB[i];
00351     }
00352     return *this;
00353 }
00354 
00355 
00356 
00357 /** multiply storage/expression vector with this (this should be a storage vector).
00358  *
00359  *  @pre 
00360  *      @arg this->size() == iB.size()
00361  *      @arg @c this must be an l-value.
00362  *
00363  *  @par Complexity: 
00364  *      O(this->size())
00365  *
00366  *  @par Exception safety: 
00367  *      basic guarentee.
00368  */
00369 template <typename T, typename S>
00370 template <typename T2, typename S2>
00371 Vector<T, S>& Vector<T, S>::operator*=(const Vector<T2, S2>& iB)
00372 {
00373     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
00374     const TSize n = storage_.size();
00375     for (TSize i = 0; i < n; ++i)
00376     {
00377         storage_[i] *= iB[i];
00378     }
00379     return *this;
00380 }
00381 
00382 
00383 
00384 /** divide this by storage/expression vector (this should be a storage vector).
00385  *
00386  *  @pre 
00387  *      @arg this->size() == iB.size()
00388  *      @arg @c this must be an l-value.
00389  *
00390  *  @par Complexity: 
00391  *      O(this->size())
00392  *
00393  *  @par Exception safety: 
00394  *      basic guarentee.
00395  */
00396 template <typename T, typename S>
00397 template <typename T2, typename S2>
00398 Vector<T, S>& Vector<T, S>::operator/=(const Vector<T2, S2>& iB)
00399 {
00400     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
00401     const TSize n = storage_.size();
00402     for (TSize i = 0; i < n; ++i)
00403     {
00404         storage_[i] /= iB[i];
00405     }
00406     return *this;
00407 }
00408 
00409 
00410 
00411 /** add @a iB to all components
00412  *
00413  *  @pre @c this must be an l-value.
00414  *
00415  *  @par Complexity: 
00416  *      O(this->size())
00417  */
00418 template <typename T, typename S>
00419 template <typename T2>
00420 Vector<T, S>& Vector<T, S>::operator+=(const T2& iB)
00421 {
00422     const TSize n = storage_.size();
00423     for (TSize i = 0; i < n; ++i)
00424     {
00425         storage_[i] += iB;
00426     }
00427     return *this;
00428 }
00429 
00430 
00431 
00432 /** subtract @a iB from all components
00433  *
00434  *  @pre @c this must be an l-value.
00435  *
00436  *  @par Complexity: 
00437  *      O(this->size())
00438  */
00439 template <typename T, typename S>
00440 template <typename T2>
00441 Vector<T, S>& Vector<T, S>::operator-=(const T2& iB)
00442 {
00443     const TSize n = storage_.size();
00444     for (TSize i = 0; i < n; ++i)
00445     {
00446         storage_[i] -= iB;
00447     }
00448     return *this;
00449 }
00450 
00451 
00452 
00453 /** multiply all components with @a iB.
00454  *
00455  *  @pre @c this must be an l-value.
00456  *
00457  *  @par Complexity: 
00458  *      O(this->size())
00459  */
00460 template <typename T, typename S>
00461 template <typename T2>
00462 Vector<T, S>& Vector<T, S>::operator*=(const T2& iB)
00463 {
00464     const TSize n = storage_.size();
00465     for (TSize i = 0; i < n; ++i)
00466     {
00467         storage_[i] *= iB;
00468     }
00469     return *this;
00470 }
00471 
00472 
00473 
00474 /** divide all components by @a iB.
00475  *
00476  *  @pre @c this must be an l-value.
00477  *
00478  *  @par Complexity: 
00479  *      O(this->size())
00480  */
00481 template <typename T, typename S>
00482 template <typename T2>
00483 Vector<T, S>& Vector<T, S>::operator/=(const T2& iB)
00484 {
00485     const TSize n = storage_.size();
00486     for (TSize i = 0; i < n; ++i)
00487     {
00488         storage_[i] /= iB;
00489     }
00490     return *this;
00491 }
00492 
00493 
00494 /** return true if vector contains no dataa at all
00495  *
00496  *  @par Complexity: 
00497  *      O(1)
00498  *
00499  *  @par Exception safety: 
00500  *      nofail.
00501  */
00502 template <typename T, typename S> inline
00503 const bool Vector<T, S>::isEmpty() const
00504 {
00505     return storage_.size() == 0;
00506 }
00507 
00508 
00509 
00510 /** Return true if all the components are (exactly!) zero
00511  *
00512  *  @par Complexity: 
00513  *      O(this->size())
00514  */
00515 template <typename T, typename S>
00516 const bool Vector<T, S>::isZero() const
00517 {
00518     const TSize n = storage_.size();
00519     for (TSize i = 0; i < n; ++i)
00520     {
00521         // if you get your compiler error here, you'll be using a broken STLport version. Ask [Bramz].
00522         //
00523         if (storage_[i] != TNumTraits::zero)
00524         {
00525             return false;
00526         }
00527     }
00528     return true;
00529 }
00530 
00531 
00532 
00533 /** Return sum of all components of vector.
00534  *
00535  *  @par Complexity: 
00536  *      O(this->size())
00537  */
00538 template <typename T, typename S>
00539 const typename Vector<T, S>::TValue
00540 Vector<T, S>::sum() const
00541 {
00542     const TSize n = storage_.size();
00543     TValue result = TNumTraits::zero;
00544     for (TSize i = 0; i < n; ++i)
00545     {
00546         result += storage_[i];
00547     }
00548     return result;
00549 }
00550 
00551 
00552 
00553 /** Return minimum of all components of vector.
00554  *
00555  *  @par Complexity: 
00556  *      O(this->size())
00557  */
00558 template <typename T, typename S>
00559 const typename Vector<T, S>::TValue
00560 Vector<T, S>::min() const
00561 {
00562     const TSize n = storage_.size();
00563     if (n == 0)
00564     {
00565         return TNumTraits::zero;
00566     }
00567     TValue result = storage_[0];
00568     for (TSize i = 1; i < n; ++i)
00569     {
00570         result = std::min(result, storage_[i]);
00571     }
00572     return result;
00573 }
00574 
00575 
00576 
00577 /** Return maximum of all components of vector.
00578  *
00579  *  @par Complexity: 
00580  *      O(this->size())
00581  */
00582 template <typename T, typename S>
00583 const typename Vector<T, S>::TValue
00584 Vector<T, S>::max() const
00585 {
00586     const TSize n = storage_.size();
00587     if (n == 0)
00588     {
00589         return TNumTraits::zero;
00590     }
00591     TValue result = storage_[0];
00592     for (TSize i = 1; i < n; ++i)
00593     {
00594         result = std::max(result, storage_[i]);
00595     }
00596     return result;
00597 }
00598 
00599 
00600 
00601 /** Return squared norm of vector.
00602  *  @return dot(*this, *this)
00603  *
00604  *  @par Complexity: 
00605  *      O(this->size())
00606  */
00607 template <typename T, typename S>
00608 const typename Vector<T, S>::TValue
00609 Vector<T, S>::squaredNorm() const
00610 {
00611     const TSize n = storage_.size();
00612     TValue result = TNumTraits::zero;
00613     for (TSize i = 0; i < n; ++i)
00614     {
00615         result += num::sqr(storage_[i]);
00616     }
00617     return result;
00618 }
00619 
00620 
00621 
00622 /** Return norm of vector.
00623  *  @return sqrt(this->squaredNorm())
00624  *
00625  *  @par Complexity: 
00626  *      O(this->size())
00627  */
00628 template <typename T, typename S>
00629 const typename Vector<T, S>::TValue
00630 Vector<T, S>::norm() const
00631 {
00632     return num::sqrt(squaredNorm());
00633 }
00634 
00635 
00636 
00637 /** return a unit vector with same direction/sense as this vector.
00638  *
00639  *  <i>The normalized vector of <b>X</b> is a vector in the same direction but with norm (length) 1.
00640  *  It is denoted <b>X^</b> and given by <b>X^</b> = <b>X</b> / |<b>X</b>|</i>,
00641  *  http://mathworld.wolfram.com/dimension_ormalizedVector.html.
00642  *
00643  *  @return *this / this->norm()
00644  *
00645  *  @par Complexity: 
00646  *      O(this->size())
00647  */
00648 template <typename T, typename S>
00649 const Vector<T, impl::VMul<T, S, impl::VScalar<T> > >
00650 Vector<T, S>::normal() const
00651 {
00652     const TValue scale = TNumTraits::one / norm();
00653     typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
00654     return Vector<T, TExpression>(TExpression(storage_, impl::VScalar<T>(storage_.size(), scale)));
00655 }
00656 
00657 
00658 
00659 /** return a vector with each component being the reciprocal value of this vector.
00660  *
00661  *  @par Complexity: 
00662  *      O(1)
00663  */
00664 template <typename T, typename S>
00665 const Vector<T, impl::VRec<T, S> >
00666 Vector<T, S>::reciprocal() const
00667 {
00668     typedef impl::VRec<T, S> TExpression;
00669     return Vector<T, TExpression>(TExpression(storage_));
00670 }
00671 
00672 
00673 
00674 /** Project vector on this one
00675  *
00676  *  @pre this->size() == iB.size()
00677  *
00678  *  @par Complexity: 
00679  *      O(this->size())
00680  */
00681 template <typename T, typename S>
00682 template <typename S2>
00683 const Vector<T, impl::VMul<T, S, impl::VScalar<T> > >
00684 Vector<T, S>::project(const Vector<T, S2>& iB) const
00685 {
00686     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(*this, iB);
00687     const TValue scale = dot(iB, *this) / squaredNorm();
00688     typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
00689     return Vector<T, TExpression>(TExpression(storage_, impl::VScalar<T>(storage_.size(), scale)));
00690 }
00691 
00692 
00693 
00694 /** Project vector on this one
00695  *
00696  *  @pre this->size() == iB.size()
00697  *
00698  *  @par Complexity: 
00699  *      O(this->size())
00700  */
00701 template <typename T, typename S>
00702 template <typename S2>
00703 const Vector<T, impl::VSub<T, S2, impl::VMul<T, S, impl::VScalar<T> > > >
00704 Vector<T, S>::reject(const Vector<T, S2>& iB) const
00705 {
00706     return iB - project(iB);
00707 }
00708 
00709 
00710 
00711 /** Normalize vector.
00712  *
00713  *  @pre @c this must be an l-value.
00714  *
00715  *  @par Complexity: 
00716  *      O(this->size())
00717  */
00718 template <typename T, typename S>
00719 void Vector<T, S>::normalize()
00720 {
00721     *this /= norm();
00722 }
00723 
00724 
00725 
00726 template <typename T, typename S> inline
00727 const typename Vector<T, S>::TStorage&
00728 Vector<T, S>::storage() const
00729 {
00730     return storage_;
00731 }
00732 
00733 
00734 
00735 template <typename T, typename S> inline
00736 typename Vector<T, S>::TStorage&
00737 Vector<T, S>::storage()
00738 {
00739     return storage_;
00740 }
00741 
00742 
00743 
00744 /** swap storage of two vectors
00745  *
00746  *  @pre @c this and @ a iOther must be l-values
00747  *
00748  *  @par Complexity: 
00749  *      O(1)
00750  *
00751  *  @par Exception safety: 
00752  *      no-fail
00753  */
00754 template <typename T, typename S>
00755 void Vector<T, S>::swap(Vector<T, S>& iOther)
00756 {
00757     storage_.swap(iOther.storage_);
00758 }
00759 
00760 
00761 
00762 // --- private -------------------------------------------------------------------------------------
00763 
00764 template <typename T, typename S>
00765 template <typename IntegralType>
00766 void Vector<T, S>::init(IntegralType iDimension, meta::Wrap<meta::True>)
00767 {
00768     TStorage temp(iDimension, T());
00769     storage_.swap(temp);
00770 }
00771 
00772 
00773 
00774 template <typename T, typename S>
00775 template <typename VectorType>
00776 void Vector<T, S>::init(const VectorType& iVector, meta::Wrap<meta::False>)
00777 {
00778     TSize n = iVector.size();
00779     TStorage temp(n, T());
00780     for (TSize i = 0; i < n; ++i)
00781     {
00782         temp[i] = iVector[i];
00783     }
00784     storage_.swap(temp);
00785 }
00786     
00787 
00788 
00789 // --- free ----------------------------------------------------------------------------------------
00790 
00791 
00792 
00793 /** @relates lass::prim::Vector
00794  *
00795  *  @par Complexity: 
00796  *      O(iA->size())
00797  */
00798 template <typename T, typename S1, typename S2>
00799 bool operator==(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00800 {
00801     typedef typename Vector<T, S1>::TSize TSize;
00802     const TSize n = iA.size();
00803 
00804     if (n != iB.size())
00805     {
00806         return false;
00807     }
00808     for (TSize i = 0; i < n; ++i)
00809     {
00810         if (iA[i] != iB[i])
00811         {
00812             return false;
00813         }
00814     }
00815     return true;
00816 }
00817 
00818 
00819 
00820 /** @relates lass::prim::Vector
00821  *
00822  *  @par Complexity: 
00823  *      O(iA.size())
00824  */
00825 template <typename T, typename S1, typename S2>
00826 bool operator!=(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00827 {
00828     return !(iA == iB);
00829 }
00830 
00831 
00832 
00833 /** dot product.
00834  *  @relates lass::num::Vector
00835  *
00836  *  @pre iA.size() == iB.size()
00837  *
00838  *  @par Complexity: 
00839  *      O(iA.size())
00840  */
00841 template <typename T, typename S1, typename S2>
00842 const T dot(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00843 {
00844     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
00845     typedef typename Vector<T, S1>::TSize TSize;
00846     const TSize n = iA.size();
00847 
00848     T result = NumTraits<T>::zero;
00849     for (TSize i = 0; i < n; ++i)
00850     {
00851         result += iA[i] * iB[i];
00852     }
00853     return result;
00854 }
00855 
00856 
00857 
00858 /** componentwise addition
00859  *  @relates lass::num::Vector
00860  *
00861  *  @pre iA.size() == iB.size()
00862  *
00863  *  @par Complexity: 
00864  *      O(1)
00865  */
00866 template <typename T, typename S1, typename S2>
00867 const Vector<T, impl::VAdd<T, S1, S2> >
00868 operator+(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00869 {
00870     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
00871     typedef impl::VAdd<T, S1, S2> TExpression;
00872     return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
00873 }
00874 
00875 
00876 
00877 /** componentwise subtraction
00878  *  @relates lass::num::Vector
00879  *
00880  *  @pre iA.size() == iB.size()
00881  *
00882  *  @par Complexity: 
00883  *      O(1)
00884  */
00885 template <typename T, typename S1, typename S2>
00886 const Vector<T, impl::VSub<T, S1, S2> >
00887 operator-(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00888 {
00889     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
00890     typedef impl::VSub<T, S1, S2> TExpression;
00891     return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
00892 }
00893 
00894 
00895 
00896 /** componentwise multiplication
00897  *  @relates lass::num::Vector
00898  *
00899  *  @pre iA.size() == iB.size()
00900  *
00901  *  @par Complexity: 
00902  *      O(1)
00903  */
00904 template <typename T, typename S1, typename S2>
00905 const Vector<T, impl::VMul<T, S1, S2> >
00906 operator*(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00907 {
00908     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
00909     typedef impl::VMul<T, S1, S2> TExpression;
00910     return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
00911 }
00912 
00913 
00914 
00915 /** componentwise division
00916  *  @relates lass::num::Vector
00917  *
00918  *  @pre iA.size() == iB.size()
00919  *
00920  *  @par Complexity: 
00921  *      O(1)
00922  */
00923 template <typename T, typename S1, typename S2>
00924 const Vector<T, impl::VDiv<T, S1, S2> >
00925 operator/(const Vector<T, S1>& iA, const Vector<T, S2>& iB)
00926 {
00927     LASS_NUM_VECTOR_ENFORCE_EQUAL_DIMENSION(iA, iB);
00928     typedef impl::VDiv<T, S1, S2> TExpression;
00929     return Vector<T, TExpression>(TExpression(iA.storage(), iB.storage()));
00930 }
00931 
00932 
00933 
00934 /** add @a iA to all components of @a iB
00935  *  @relates lass::num::Vector
00936  *
00937  *  @par Complexity: 
00938  *      O(1)
00939  */
00940 template <typename T, typename S>
00941 const Vector<T, impl::VAdd<T, impl::VScalar<T>, S> >
00942 operator+(const T& iA, const Vector<T, S>& iB)
00943 {
00944     typedef impl::VAdd<T, impl::VScalar<T>, S> TExpression;
00945     return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
00946 }
00947 
00948 
00949 
00950 /** add @a iA to all negated components of @a iB
00951  *  @relates lass::num::Vector
00952  *
00953  *  @par Complexity: 
00954  *      O(1)
00955  */
00956 template <typename T, typename S>
00957 const Vector<T, impl::VSub<T, impl::VScalar<T>, S> >
00958 operator-(const T& iA, const Vector<T, S>& iB)
00959 {
00960     typedef impl::VSub<T, impl::VScalar<T>, S> TExpression;
00961     return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
00962 }
00963 
00964 
00965 
00966 /** multiply @a iA with all components of @a iB
00967  *  @relates lass::num::Vector
00968  *
00969  *  @par Complexity: 
00970  *      O(1)
00971  */
00972 template <typename T, typename S>
00973 const Vector<T, impl::VMul<T, impl::VScalar<T>, S> >
00974 operator*(const T& iA, const Vector<T, S>& iB)
00975 {
00976     typedef impl::VMul<T, impl::VScalar<T>, S> TExpression;
00977     return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
00978 }
00979 
00980 
00981 
00982 /** multiply @a iA with all reciprocal components of @a iB
00983  *  @relates lass::num::Vector
00984  *
00985  *  @par Complexity: 
00986  *      O(1)
00987  */
00988 template <typename T, typename S>
00989 const Vector<T, impl::VDiv<T, impl::VScalar<T>, S> >
00990 operator/(const T& iA, const Vector<T, S>& iB)
00991 {
00992     typedef impl::VDiv<T, impl::VScalar<T>, S> TExpression;
00993     return Vector<T, TExpression>(TExpression(impl::VScalar<T>(iB.size(), iA), iB.storage()));
00994 }
00995 
00996 
00997 
00998 /** add @a iB to all components of @a iA
00999  *  @relates lass::num::Vector
01000  *
01001  *  @par Complexity: 
01002  *      O(1)
01003  */
01004 template <typename T, typename S>
01005 const Vector<T, impl::VAdd<T, S, impl::VScalar<T> > >
01006 operator+(const Vector<T, S>& iA, const T& iB)
01007 {
01008     typedef impl::VAdd<T, S, impl::VScalar<T> > TExpression;
01009     return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
01010 }
01011 
01012 
01013 
01014 /** subtract @a iB from all components of @a iA
01015  *  @relates lass::num::Vector
01016  *
01017  *  @par Complexity: 
01018  *      O(1)
01019  */
01020 template <typename T, typename S>
01021 const Vector<T, impl::VSub<T, S, impl::VScalar<T> > >
01022 operator-(const Vector<T, S>& iA, const T& iB)
01023 {
01024     typedef impl::VSub<T, S, impl::VScalar<T> > TExpression;
01025     return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
01026 }
01027 
01028 
01029 
01030 /** multiply all components of @a iA with @a iB.
01031  *  @relates lass::num::Vector
01032  *
01033  *  @par Complexity: 
01034  *      O(1)
01035  */
01036 template <typename T, typename S>
01037 const Vector<T, impl::VMul<T, S, impl::VScalar<T> > >
01038 operator*(const Vector<T, S>& iA, const T& iB)
01039 {
01040     typedef impl::VMul<T, S, impl::VScalar<T> > TExpression;
01041     return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
01042 }
01043 
01044 
01045 
01046 /** multiply all components of @a iA with @a iB.
01047  *  @relates lass::num::Vector
01048  *
01049  *  @par Complexity: 
01050  *      O(1)
01051  */
01052 template <typename T, typename S>
01053 const Vector<T, impl::VDiv<T, S, impl::VScalar<T> > >
01054 operator/(const Vector<T, S>& iA, const T& iB)
01055 {
01056     typedef impl::VDiv<T, S, impl::VScalar<T> > TExpression;
01057     return Vector<T, TExpression>(TExpression(iA.storage(), impl::VScalar<T>(iA.size(), iB)));
01058 }
01059 
01060 
01061 
01062 /** @relates lass::prim::Vector
01063  *
01064  *  @par Complexity: 
01065  *      O(iB.size())
01066  */
01067 template <typename T, typename S, typename Char, typename Traits>
01068 std::basic_ostream<Char, Traits>&
01069 operator<<(std::basic_ostream<Char, Traits>& oOStream, const Vector<T, S>& iB)
01070 {
01071     typedef typename Vector<T, S>::TSize TSize;
01072     const TSize n = iB.size();
01073 
01074     LASS_ENFORCE_STREAM(oOStream) << "(";
01075     if (n > 0)
01076     {
01077         LASS_ENFORCE_STREAM(oOStream) << iB[0];
01078     }
01079     for (TSize i = 1; i < n; ++i)
01080     {
01081         LASS_ENFORCE_STREAM(oOStream) << ", " << iB[i];
01082     }
01083     LASS_ENFORCE_STREAM(oOStream) << ")";
01084     return oOStream;
01085 }
01086 
01087 
01088 
01089 /** @relates lass::prim::Vector
01090  */
01091 template <typename T, typename Char, typename Traits>
01092 std::basic_istream<Char, Traits>&
01093 operator>>(std::basic_istream<Char, Traits>& ioIStream, Vector<T>& oB)
01094 {
01095     typedef typename Vector<T>::TValue TValue;
01096     typedef typename Vector<T>::TSize TSize;
01097     typedef typename Vector<T>::TStorage TStorage;
01098 
01099     TStorage buffer;
01100     TValue value;
01101     TSize size = 0;
01102 
01103     char c = 0;
01104     LASS_ENFORCE_STREAM(ioIStream) >> c;
01105     if (c != '(')
01106     {
01107         ioIStream.clear(std::ios::failbit);
01108         return ioIStream;
01109     }
01110 
01111     // TODO peek for empty vectors '()'
01112 
01113     // assume no empty vector here
01114     do
01115     {
01116         c = 0;
01117         LASS_ENFORCE_STREAM(ioIStream) >> value >> c;
01118         buffer.push_back(value);
01119         ++size;
01120         if (c != ',' && c != ')')
01121         {
01122             ioIStream.clear(std::ios::failbit);
01123             return ioIStream;
01124         }
01125     }
01126     while (c != ')');
01127 
01128     oB.storage().swap(buffer);
01129     return ioIStream;
01130 }
01131 
01132 
01133 
01134 }
01135 
01136 }
01137 
01138 #endif
01139 
01140 // EOF

Generated on Mon Nov 10 14:22:02 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo