|
Intrepid
|
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
1.7.6.1