Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_Vector.i.h
00001 // @HEADER
00002 // ************************************************************************
00003 //
00004 //                           Intrepid Package
00005 //                 Copyright (2007) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions: Alejandro Mota (amota@sandia.gov)
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 
00042 #if !defined(Intrepid_MiniTensor_Vector_i_h)
00043 #define Intrepid_MiniTensor_Vector_i_h
00044 
00045 namespace Intrepid
00046 {
00047 
00048 //
00049 // Default constructor
00050 //
00051 template<typename T, Index N>
00052 inline
00053 Vector<T, N>::Vector() :
00054 TensorBase<T, Store>::TensorBase()
00055 {
00056   return;
00057 }
00058 
00059 //
00060 // Constructor that initializes to NaNs
00061 //
00062 template<typename T, Index N>
00063 inline
00064 Vector<T, N>::Vector(Index const dimension) :
00065 TensorBase<T, Store>::TensorBase(dimension, ORDER)
00066 {
00067   return;
00068 }
00069 
00073 template<typename T, Index N>
00074 inline
00075 Vector<T, N>::Vector(Index const dimension, ComponentValue const value) :
00076 TensorBase<T, Store>::TensorBase(dimension, ORDER, value)
00077 {
00078   return;
00079 }
00080 
00081 template<typename T, Index N>
00082 inline
00083 Vector<T, N>::Vector(ComponentValue const value) :
00084 TensorBase<T, Store>::TensorBase(N, ORDER, value)
00085 {
00086   return;
00087 }
00088 
00089 //
00090 // Create vector from array
00091 //
00092 template<typename T, Index N>
00093 inline
00094 Vector<T, N>::Vector(Index const dimension, T const * data_ptr) :
00095 TensorBase<T, Store>::TensorBase(dimension, ORDER, data_ptr)
00096 {
00097   return;
00098 }
00099 
00100 template<typename T, Index N>
00101 inline
00102 Vector<T, N>::Vector(T const * data_ptr) :
00103 TensorBase<T, Store>::TensorBase(N, ORDER, data_ptr)
00104 {
00105   return;
00106 }
00107 
00108 //
00109 // Copy constructor
00110 //
00111 template<typename T, Index N>
00112 inline
00113 Vector<T, N>::Vector(Vector<T, N> const & v) :
00114 TensorBase<T, Store>::TensorBase(v)
00115 {
00116   return;
00117 }
00118 
00119 //
00120 // Create vector specifying components
00121 //
00122 template<typename T, Index N>
00123 inline
00124 Vector<T, N>::Vector(T const & s0, T const & s1)
00125 {
00126   Vector<T, N> &
00127   self = (*this);
00128 
00129   self.set_dimension(2);
00130 
00131   self[0] = s0;
00132   self[1] = s1;
00133 
00134   return;
00135 }
00136 
00137 //
00138 // Create vector specifying components
00139 //
00140 template<typename T, Index N>
00141 inline
00142 Vector<T, N>::Vector(T const & s0, T const & s1, T const & s2)
00143 {
00144   Vector<T, N> &
00145   self = (*this);
00146 
00147   self.set_dimension(3);
00148 
00149   self[0] = s0;
00150   self[1] = s1;
00151   self[2] = s2;
00152 
00153   return;
00154 }
00155 
00156 //
00157 // Simple destructor
00158 //
00159 template<typename T, Index N>
00160 inline
00161 Vector<T, N>::~Vector()
00162 {
00163   return;
00164 }
00165 
00166 //
00167 // Get dimension
00168 //
00169 template<typename T, Index N>
00170 inline
00171 Index
00172 Vector<T, N>::get_dimension() const
00173 {
00174   return IS_DYNAMIC == true ? TensorBase<T, Store>::get_dimension() : N;
00175 }
00176 
00177 //
00178 // Set dimension
00179 //
00180 template<typename T, Index N>
00181 inline
00182 void
00183 Vector<T, N>::set_dimension(Index const dimension)
00184 {
00185   if (IS_DYNAMIC == true) {
00186     TensorBase<T, Store>::set_dimension(dimension, ORDER);
00187   }
00188   else {
00189     assert(dimension == N);
00190   }
00191 
00192   return;
00193 }
00194 
00195 //
00196 // Indexing for constant vector
00197 //
00198 template<typename T, Index N>
00199 inline
00200 T const &
00201 Vector<T, N>::operator()(Index const i) const
00202 {
00203   return (*this)[i];
00204 }
00205 
00206 //
00207 // Vector indexing
00208 //
00209 template<typename T, Index N>
00210 inline
00211 T &
00212 Vector<T, N>::operator()(Index const i)
00213 {
00214   return (*this)[i];
00215 }
00216 
00217 //
00218 // Vector addition
00219 //
00220 template<typename S, typename T, Index N>
00221 inline
00222 Vector<typename Promote<S, T>::type, N>
00223 operator+(Vector<S, N> const & u, Vector<T, N> const & v)
00224 {
00225   Vector<typename Promote<S, T>::type, N>
00226   w(u.get_dimension());
00227 
00228   add(u, v, w);
00229 
00230   return w;
00231 }
00232 
00233 //
00234 // Vector subtraction
00235 //
00236 template<typename S, typename T, Index N>
00237 inline
00238 Vector<typename Promote<S, T>::type, N>
00239 operator-(Vector<S, N> const & u, Vector<T, N> const & v)
00240 {
00241   Vector<typename Promote<S, T>::type, N>
00242   w(u.get_dimension());
00243 
00244   subtract(u, v, w);
00245 
00246   return w;
00247 }
00248 
00249 //
00250 // Vector minus
00251 //
00252 template<typename T, Index N>
00253 inline
00254 Vector<T, N>
00255 operator-(Vector<T, N> const & u)
00256 {
00257   Vector<T, N>
00258   v(u.get_dimension());
00259 
00260   minus(u, v);
00261 
00262   return v;
00263 }
00264 
00265 //
00266 // Vector dot product
00267 //
00268 template<typename S, typename T, Index N>
00269 inline
00270 typename Promote<S, T>::type
00271 operator*(Vector<S, N> const & u, Vector<T, N> const & v)
00272 {
00273   return dot(u, v);
00274 }
00275 
00276 //
00277 // Vector equality tested by components
00278 //
00279 template<typename T, Index N>
00280 inline
00281 bool
00282 operator==(Vector<T, N> const & u, Vector<T, N> const & v)
00283 {
00284   return equal(u, v);
00285 }
00286 
00287 //
00288 // Vector inequality tested by components
00289 //
00290 template<typename T, Index N>
00291 inline
00292 bool
00293 operator!=(Vector<T, N> const & u, Vector<T, N> const & v)
00294 {
00295   return not_equal(u, v);
00296 }
00297 
00298 //
00299 // Scalar vector product
00300 //
00301 template<typename S, typename T, Index N>
00302 inline
00303 typename lazy_disable_if< order_1234<S>, apply_vector< Promote<S,T>, N> >::type
00304 operator*(S const & s, Vector<T, N> const & u)
00305 {
00306   Vector<typename Promote<S, T>::type, N>
00307   v(u.get_dimension());
00308 
00309   scale(u, s, v);
00310 
00311   return v;
00312 }
00313 
00314 //
00315 // Vector scalar product
00316 //
00317 template<typename S, typename T, Index N>
00318 inline
00319 typename lazy_disable_if< order_1234<S>, apply_vector< Promote<S,T>, N> >::type
00320 operator*(Vector<T, N> const & u, S const & s)
00321 {
00322   Vector<typename Promote<S, T>::type, N>
00323   v(u.get_dimension());
00324 
00325   scale(u, s, v);
00326 
00327   return v;
00328 }
00329 
00330 //
00331 // Vector scalar division
00332 //
00333 template<typename S, typename T, Index N>
00334 inline
00335 Vector<typename Promote<S, T>::type, N>
00336 operator/(Vector<T, N> const & u, S const & s)
00337 {
00338   Vector<typename Promote<S, T>::type, N>
00339   v(u.get_dimension());
00340 
00341   divide(u, s, v);
00342 
00343   return v;
00344 }
00345 
00346 //
00347 // Scalar vector division
00348 //
00349 template<typename S, typename T, Index N>
00350 inline
00351 Vector<typename Promote<S, T>::type, N>
00352 operator/(S const & s, Vector<T, N> const & u)
00353 {
00354   Vector<typename Promote<S, T>::type, N>
00355   v(u.get_dimension());
00356 
00357   split(u, s, v);
00358 
00359   return v;
00360 }
00361 
00362 //
00363 // Vector dot product
00364 //
00365 template<typename S, typename T, Index N>
00366 inline
00367 typename Promote<S, T>::type
00368 dot(Vector<S, N> const & u, Vector<T, N> const & v)
00369 {
00370   Index const
00371   dimension = u.get_dimension();
00372 
00373   assert(v.get_dimension() == dimension);
00374 
00375   typename Promote<S, T>::type
00376   s = 0.0;
00377 
00378   switch (dimension) {
00379 
00380     default:
00381       for (Index i = 0; i < dimension; ++i) {
00382         s += u(i) * v(i);
00383       }
00384       break;
00385 
00386     case 3:
00387       s = u(0) * v(0) + u(1) * v(1) + u(2) * v(2);
00388       break;
00389 
00390     case 2:
00391       s = u(0) * v(0) + u(1) * v(1);
00392       break;
00393 
00394   }
00395 
00396   return s;
00397 }
00398 
00399 //
00400 // Cross product only valid for R^3.
00401 //
00402 template<typename S, typename T, Index N>
00403 inline
00404 Vector<typename Promote<S, T>::type, N>
00405 cross(Vector<S, N> const & u, Vector<T, N> const & v)
00406 {
00407   Index const
00408   dimension = u.get_dimension();
00409 
00410   assert(v.get_dimension() == dimension);
00411 
00412   Vector<typename Promote<S, T>::type, N>
00413   w(dimension);
00414 
00415   switch (dimension) {
00416 
00417     case 3:
00418       w(0) = u(1) * v(2) - u(2) * v(1);
00419       w(1) = u(2) * v(0) - u(0) * v(2);
00420       w(2) = u(0) * v(1) - u(1) * v(0);
00421       break;
00422 
00423     default:
00424       std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00425       std::cerr << std::endl;
00426       std::cerr << "Cross product undefined for R^" << dimension;
00427       std::cerr << std::endl;
00428       exit(1);
00429       break;
00430 
00431   }
00432 
00433   return w;
00434 }
00435 
00436 //
00437 // R^N vector 2-norm
00438 // \return \f$ \sqrt{u \cdot u} \f$
00439 //
00440 template<typename T, Index N>
00441 inline
00442 T
00443 norm(Vector<T, N> const & u)
00444 {
00445   Index const
00446   dimension = u.get_dimension();
00447 
00448   T
00449   s = 0.0;
00450 
00451   switch (dimension) {
00452 
00453     default:
00454       s = std::sqrt(dot(u, u));
00455       break;
00456 
00457     case 3:
00458       s = std::sqrt(u(0) * u(0) + u(1) * u(1) + u(2) * u(2));
00459       break;
00460 
00461     case 2:
00462       s = std::sqrt(u(0) * u(0) + u(1) * u(1));
00463       break;
00464 
00465   }
00466 
00467   return s;
00468 }
00469 
00470 //
00471 // R^N vector 2-norm square for fast distance calculations.
00472 // \return \f$ u \cdot u \f$
00473 //
00474 template<typename T, Index N>
00475 inline
00476 T
00477 norm_square(Vector<T, N> const & u)
00478 {
00479   Index const
00480   dimension = u.get_dimension();
00481 
00482   T
00483   s = 0.0;
00484 
00485   switch (dimension) {
00486 
00487     default:
00488       s = dot(u, u);
00489       break;
00490 
00491     case 3:
00492       s = u(0) * u(0) + u(1) * u(1) + u(2) * u(2);
00493       break;
00494 
00495     case 2:
00496       s = u(0) * u(0) + u(1) * u(1);
00497       break;
00498 
00499   }
00500 
00501   return s;
00502 }
00503 
00504 //
00505 // R^N vector 1-norm
00506 // \return \f$ \sum_i |u_i| \f$
00507 //
00508 template<typename T, Index N>
00509 inline
00510 T
00511 norm_1(Vector<T, N> const & u)
00512 {
00513   Index const
00514   dimension = u.get_dimension();
00515 
00516   T
00517   s = 0.0;
00518 
00519   switch (dimension) {
00520 
00521     default:
00522       for (Index i = 0; i < dimension; ++i) {
00523         s += std::abs(u(i));
00524       }
00525       break;
00526 
00527     case 3:
00528       s = std::abs(u(0)) + std::abs(u(1)) + std::abs(u(2));
00529       break;
00530 
00531     case 2:
00532       s = std::abs(u(0)) + std::abs(u(1));
00533       break;
00534 
00535   }
00536 
00537   return s;
00538 }
00539 
00540 //
00541 // R^N vector infinity-norm
00542 // \return \f$ \max(|u_0|,...|u_i|,...|u_N|) \f$
00543 //
00544 template<typename T, Index N>
00545 inline
00546 T
00547 norm_infinity(Vector<T, N> const & u)
00548 {
00549   Index const
00550   dimension = u.get_dimension();
00551 
00552   T
00553   s = 0.0;
00554 
00555   switch (dimension) {
00556 
00557     default:
00558       for (Index i = 0; i < dimension; ++i) {
00559         s = std::max(s, std::abs(u(i)));
00560       }
00561       break;
00562 
00563     case 3:
00564       s = std::max(std::max(std::abs(u(0)), std::abs(u(1))), std::abs(u(2)));
00565       break;
00566 
00567     case 2:
00568       s = std::max(std::abs(u(0)), std::abs(u(1)));
00569       break;
00570 
00571   }
00572 
00573   return s;
00574 }
00575 
00576 //
00577 // \return u / |u|, fails for |u| = 0
00578 //
00579 template<typename T, Index N>
00580 inline
00581 Vector<T, N>
00582 unit(Vector<T, N> const & u)
00583 {
00584   return u / norm(u);
00585 }
00586 
00587 //
00588 // Compute Householder vector
00589 //
00590 template<typename T, Index N>
00591 std::pair<Vector<T, N>, T>
00592 house(Vector<T, N> const & x)
00593 {
00594   Vector<T, N>
00595   v = x;
00596 
00597   v[0] = 1.0;
00598 
00599   Index const
00600   dimension = x.get_dimension();
00601 
00602   T
00603   sigma = 0.0;
00604 
00605   for (Index i = 1; i < dimension; ++i) {
00606     sigma = v[i] * v[i];
00607   }
00608 
00609   T
00610   beta = 0.0;
00611 
00612   if (sigma > 0.0) {
00613     T const
00614     mu = std::sqrt(x[0] * x[0] + sigma);
00615     v[0] = x[0] > 0.0 ? -sigma / (x[0] + mu) : x[0] - mu;
00616     beta = 2.0 * v[0] * v[0] / (sigma + v[0] * v[0]);
00617     v = v / v[0];
00618   }
00619 
00620   return std::make_pair(v, beta);
00621 }
00622 
00623 } // namespace Intrepid
00624 
00625 #endif // Intrepid_MiniTensor_Vector_i_h