Intrepid
/usr/src/RPM/BUILD/trilinos-11.12.1/packages/intrepid/src/Shared/MiniTensor/Intrepid_MiniTensor_TensorBase.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_TensorBase_i_h)
00043 #define Intrepid_MiniTensor_TensorBase_i_h
00044 
00045 namespace Intrepid
00046 {
00047 
00048 //
00049 // Default constructor.
00050 //
00051 template<typename T, typename ST>
00052 inline
00053 TensorBase<T, ST>::TensorBase() :
00054 dimension_(0)
00055 {
00056   if (ST::IS_DYNAMIC == true) {
00057     set_number_components(0);
00058   } else {
00059     fill(NANS);
00060   }
00061   return;
00062 }
00063 
00064 //
00065 // Construction that initializes to NaNs
00066 //
00067 template<typename T, typename ST>
00068 inline
00069 TensorBase<T, ST>::TensorBase(Index const dimension, Index const order) :
00070 dimension_(0)
00071 {
00072   set_dimension(dimension, order);
00073 
00074   fill(NANS);
00075 
00076   return;
00077 }
00078 
00079 //
00080 // Create with specified value
00081 //
00082 template<typename T, typename ST>
00083 inline
00084 TensorBase<T, ST>::TensorBase(
00085     Index const dimension,
00086     Index const order,
00087     ComponentValue const value) :
00088     dimension_(0)
00089 {
00090   set_dimension(dimension, order);
00091 
00092   fill(value);
00093 
00094   return;
00095 }
00096 
00097 //
00098 // Construction from a scalar
00099 //
00100 template<typename T, typename ST>
00101 inline
00102 TensorBase<T, ST>::TensorBase(
00103     Index const dimension,
00104     Index const order,
00105     T const & s) :
00106     dimension_(0)
00107 {
00108   set_dimension(dimension, order);
00109 
00110   fill(s);
00111 
00112   return;
00113 }
00114 
00115 //
00116 // Construction from array
00117 //
00118 template<typename T, typename ST>
00119 inline
00120 TensorBase<T, ST>::TensorBase(
00121     Index const dimension,
00122     Index const order,
00123     T const * data_ptr) :
00124     dimension_(0)
00125 {
00126   set_dimension(dimension, order);
00127 
00128   fill(data_ptr);
00129 
00130   return;
00131 }
00132 
00133 //
00134 // Copy constructor
00135 //
00136 template<typename T, typename ST>
00137 inline
00138 TensorBase<T, ST>::TensorBase(TensorBase<T, ST> const & X) :
00139 dimension_(X.dimension_)
00140 {
00141   Index const
00142   number_components = X.get_number_components();
00143 
00144   set_number_components(number_components);
00145 
00146   for (Index i = 0; i < number_components; ++i) {
00147     (*this)[i] = X[i];
00148   }
00149 
00150   return;
00151 }
00152 
00153 //
00154 // Copy assignment
00155 //
00156 template<typename T, typename ST>
00157 inline
00158 TensorBase<T, ST> &
00159 TensorBase<T, ST>::operator=(TensorBase<T, ST> const & X)
00160 {
00161   if (this == &X) return *this;
00162 
00163   dimension_ = X.dimension_;
00164 
00165   Index const
00166   number_components = X.get_number_components();
00167 
00168   set_number_components(number_components);
00169 
00170   for (Index i = 0; i < number_components; ++i) {
00171     (*this)[i] = X[i];
00172   }
00173 
00174   return *this;
00175 }
00176 
00177 //
00178 // Simple destructor
00179 //
00180 template<typename T, typename ST>
00181 inline
00182 TensorBase<T, ST>::~TensorBase()
00183 {
00184   return;
00185 }
00186 
00187 //
00188 // Get dimension
00189 //
00190 template<typename T, typename ST>
00191 inline
00192 Index
00193 TensorBase<T, ST>::get_dimension() const
00194 {
00195   assert(ST::IS_DYNAMIC == true);
00196 
00197   return dimension_;
00198 }
00199 
00200 //
00201 // Set dimension
00202 //
00203 template<typename T, typename ST>
00204 inline
00205 void
00206 TensorBase<T, ST>::set_dimension(Index const dimension, Index const order)
00207 {
00208   if (ST::IS_STATIC == true) return;
00209 
00210   dimension_ = dimension;
00211 
00212   Index const
00213   number_components = integer_power(dimension, order);
00214 
00215   set_number_components(number_components);
00216 
00217   return;
00218 }
00219 
00220 //
00221 // Linear access to components
00222 //
00223 template<typename T, typename ST>
00224 inline
00225 T const &
00226 TensorBase<T, ST>::operator[](Index const i) const
00227 {
00228   return components_[i];
00229 }
00230 
00231 //
00232 // Linear access to components
00233 //
00234 template<typename T, typename ST>
00235 inline
00236 T &
00237 TensorBase<T, ST>::operator[](Index const i)
00238 {
00239   return components_[i];
00240 }
00241 
00242 //
00243 // Get total number of components
00244 //
00245 template<typename T, typename ST>
00246 inline
00247 Index
00248 TensorBase<T, ST>::get_number_components() const
00249 {
00250   return components_.size();
00251 }
00252 
00253 //
00254 // Allocate space for components
00255 //
00256 template<typename T, typename ST>
00257 inline
00258 void
00259 TensorBase<T, ST>::set_number_components(Index const number_components)
00260 {
00261   components_.resize(number_components);
00262 
00263   return;
00264 }
00265 
00266 //
00267 // Fill components with value.
00268 //
00269 template<typename T, typename ST>
00270 inline
00271 void
00272 TensorBase<T, ST>::fill(ComponentValue const value)
00273 {
00274   Index const
00275   number_components = get_number_components();
00276 
00277   switch (value) {
00278 
00279     case ZEROS:
00280       for (Index i = 0; i < number_components; ++i) {
00281         (*this)[i] = 0;
00282       }
00283       break;
00284 
00285     case ONES:
00286       for (Index i = 0; i < number_components; ++i) {
00287         (*this)[i] = 1;
00288       }
00289       break;
00290 
00291     case SEQUENCE:
00292       for (Index i = 0; i < number_components; ++i) {
00293         (*this)[i] = static_cast<T>(i);
00294       }
00295       break;
00296 
00297     case RANDOM_UNIFORM:
00298       for (Index i = 0; i < number_components; ++i) {
00299         (*this)[i] = random_uniform<T>();
00300       }
00301       break;
00302 
00303     case RANDOM_NORMAL:
00304       for (Index i = 0; i < number_components; ++i) {
00305         (*this)[i] = random_normal<T>();
00306       }
00307       break;
00308 
00309     case NANS:
00310       for (Index i = 0; i < number_components; ++i) {
00311         (*this)[i] = not_a_number<T>();
00312       }
00313       break;
00314 
00315     default:
00316       std::cerr << "ERROR: " << __PRETTY_FUNCTION__;
00317       std::cerr << std::endl;
00318       std::cerr << "Unknown specification of value for filling components.";
00319       std::cerr << std::endl;
00320       exit(1);
00321       break;
00322   }
00323 
00324   return;
00325 }
00326 
00327 //
00328 // Fill components from argument
00329 //
00330 template<typename T, typename ST>
00331 inline
00332 void
00333 TensorBase<T, ST>::fill(T const & s)
00334 {
00335   Index const
00336   number_components = get_number_components();
00337 
00338   for (Index i = 0; i < number_components; ++i) {
00339     (*this)[i] = s;
00340   }
00341 
00342   return;
00343 }
00344 
00345 //
00346 // Fill components from array defined by pointer.
00347 //
00348 template<typename T, typename ST>
00349 inline
00350 void
00351 TensorBase<T, ST>::fill(T const * data_ptr)
00352 {
00353   assert(data_ptr != NULL);
00354 
00355   Index const
00356   number_components = get_number_components();
00357 
00358   for (Index i = 0; i < number_components; ++i) {
00359     (*this)[i] = data_ptr[i];
00360   }
00361 
00362   return;
00363 }
00364 
00365 //
00366 // Component increment
00367 //
00368 template<typename T, typename ST>
00369 template<typename S, typename SS>
00370 inline
00371 TensorBase<T, ST> &
00372 TensorBase<T, ST>::operator+=(TensorBase<S, SS> const & X)
00373 {
00374   Index const
00375   number_components = get_number_components();
00376 
00377   assert(number_components == X.get_number_components());
00378 
00379   for (Index i = 0; i < number_components; ++i) {
00380     (*this)[i] += X[i];
00381   }
00382 
00383   return *this;
00384 }
00385 
00386 //
00387 // Component decrement
00388 //
00389 template<typename T, typename ST>
00390 template<typename S, typename SS>
00391 inline
00392 TensorBase<T, ST> &
00393 TensorBase<T, ST>::operator-=(TensorBase<S, SS> const & X)
00394 {
00395   Index const
00396   number_components = get_number_components();
00397 
00398   assert(number_components == X.get_number_components());
00399 
00400   for (Index i = 0; i < number_components; ++i) {
00401     (*this)[i] -= X[i];
00402   }
00403 
00404   return *this;
00405 }
00406 
00407 //
00408 // Component scale
00409 //
00410 template<typename T, typename ST>
00411 template<typename S>
00412 inline
00413 TensorBase<T, ST> &
00414 TensorBase<T, ST>::operator*=(S const & X)
00415 {
00416   Index const
00417   number_components = get_number_components();
00418 
00419   for (Index i = 0; i < number_components; ++i) {
00420     (*this)[i] *= X;
00421   }
00422   return *this;
00423 }
00424 
00425 //
00426 // Component divide
00427 //
00428 template<typename T, typename ST>
00429 template<typename S>
00430 inline
00431 TensorBase<T, ST> &
00432 TensorBase<T, ST>::operator/=(S const & X)
00433 {
00434   Index const
00435   number_components = get_number_components();
00436 
00437   for (Index i = 0; i < number_components; ++i) {
00438     (*this)[i] /= X;
00439   }
00440   return *this;
00441 }
00442 
00443 //
00444 // Fill with zeros
00445 //
00446 template<typename T, typename ST>
00447 inline
00448 void
00449 TensorBase<T, ST>::clear()
00450 {
00451   fill(ZEROS);
00452   return;
00453 }
00454 
00455 //
00456 // Square of Frobenius norm
00457 //
00458 template<typename T, typename ST>
00459 T
00460 norm_f_square(TensorBase<T, ST> const & X)
00461 {
00462   T
00463   s = 0.0;
00464 
00465   for (Index i = 0; i < X.get_number_components(); ++i) {
00466     s += X[i] * X[i];
00467   }
00468 
00469   return s;
00470 }
00471 
00472 //
00473 // Frobenius norm
00474 //
00475 template<typename T, typename ST>
00476 T
00477 norm_f(TensorBase<T, ST> const & X)
00478 {
00479   return std::sqrt(norm_f_square(X));
00480 }
00481 
00482 //
00483 // Base addition
00484 //
00485 template<typename R, typename S, typename T, typename SR, typename SS,
00486 typename ST>
00487 void
00488 add(
00489     TensorBase<R, SR> const & A,
00490     TensorBase<S, SS> const & B,
00491     TensorBase<T, ST> & C
00492 )
00493 {
00494   Index const
00495   number_components = A.get_number_components();
00496 
00497   assert(B.get_number_components() == number_components);
00498   assert(C.get_number_components() == number_components);
00499 
00500   for (Index i = 0; i < number_components; ++i) {
00501     C[i] = A[i] + B[i];
00502   }
00503 
00504   return;
00505 }
00506 
00507 //
00508 // Base subtraction
00509 //
00510 template<typename R, typename S, typename T, typename SR, typename SS,
00511 typename ST>
00512 void
00513 subtract(
00514     TensorBase<R, SR> const & A,
00515     TensorBase<S, SS> const & B,
00516     TensorBase<T, ST> & C)
00517 {
00518   Index const
00519   number_components = A.get_number_components();
00520 
00521   assert(B.get_number_components() == number_components);
00522   assert(C.get_number_components() == number_components);
00523 
00524   for (Index i = 0; i < number_components; ++i) {
00525     C[i] = A[i] - B[i];
00526   }
00527 
00528   return;
00529 }
00530 
00531 //
00532 // Base minus
00533 //
00534 template<typename T, typename ST>
00535 void
00536 minus(TensorBase<T, ST> const & A, TensorBase<T, ST> & B)
00537 {
00538   Index const
00539   number_components = A.get_number_components();
00540 
00541   assert(B.get_number_components() == number_components);
00542 
00543   for (Index i = 0; i < number_components; ++i) {
00544     B[i] = - A[i];
00545   }
00546 
00547   return;
00548 }
00549 
00550 //
00551 // Base equality
00552 //
00553 template<typename T, typename ST>
00554 bool
00555 equal(TensorBase<T, ST> const & A, TensorBase<T, ST> const & B)
00556 {
00557   Index const
00558   number_components = A.get_number_components();
00559 
00560   assert(B.get_number_components() == number_components);
00561 
00562   for (Index i = 0; i < number_components; ++i) {
00563     if (A[i] != B[i]) return false;
00564   }
00565 
00566   return true;
00567 }
00568 
00569 //
00570 // Base not equality
00571 //
00572 template<typename T, typename ST>
00573 bool
00574 not_equal(TensorBase<T, ST> const & A, TensorBase<T, ST> const & B)
00575 {
00576   return !(equal(A, B));
00577 }
00578 
00579 //
00580 // Base scaling
00581 //
00582 template<typename R, typename S, typename T, typename SR, typename ST>
00583 void
00584 scale(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
00585 {
00586   Index const
00587   number_components = A.get_number_components();
00588 
00589   assert(B.get_number_components() == number_components);
00590 
00591   for (Index i = 0; i < number_components; ++i) {
00592     B[i] = s * A[i];
00593   }
00594 
00595   return;
00596 }
00597 
00598 //
00599 // Base division
00600 //
00601 template<typename R, typename S, typename T, typename SR, typename ST>
00602 void
00603 divide(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
00604 {
00605   Index const
00606   number_components = A.get_number_components();
00607 
00608   assert(B.get_number_components() == number_components);
00609 
00610   for (Index i = 0; i < number_components; ++i) {
00611     B[i] = A[i] / s;
00612   }
00613 
00614   return;
00615 }
00616 
00617 //
00618 // Base split (scalar divided by tensor)
00619 //
00620 template<typename R, typename S, typename T, typename SR, typename ST>
00621 void
00622 split(TensorBase<R, SR> const & A, S const & s, TensorBase<T, ST> & B)
00623 {
00624   Index const
00625   number_components = A.get_number_components();
00626 
00627   assert(B.get_number_components() == number_components);
00628 
00629   for (Index i = 0; i < number_components; ++i) {
00630     B[i] = s / A[i];
00631   }
00632 
00633   return;
00634 }
00635 
00636 } // namespace Intrepid
00637 
00638 #endif // Intrepid_MiniTensor_TensorBase_i_h