1 /*  _______________________________________________________________________
2 
3     PECOS: Parallel Environment for Creation Of Stochastics
4     Copyright (c) 2011, Sandia National Laboratories.
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Pecos directory.
7     _______________________________________________________________________ */
8 
9 #ifndef PECOS_DATA_TYPES_H
10 #define PECOS_DATA_TYPES_H
11 
12 #if defined(HAVE_CONFIG_H) && !defined(DISABLE_DAKOTA_CONFIG_H)
13   // HAVE_CONFIG_H is STILL set in Dakota/src (EVEN IN THE CMAKE BUILD!) so
14   // use a "disable config header" conditional to help manage the transition
15   #include "pecos_config.h"
16 #endif // HAVE_CONFIG_H
17 
18 #include "pecos_global_defs.hpp"
19 
20 #include "Teuchos_SerialDenseVector.hpp"
21 #include "Teuchos_SerialDenseSolver.hpp"
22 #include "Teuchos_SerialSpdDenseSolver.hpp"
23 
24 #include "boost/multi_array.hpp"
25 #include "boost/dynamic_bitset.hpp"
26 
27 #include <algorithm>  // for std::find
28 #include <complex>
29 #include <list>
30 #include <map>
31 #include <set>
32 #include <string>
33 #include <vector>
34 #include <deque>
35 
36 
37 namespace Pecos {
38 
39 // avoid problems with circular dependencies by using fwd declarations
40 //class BasisFunction;
41 class SurrogateDataVars;
42 class SurrogateDataResp;
43 
44 // -----------------------------------
45 // Aliases for fundamental data types:
46 // -----------------------------------
47 typedef double Real;
48 
49 // --------
50 // Strings:
51 // --------
52 typedef std::string String;
53 
54 
55 // --------------------------------
56 // Numerical arrays (serial dense):
57 // --------------------------------
58 typedef Teuchos::SerialDenseVector<int, Real>                RealVector;
59 typedef Teuchos::SerialDenseVector<int, int>                 IntVector;
60 typedef Teuchos::SerialDenseVector<int, std::complex<Real> > ComplexVector;
61 typedef Teuchos::SerialDenseMatrix<int, Real>                RealMatrix;
62 typedef Teuchos::SerialDenseMatrix<int, int>                 IntMatrix;
63 typedef Teuchos::SerialSymDenseMatrix<int, Real>             RealSymMatrix;
64 
65 
66 // ---------------------------------
67 // Numerical solvers (serial dense):
68 // ---------------------------------
69 typedef Teuchos::SerialDenseSolver<int, Real>    RealSolver;
70 typedef Teuchos::SerialSpdDenseSolver<int, Real> RealSpdSolver;
71 
72 
73 // ---------------------------------------
74 // Admin/bookkeeping arrays (serial only):
75 // ---------------------------------------
76 typedef boost::dynamic_bitset<unsigned long> BitArray;
77 
78 typedef std::pair<unsigned short, unsigned short> UShortUShortPair;
79 typedef std::pair<int, int>                       IntIntPair;
80 typedef std::pair<Real, Real>                     RealRealPair;
81 typedef std::pair<Real, RealVector>               RealRealVectorPair;
82 
83 typedef std::list<unsigned short>    UShortList;
84 typedef std::list<size_t>            SizetList;
85 
86 typedef std::vector<Real>              RealArray;
87 typedef std::vector<RealArray>         Real2DArray;
88 typedef std::vector<Real2DArray>       Real3DArray;
89 typedef std::vector<int>               IntArray;
90 typedef std::vector<IntArray>          Int2DArray;
91 typedef std::vector<short>             ShortArray;
92 typedef std::vector<unsigned short>    UShortArray;
93 typedef std::vector<unsigned long>     ULongArray;
94 typedef std::vector<UShortArray>       UShort2DArray;
95 typedef std::vector<UShort2DArray>     UShort3DArray;
96 typedef std::vector<UShort3DArray>     UShort4DArray;
97 typedef std::vector<UShort4DArray>     UShort5DArray;
98 typedef std::deque<UShortArray>        UShortArrayDeque;
99 typedef std::deque<UShort2DArray>      UShort2DArrayDeque;
100 typedef std::vector<UShortArrayDeque>  UShortArrayDequeArray;
101 typedef std::vector<size_t>            SizetArray;
102 typedef std::vector<SizetArray>        Sizet2DArray;
103 typedef std::vector<Sizet2DArray>      Sizet3DArray;
104 typedef std::vector<std::complex<Real> > ComplexArray;
105 typedef std::vector<RealRealPair>      RealRealPairArray;
106 typedef std::vector<String>            StringArray;
107 typedef std::vector<RealVector>        RealVectorArray;
108 typedef std::vector<RealVectorArray>   RealVector2DArray;
109 typedef std::vector<RealVector2DArray> RealVector3DArray;
110 typedef std::vector<IntVector>         IntVectorArray;
111 typedef std::vector<RealMatrix>        RealMatrixArray;
112 typedef std::vector<RealMatrixArray>   RealMatrix2DArray;
113 typedef std::vector<RealMatrix2DArray> RealMatrix3DArray;
114 typedef std::vector<RealSymMatrix>     RealSymMatrixArray;
115 typedef std::deque<RealVector>         RealVectorDeque;
116 typedef std::deque<RealMatrix>         RealMatrixDeque;
117 typedef std::vector<RealVectorDeque>   RealVectorDequeArray;
118 typedef std::vector<RealMatrixDeque>   RealMatrixDequeArray;
119 
120 //typedef std::vector<BasisFunction>  BasisFunctionArray;
121 typedef std::vector<SurrogateDataVars> SDVArray;
122 typedef std::vector<SurrogateDataResp> SDRArray;
123 typedef std::deque<SDVArray>           SDVArrayDeque;
124 typedef std::deque<SDRArray>           SDRArrayDeque;
125 
126 typedef std::set<size_t>                  SizetSet;
127 typedef std::set<int>                     IntSet;
128 typedef std::set<String>                  StringSet;
129 typedef std::set<Real>                    RealSet;
130 typedef std::set<BitArray>                BitArraySet;
131 typedef std::set<UShortArray>             UShortArraySet;
132 typedef std::multiset<unsigned short>     UShortMultiSet;
133 typedef std::multiset<UShortMultiSet>     UShort2DMultiSet;
134 typedef std::vector<IntSet>               IntSetArray;
135 typedef std::vector<StringSet>            StringSetArray;
136 typedef std::vector<RealSet>              RealSetArray;
137 typedef std::map<int, short>              IntShortMap;
138 typedef std::map<size_t, short>           SizetShortMap;
139 typedef std::map<BitArray, unsigned long> BitArrayULongMap;
140 typedef std::map<unsigned long, unsigned long> ULongULongMap;
141 typedef std::map<int, int>                IntIntMap;
142 typedef std::map<int, Real>               IntRealMap;
143 typedef std::map<String, Real>            StringRealMap;
144 typedef std::map<Real, Real>              RealRealMap;
145 typedef std::map<RealRealPair, Real>      RealRealPairRealMap;
146 typedef std::map<IntIntPair, Real>        IntIntPairRealMap;
147 typedef std::vector<SizetSet>             SizetSetArray;
148 typedef std::deque<size_t>                SizetDeque;
149 typedef std::deque<SizetArray>            SizetArrayDeque;
150 typedef std::deque<SizetSet>              SizetSetDeque;
151 typedef std::vector<UShortArraySet>       UShortArraySetArray;
152 typedef std::vector<IntRealMap>           IntRealMapArray;
153 typedef std::vector<StringRealMap>        StringRealMapArray;
154 typedef std::vector<RealRealMap>          RealRealMapArray;
155 typedef std::vector<RealRealPairRealMap>  RealRealPairRealMapArray;
156 typedef std::vector<IntIntPairRealMap>    IntIntPairRealMapArray;
157 typedef std::map<unsigned short, RealArray> UShortRealArrayMap;
158 typedef std::map<int, RealVector>         IntRealVectorMap;
159 typedef std::map<UShortMultiSet,   Real>  UShortMultiSetRealMap;
160 typedef std::map<UShort2DMultiSet, Real>  UShort2DMultiSetRealMap;
161 
162 typedef boost::multi_array_types::index_range      idx_range;
163 typedef boost::multi_array<size_t, 1>              SizetMultiArray;
164 typedef SizetMultiArray::array_view<1>::type       SizetMultiArrayView;
165 typedef SizetMultiArray::const_array_view<1>::type SizetMultiArrayConstView;
166 
167 // ---------
168 // Iterators
169 // ---------
170 typedef IntSet::iterator                    ISIter;
171 typedef IntSet::const_iterator              ISCIter;
172 typedef SizetSet::iterator                  StSIter;
173 typedef SizetSet::const_iterator            StSCIter;
174 typedef BitArraySet::iterator               BASIter;
175 typedef BitArraySet::const_iterator         BASCIter;
176 typedef RealSet::iterator                   RSIter;
177 typedef RealSet::const_iterator             RSCIter;
178 typedef IntShortMap::iterator               IShMIter;
179 typedef IntShortMap::const_iterator         IShMCIter;
180 typedef SizetShortMap::iterator             StShMIter;
181 typedef SizetShortMap::const_iterator       StShMCIter;
182 typedef IntIntMap::iterator                 IIMIter;
183 typedef IntIntMap::const_iterator           IIMCIter;
184 typedef BitArrayULongMap::iterator          BAULMIter;
185 typedef BitArrayULongMap::const_iterator    BAULMCIter;
186 typedef ULongULongMap::iterator             ULULMIter;
187 typedef ULongULongMap::const_iterator       ULULMCIter;
188 typedef IntRealMap::iterator                IRMIter;
189 typedef IntRealMap::const_iterator          IRMCIter;
190 typedef StringRealMap::iterator             SRMIter;
191 typedef StringRealMap::const_iterator       SRMCIter;
192 typedef RealRealMap::iterator               RRMIter;
193 typedef RealRealMap::const_iterator         RRMCIter;
194 typedef IntIntPairRealMap::iterator         IIPRMIter;
195 typedef IntIntPairRealMap::const_iterator   IIPRMCIter;
196 typedef RealRealPairRealMap::iterator       RRPRMIter;
197 typedef RealRealPairRealMap::const_iterator RRPRMCIter;
198 
199 
200 template <typename PecosContainerType>
find_index(const PecosContainerType & c,const typename PecosContainerType::value_type & val)201 inline size_t find_index(const PecosContainerType& c,
202 			 const typename PecosContainerType::value_type& val)
203 {
204   // For a default container, employ one traversal
205 
206   typename PecosContainerType::const_iterator cit;
207   size_t cntr; // force size_t to ensure that _NPOS is valid
208   for (cit=c.begin(), cntr=0; cit!=c.end(); ++cit, ++cntr)
209     if (*cit == val)
210       return cntr;
211   return _NPOS;
212 }
213 
214 
215 template <typename ScalarType>
find_min(const std::vector<ScalarType> & vec)216 inline ScalarType find_min(const std::vector<ScalarType>& vec)
217 {
218   size_t i, len = vec.size();
219   ScalarType min = (len) ? vec[0] : std::numeric_limits<ScalarType>::max();
220   for (i=1; i<len; ++i)
221     if (vec[i] < min)
222       min = vec[i];
223   return min;
224 }
225 
226 
227 template <typename ScalarType>
find_max(const std::vector<ScalarType> & vec)228 inline ScalarType find_max(const std::vector<ScalarType>& vec)
229 {
230   size_t i, len = vec.size();
231   ScalarType max = (len) ? vec[0] : std::numeric_limits<ScalarType>::min();
232   for (i=1; i<len; ++i)
233     if (vec[i] > max)
234       max = vec[i];
235   return max;
236 }
237 
238 
239 template <typename ValueType>
set_value_to_index(const std::set<ValueType> & s,const ValueType & val)240 inline size_t set_value_to_index(const std::set<ValueType>& s,
241 				 const ValueType& val)
242 {
243   // For a sorted container, use fast lookup + distance()
244 
245   typename std::set<ValueType>::const_iterator cit = s.find(val);
246   return (cit == s.end()) ? _NPOS : std::distance(s.begin(), cit);
247 }
248 
249 
250 template <typename KeyType, typename ValueType>
map_key_to_index(const std::map<KeyType,ValueType> & m,const KeyType & key)251 inline size_t map_key_to_index(const std::map<KeyType, ValueType>& m,
252 			       const KeyType& key)
253 {
254   // For a sorted container, use fast lookup + distance()
255 
256   typename std::map<KeyType, ValueType>::const_iterator cit = m.find(key);
257   return (cit == m.end()) ? _NPOS : std::distance(m.begin(), cit);
258 }
259 
260 
261 /// compare two Real values using DBL_EPSILON relative tolerance:
262 /// return true if same, false if different
real_compare(Real r1,Real r2)263 inline bool real_compare(Real r1, Real r2)
264 {
265   if (r1 == r2) // a higher bar than we want, but check before relative test
266     return true;
267   else if (r2 >= DBL_MAX || r2 <= -DBL_MAX) // +/-DBL_MAX or +/-dbl_inf
268     return (r1 == r2);                      // assume outside tol if not equal
269   else if  (std::abs(r2) <= DBL_MIN)        // +/-0 (see IEEE 754)
270     return (std::abs(r1) <= DBL_MIN);       // assume within tol if not equal
271   else
272     return (std::abs(1. - r1/r2) <= DBL_EPSILON); // relative
273 }
274 
275 
276 /// compute 1-norm |i| (sum of indices) for the given index_set
277 template <typename OrdinalType>
l1_norm(const std::vector<OrdinalType> & index_set)278 inline size_t l1_norm(const std::vector<OrdinalType>& index_set)
279 {
280   // hardwire to size_t instead of OrdinalType since could be a large sum
281   // of smaller types
282   size_t i, norm = 0, len = index_set.size();
283   // assume unsigned types since std::abs(index_set[i]) will not compile
284   // for unsigned types on some platforms
285   for (i=0; i<len; ++i)
286     norm += index_set[i];//std::abs(index_set[i]);
287   return norm;
288 }
289 
290 
291 /// inflate a scalar specification into a homogeneous vector
292 template <typename OrdinalType, typename ScalarType>
inflate_scalar(std::vector<ScalarType> & v,OrdinalType num_v)293 void inflate_scalar(std::vector<ScalarType>& v, OrdinalType num_v)
294 {
295   OrdinalType v_len = v.size();
296   if (v_len != num_v) {
297     if (v_len == 1) {
298       ScalarType v0 = v[0];
299       v.assign(num_v, v0);
300     }
301     else {
302       PCerr << "Error: specification length (" << v_len
303 	    << ") does not match target length (" << num_v
304 	    << ") in Pecos::inflate_scalar()." << std::endl;
305       abort_handler(-1);
306     }
307   }
308 }
309 
310 
311 /// For T=SerialDense{Vector,Matrix} and ContainerT=std::{vector,deque}<T>
312 template <typename ContainerT1, typename ContainerT2>
push_back_to_back(ContainerT1 & array1,ContainerT2 & array2)313 inline void push_back_to_back(ContainerT1& array1, ContainerT2& array2)
314 {
315   typename ContainerT1::iterator p1_it = --array1.end();
316   // avoid deep copy of potentially large Real{Vector,Matrix}
317   // push_back empty instance and update in place
318   array2.push_back(typename ContainerT2::value_type()); // push empty
319   array2.back().swap(*p1_it); // shallow copy
320   array1.erase(p1_it);
321 }
322 
323 
324 /// For T=SerialDense{Vector,Matrix} and ContainerT=std::{vector,deque}<T>
325 template <typename ContainerT1, typename OrdinalType, typename ContainerT2>
push_index_to_back(ContainerT1 & array1,OrdinalType p1_index,ContainerT2 & array2)326 inline void push_index_to_back(ContainerT1& array1, OrdinalType p1_index,
327 			       ContainerT2& array2)
328 {
329   typename ContainerT1::iterator p1_it = array1.begin() + p1_index;
330   // avoid deep copy of potentially large Real{Vector,Matrix}
331   // push_back empty instance and update in place
332   array2.push_back(typename ContainerT2::value_type());
333   array2.back().swap(*p1_it); // shallow copy
334   array1.erase(p1_it);
335 }
336 
337 
338 /// For T=SerialDense{Vector,Matrix} and ContainerT=std::{vector,deque}<T>
339 template <typename ContainerT1, typename OrdinalType, typename ContainerT2>
push_range_to_back(ContainerT1 & array1,OrdinalType p1_index,ContainerT2 & array2)340 inline void push_range_to_back(ContainerT1& array1, OrdinalType p1_index,
341 			       ContainerT2& array2)
342 {
343   // avoid deep copies of potentially large Real{Vector,Matrix} instances
344   size_t i1, i2, len1 = array1.size(), len2 = array2.size(),
345     new_len2 = len2 + len1 - p1_index;
346   array2.resize(new_len2); // populates end with empty instances
347   for (i1=p1_index, i2=len2; i1<len1; ++i1, ++i2)
348     array2[i2].swap(array1[i1]);
349   array1.resize(p1_index);
350 }
351 
352 
353 /// equality operator for SizetArray and SizetMultiArrayConstView
operator ==(const SizetArray & sa,SizetMultiArrayConstView smav)354 inline bool operator==(const SizetArray& sa, SizetMultiArrayConstView smav)
355 {
356   // Check for equality in array lengths
357   size_t i, len = sa.size();
358   if ( smav.size() != len )
359     return false;
360 
361   // Check each size_t
362   for (i=0; i<len; i++)
363     if ( smav[i] != sa[i] )
364       return false;
365 
366   return true;
367 }
368 
369 
370 /// equality operator for vector compared to vector (non-Real types)
371 template <typename OrdinalType, typename ScalarType>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v1,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v2)372 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v1,
373 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v2)
374 {
375   // Check for equality in array lengths
376   OrdinalType i, len = v1.length();
377   if (v2.length() != len)
378     return false;
379 
380   // Check each key,value pair
381   for (i=0; i<len; ++i)
382     if (v1[i] != v2[i])
383       return false;
384 
385   return true;
386 }
387 
388 
389 /// specialization of equality operator for RealVector compared to RealVector
390 template <typename OrdinalType>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,Real> & v1,const Teuchos::SerialDenseVector<OrdinalType,Real> & v2)391 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, Real>& v1,
392 		const Teuchos::SerialDenseVector<OrdinalType, Real>& v2)
393 {
394   // Check for equality in array lengths
395   OrdinalType i, len = v1.length();
396   if (v2.length() != len)
397     return false;
398 
399   // Check each key,value pair
400   for (i=0; i<len; ++i)
401     if (!real_compare(v1[i], v2[i]))
402       return false;
403 
404   return true;
405 }
406 
407 
408 /// equality operator for set compared to vector
409 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,const std::set<ScalarType1> & s)410 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
411 		const std::set<ScalarType1>& s)
412 {
413   // Check for equality in array lengths
414   if ( s.size() != v.length() )
415     return false;
416 
417   // Check each key,value pair
418   typename std::set<ScalarType1>::const_iterator cit;  OrdinalType cntr;
419   for (cit=s.begin(), cntr=0; cit!=s.end(); ++cit, ++cntr)
420     if (v[cntr] != (ScalarType2)(*cit))
421       return false;
422 
423   return true;
424 }
425 
426 
427 /// specialization of equality operator for StringSet compared to vector
428 template <typename OrdinalType, typename ScalarType2>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,const std::set<String> & s)429 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
430 		const std::set<String>& s)
431 {
432   // Check for equality in array lengths
433   size_t s_len = s.size();
434   if ( s_len != v.length() )
435     return false;
436 
437   // Check each key,value pair
438   for (OrdinalType cntr=0; cntr<s_len; ++cntr)
439     if (v[cntr] != (ScalarType2)cntr)
440       return false;
441 
442   return true;
443 }
444 
445 
446 /// equality operator for unrolled map compared to vector
447 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,const std::map<ScalarType1,ScalarType2> & m)448 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
449 		const std::map<ScalarType1, ScalarType2>& m)
450 {
451   // Check for equality in array lengths
452   if ( m.size() * 2 != v.length() )
453     return false;
454 
455   // Check each key,value pair
456   typename std::map<ScalarType1, ScalarType2>::const_iterator cit;
457   OrdinalType cntr;
458   for (cit=m.begin(), cntr=0; cit!=m.end(); ++cit) {
459     if (v[cntr] != (ScalarType2)cit->first)  return false; ++cntr;
460     if (v[cntr] !=              cit->second) return false; ++cntr;
461   }
462 
463   return true;
464 }
465 
466 
467 /// specialization of equality operator for StringRealMap compared to vector
468 template <typename OrdinalType, typename ScalarType2>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,const std::map<String,ScalarType2> & m)469 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
470 		const std::map<String, ScalarType2>& m)
471 {
472   // Check for equality in array lengths
473   if ( m.size() * 2 != v.length() )
474     return false;
475 
476   // Check each key,value pair
477   typename std::map<String, ScalarType2>::const_iterator cit;
478   OrdinalType cntr;
479   for (cit=m.begin(), cntr=0; cit!=m.end(); ++cit) {
480     if (v[cntr] != (ScalarType2)cntr)  return false;  ++cntr;
481     if (v[cntr] !=       cit->second)  return false;  ++cntr;
482   }
483 
484   return true;
485 }
486 
487 
488 /// equality operator for unrolled map compared to vector
489 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
equivalent(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,const std::map<std::pair<ScalarType1,ScalarType1>,ScalarType2> & m)490 bool equivalent(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
491 		const std::map<std::pair<ScalarType1, ScalarType1>,
492 		               ScalarType2>& m)
493 {
494   // Check for equality in array lengths
495   if ( m.size() * 3 != v.length() )
496     return false;
497 
498   // Check each key,value pair
499   typename std::map<std::pair<ScalarType1, ScalarType1>, ScalarType2>::
500     const_iterator cit;
501   OrdinalType cntr = 0;
502   for (cit=m.begin(); cit!=m.end(); ++cit) {
503     const std::pair<ScalarType1, ScalarType1>& pr = cit->first;
504     if (v[cntr] != (ScalarType2)pr.first)   return false;  ++cntr;
505     if (v[cntr] != (ScalarType2)pr.second)  return false;  ++cntr;
506     if (v[cntr] !=            cit->second)  return false;  ++cntr;
507   }
508 
509   return true;
510 }
511 
512 
513 /// copy Teuchos::SerialDenseVector<OrdinalType, ScalarType> to
514 /// std::vector<ScalarType>
515 template <typename OrdinalType, typename ScalarType>
copy_data(const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv,std::vector<ScalarType> & v)516 void copy_data(const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv,
517 	       std::vector<ScalarType>& v)
518 {
519   OrdinalType size_sdv = sdv.length();
520   if (size_sdv != v.size())
521     v.resize(size_sdv);
522   for (OrdinalType i=0; i<size_sdv; ++i)
523     v[i] = sdv[i];
524 }
525 
526 
527 /// copy std::vector<ScalarType> to
528 /// Teuchos::SerialDenseVector<OrdinalType, ScalarType>
529 template <typename OrdinalType, typename ScalarType>
copy_data(const std::vector<ScalarType> & v,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv)530 void copy_data(const std::vector<ScalarType>& v,
531 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv)
532 {
533   size_t size_v = v.size();
534   if (sdv.length() != size_v)
535     sdv.sizeUninitialized(size_v);
536   for (OrdinalType i=0; i<size_v; ++i)
537     sdv[i] = v[i];
538 }
539 
540 
541 /// copy Teuchos::SerialDenseVector<OrdinalType, ScalarType> to same
542 /// (used in place of operator= when a deep copy is required regardless
543 /// of Teuchos DataAccess mode)
544 template <typename OrdinalType, typename ScalarType>
copy_data(const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv1,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv2)545 void copy_data(const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv1,
546 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv2)
547 {
548   OrdinalType size_sdv1 = sdv1.length();
549   if (size_sdv1 != sdv2.length())
550     sdv2.sizeUninitialized(size_sdv1);
551   for (OrdinalType i=0; i<size_sdv1; ++i)
552     sdv2[i] = sdv1[i];
553 }
554 
555 
556 /// copy Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType> to same
557 /// (used in place of operator= when a deep copy is required regardless
558 /// of Teuchos DataAccess mode)
559 template <typename OrdinalType, typename ScalarType>
copy_data(const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & ssdm1,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & ssdm2)560 void copy_data(const
561 	       Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& ssdm1,
562 	       Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& ssdm2)
563 {
564   OrdinalType size_ssdm1 = ssdm1.numRows();
565   if (size_ssdm1 != ssdm2.numRows())
566     ssdm2.shapeUninitialized(size_ssdm1);
567   ssdm2.assign(ssdm1); // copies values
568 }
569 
570 
571 /// copy Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType> to same
572 /// (used in place of operator= when a deep copy is required regardless
573 /// of Teuchos DataAccess mode)
574 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType1> & sdm1,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType2> & sdm2)575 void copy_data(const
576 	       Teuchos::SerialDenseMatrix<OrdinalType, ScalarType1>& sdm1,
577 	       Teuchos::SerialDenseMatrix<OrdinalType, ScalarType2>& sdm2)
578 {
579   OrdinalType r, c, nr_sdm1 = sdm1.numRows(), nc_sdm1 = sdm1.numCols();
580   if (nr_sdm1 != sdm2.numRows() || nc_sdm1 != sdm2.numCols())
581     sdm2.shapeUninitialized(nr_sdm1, nc_sdm1);
582   for (r=0; r<nr_sdm1; ++r)
583     for (c=0; c<nc_sdm1; ++c)
584       sdm2(r,c) = static_cast<ScalarType2>(sdm1(r,c));
585 }
586 
587 
588 /// copy ScalarType* to ScalarType*
589 template <typename OrdinalType, typename ScalarType>
copy_data(const ScalarType * ptr1,const OrdinalType ptr_len,ScalarType * ptr2)590 void copy_data(const ScalarType* ptr1, const OrdinalType ptr_len,
591 	       ScalarType* ptr2)
592 {
593   for (OrdinalType i=0; i<ptr_len; ++i)
594     ptr2[i] = ptr1[i];
595 }
596 
597 
598 /// copy ScalarType* to Teuchos::SerialDenseVector<OrdinalType, ScalarType>
599 template <typename OrdinalType, typename ScalarType>
copy_data(const ScalarType * ptr,const OrdinalType ptr_len,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv)600 void copy_data(const ScalarType* ptr, const OrdinalType ptr_len,
601 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv)
602 {
603   if (sdv.length() != ptr_len)
604     sdv.sizeUninitialized(ptr_len);
605   for (OrdinalType i=0; i<ptr_len; ++i)
606     sdv[i] = ptr[i];
607 }
608 
609 
610 /// copy Array<T> to T*
611 template <typename T>
copy_data(const std::vector<T> & vec,T * ptr,const size_t ptr_len)612 void copy_data(const std::vector<T>& vec, T* ptr, const size_t ptr_len)
613 {
614   if (ptr_len != vec.size()) { // could use <, but enforce exact match
615     PCerr << "Error: bad ptr_len in copy_data(std::vector<T>, T* ptr)."
616 	  << std::endl;
617     abort_handler(-1);
618   }
619   for (size_t i=0; i<ptr_len; ++i)
620     ptr[i] = vec[i];
621 }
622 
623 
624 /// copy T* to Array<T>
625 template <typename T>
copy_data(const T * ptr,const size_t ptr_len,std::vector<T> & vec)626 void copy_data(const T* ptr, const size_t ptr_len, std::vector<T>& vec)
627 {
628   if (ptr_len != vec.size())
629     vec.resize(ptr_len);
630   for (size_t i=0; i<ptr_len; ++i)
631     vec[i] = ptr[i];
632 }
633 
634 
635 /// copy ScalarType1* to Array<ScalarType2> with data cast
636 template <typename ScalarType1, typename ScalarType2>
copy_data(const ScalarType1 * ptr,const size_t ptr_len,std::vector<ScalarType2> & vec)637 void copy_data(const ScalarType1* ptr, const size_t ptr_len,
638 	       std::vector<ScalarType2>& vec)
639 {
640   if (ptr_len != vec.size())
641     vec.resize(ptr_len);
642   for (size_t i=0; i<ptr_len; ++i)
643     vec[i] = static_cast<ScalarType2>(ptr[i]);
644 }
645 
646 
647 /// copy ScalarType* to BitArray
648 template <typename OrdinalType, typename ScalarType>
copy_data(const ScalarType * ptr,const OrdinalType ptr_len,BitArray & ba)649 void copy_data(const ScalarType* ptr, const OrdinalType ptr_len,
650 	       BitArray& ba)
651 {
652   if (ba.size() != ptr_len)
653     ba.resize(ptr_len);
654   for (OrdinalType i=0; i<ptr_len; ++i)
655     ba[i] = (ptr[i]) ? true : false;
656 }
657 
658 
659 /// copy BitArray to ScalarType*
660 template <typename OrdinalType> //, typename ScalarType>
copy_data(const BitArray & ba,bool * ptr,const OrdinalType ptr_len)661 void copy_data(const BitArray& ba, bool* ptr, //ScalarType* ptr,
662 	       const OrdinalType ptr_len)
663 {
664   for (OrdinalType i=0; i<ptr_len; ++i)
665     ptr[i] = ba[i]; // or static_cast<ScalarType>(ba[i])
666 }
667 
668 
669 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const std::set<ScalarType1> & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v)670 void copy_data(const std::set<ScalarType1>& s,
671 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v)
672 {
673   // convert map[x] = y to vector of concatenated (x,y) pairs
674   v.sizeUninitialized(s.size());
675   typename std::set<ScalarType1>::const_iterator cit;  OrdinalType cntr;
676   for (cit=s.begin(), cntr=0; cit!=s.end(); ++cit, ++cntr)
677     v[cntr] = (ScalarType2)(*cit);
678 }
679 
680 
681 // specialization for StringSet using set indices
682 template <typename OrdinalType, typename ScalarType2>
copy_data(const std::set<String> & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v)683 void copy_data(const std::set<String>& s,
684 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v)
685 {
686   // convert map[x] = y to vector of concatenated (x,y) pairs
687   OrdinalType cntr, s_len = s.size();
688   v.sizeUninitialized(s_len);
689   for (cntr=0; cntr<s_len; ++cntr)
690     v[cntr] = (ScalarType2)cntr;
691 }
692 
693 
694 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,std::map<ScalarType1,ScalarType2> & m)695 void copy_data(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
696 	       std::map<ScalarType1, ScalarType2>& m)
697 {
698   OrdinalType v_len = v.length();
699   if (v_len % 2) {
700     PCerr << "Error: vector length (" << v_len << ") must be multiple of 2 in "
701 	  << "Pecos::copy_data(Teuchos::SerialDenseVector, std::map)."
702 	  << std::endl;
703     abort_handler(-1);
704   }
705   // convert vector of concatenated (x,y) pairs to map[x] = y
706   OrdinalType i, j, m_len = v_len / 2;
707   m.clear();
708   for (i=0; i<m_len; ++i) {
709     j = 2*i;
710     ScalarType1 vj = (ScalarType1)v[j];
711     m[vj] = v[j+1];
712   }
713 }
714 
715 
716 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const std::map<ScalarType1,ScalarType2> & m,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v)717 void copy_data(const std::map<ScalarType1, ScalarType2>& m,
718 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v)
719 {
720   // convert map[x] = y to vector of concatenated (x,y) pairs
721   v.sizeUninitialized(m.size() * 2);
722   typename std::map<ScalarType1, ScalarType2>::const_iterator cit;
723   OrdinalType cntr = 0;
724   for (cit=m.begin(); cit!=m.end(); ++cit) {
725     v[cntr] = (ScalarType2)cit->first;  ++cntr;
726     v[cntr] =              cit->second; ++cntr;
727   }
728 }
729 
730 
731 /// specialization for StringScalarTypeMap: store index of string value
732 template <typename OrdinalType, typename ScalarType2>
copy_data(const std::map<String,ScalarType2> & m,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v)733 void copy_data(const std::map<String, ScalarType2>& m,
734 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v)
735 {
736   // convert map[x] = y to vector of concatenated (x,y) pairs
737   v.sizeUninitialized(m.size() * 2);
738   typename std::map<String, ScalarType2>::const_iterator cit;
739   size_t str_index = 0;  OrdinalType cntr = 0;
740   for (cit=m.begin(); cit!=m.end(); ++cit) {
741     v[cntr] = (ScalarType2)str_index;  ++cntr;  ++str_index;
742     v[cntr] =            cit->second;  ++cntr;
743   }
744 }
745 
746 
747 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const std::map<std::pair<ScalarType1,ScalarType1>,ScalarType2> & m,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v)748 void copy_data(const std::map<std::pair<ScalarType1, ScalarType1>,
749 	                      ScalarType2>& m,
750 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v)
751 {
752   // convert map[x] = y to vector of concatenated (x,y) pairs
753   v.sizeUninitialized(m.size() * 3);
754   typename std::map<std::pair<ScalarType1, ScalarType1>, ScalarType2>::
755     const_iterator cit;
756   OrdinalType cntr = 0;
757   for (cit=m.begin(); cit!=m.end(); ++cit) {
758     const std::pair<ScalarType1, ScalarType1>& pr = cit->first;
759     v[cntr] = (ScalarType2)pr.first;   ++cntr;
760     v[cntr] = (ScalarType2)pr.second;  ++cntr;
761     v[cntr] =            cit->second;  ++cntr;
762   }
763 }
764 
765 
766 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
copy_data(const Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & v,std::map<std::pair<ScalarType1,ScalarType1>,ScalarType2> & m)767 void copy_data(const Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& v,
768 	       std::map<std::pair<ScalarType1, ScalarType1>, ScalarType2>& m)
769 {
770   OrdinalType v_len = v.length();
771   if (v_len % 3) {
772     PCerr << "Error: vector length (" << v_len << ") must be multiple of 3 in "
773 	  << "Pecos::copy_data(Teuchos::SerialDenseVector, std::map<std::pair, "
774 	  << "T>)." << std::endl;
775     abort_handler(-1);
776   }
777   // convert vector of concatenated (xl,xu,y) triplets to map[xl,xu] = y
778   OrdinalType i, j, m_len = v_len / 3;
779   m.clear();
780   std::pair<ScalarType1, ScalarType1> pr;
781   for (i=0; i<m_len; ++i) {
782     j = 3*i;
783     pr.first  = (ScalarType1)v[j];
784     pr.second = (ScalarType1)v[j+1];
785     m[pr]     = v[j+2];
786   }
787 }
788 
789 
790 /// cast Teuchos::SerialDenseVector from one ScalarType to another
791 template <typename OrdinalType, typename ScalarType1, typename ScalarType2>
cast_data(const Teuchos::SerialDenseVector<OrdinalType,ScalarType1> & sdv1,Teuchos::SerialDenseVector<OrdinalType,ScalarType2> & sdv2)792 void cast_data(const Teuchos::SerialDenseVector<OrdinalType, ScalarType1>& sdv1,
793 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType2>& sdv2)
794 {
795   OrdinalType i, size_sdv1 = sdv1.length();
796   if (size_sdv1 != sdv2.length())
797     sdv2.sizeUninitialized(size_sdv1);
798   for (i=0; i<size_sdv1; ++i)
799     sdv2[i] = (ScalarType2)sdv1[i];
800 }
801 
802 
803 /// cast std::vector from one ScalarType to another
804 template <typename ScalarType1, typename ScalarType2>
cast_data(const std::vector<ScalarType1> & v1,std::vector<ScalarType2> & v2)805 void cast_data(const std::vector<ScalarType1>& v1, std::vector<ScalarType2>& v2)
806 {
807   size_t i, size_v1 = v1.size();
808   if (size_v1 != v2.size())
809     v2.resize(size_v1);
810   for (i=0; i<size_v1; ++i)
811     v2[i] = (ScalarType2)v1[i];
812 }
813 
814 
815 /// copy Teuchos::SerialDenseVector<OrdinalType, ScalarType> to
816 /// ith row of Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>
817 template <typename OrdinalType, typename ScalarType>
copy_row(const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm,OrdinalType row)818 void copy_row(const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv,
819 	      Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm,
820 	      OrdinalType row)
821 {
822   OrdinalType i, len = sdv.length();
823   //if (sdm.numCols() != len)
824   //  PCerr << std::endl;
825   for (i=0; i<len; ++i)
826     sdm(row, i) = sdv[i];
827 }
828 
829 
830 /// copy ith row of Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>
831 /// to Teuchos::SerialDenseVector<OrdinalType, ScalarType>
832 template <typename OrdinalType, typename ScalarType>
copy_row(const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm,OrdinalType row,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv)833 void copy_row(const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm,
834 	      OrdinalType row,
835 	      const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv)
836 {
837   OrdinalType i, len = sdm.numCols();
838   if (sdv.length() != len)
839     sdv.sizeUninitialized(len);
840   for (OrdinalType i=0; i<len; ++i)
841     sdv[i] = sdm(row, i);
842 }
843 
844 
845 /* Since no options to manage, implement directly in operator<<
846 
847 /// std::ostream write for Teuchos::SerialDenseVector
848 template <typename OrdinalType, typename ScalarType>
849 void write_data(std::ostream& s,
850 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v)
851 {
852   s << std::scientific << std::setprecision(WRITE_PRECISION);
853   OrdinalType len = v.length();
854   for (OrdinalType i=0; i<len; i++)
855     s << "                     " << std::setw(WRITE_PRECISION+7)
856       << v[i] << '\n';
857 }
858 */
859 
860 
861 /// formatted ostream insertion operator for SerialDenseMatrix
862 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & m,bool brackets=true,bool row_rtn=true,bool final_rtn=true)863 void write_data(std::ostream& s,
864                 const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& m,
865                 bool brackets = true, bool row_rtn = true,
866 		bool final_rtn = true)
867 {
868   OrdinalType i, j, nrows = m.numRows(), ncols = m.numCols();
869   s << std::scientific << std::setprecision(WRITE_PRECISION);
870   if (brackets)  s << "[[ ";
871   for (i=0; i<nrows; ++i) {
872     for (j=0; j<ncols; ++j)
873       s << std::setw(WRITE_PRECISION+7) << m(i,j) << ' ';
874     if (row_rtn && i!=m.numRows()-1)
875       s << "\n";
876   }
877   if (brackets)  s << "]] ";
878   if (final_rtn) s << '\n';
879 }
880 
881 
882 /// formatted ostream insertion operator for SerialSymDenseMatrix
883 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & m,bool brackets=true,bool row_rtn=true,bool final_rtn=true)884 void write_data(std::ostream& s,
885                 const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& m,
886                 bool brackets = true, bool row_rtn = true,
887 		bool final_rtn = true)
888 {
889   OrdinalType i, j, nrows = m.numRows();
890   s << std::scientific << std::setprecision(WRITE_PRECISION);
891   if (brackets)  s << "[[ ";
892   for (i=0; i<nrows; ++i) {
893     for (j=0; j<nrows; ++j)
894       s << std::setw(WRITE_PRECISION+7) << m(i,j) << ' ';
895     if (row_rtn && i!=m.numRows()-1)
896       s << "\n   ";
897   }
898   if (brackets)  s << "]] ";
899   if (final_rtn) s << '\n';
900 }
901 
902 
903 /// ostream insertion operator for a column vector from a SerialDenseMatrix
904 template <typename OrdinalType, typename ScalarType>
write_data_trans(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & sdv,bool brackets,bool row_rtn,bool final_rtn)905 void write_data_trans(std::ostream& s,
906   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& sdv,
907   bool brackets, bool row_rtn, bool final_rtn)
908 {
909   OrdinalType i, num_items = sdv.length();
910   s << std::scientific << std::setprecision(WRITE_PRECISION);
911   if (brackets) s << " [ ";
912   else          s << "   ";
913   for (i=0; i<num_items; ++i) {
914     s << std::setw(WRITE_PRECISION+7) << sdv[i] << ' ';
915     if (row_rtn && (i+1)%4 == 0)
916       s << "\n   "; // Output 4 gradient components per line
917   }
918   if (brackets)  s << "] ";
919   if (final_rtn) s << '\n';
920 }
921 
922 
923 /// std::ostream insertion operator for SerialDenseVector (Pecos namespace)
924 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & data)925 inline std::ostream& operator<<(std::ostream& s,
926   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data)
927 {
928   //write_data(s, data); // not necessary since no additional options
929   //return s;
930 
931   s << std::scientific << std::setprecision(WRITE_PRECISION);
932   OrdinalType len = data.length();
933   for (OrdinalType i=0; i<len; i++)
934     s << "                     " << std::setw(WRITE_PRECISION+7)
935       << data[i] << '\n';
936   return s;
937 }
938 
939 
940 /// std::ostream insertion operator for SerialDenseMatrix (Pecos namespace)
941 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & data)942 inline std::ostream& operator<<(std::ostream& s,
943   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data)
944 { write_data(s, data, true, true, true); return s; }
945 
946 
947 /// std::ostream insertion operator for SerialSymDenseMatrix (Pecos namespace)
948 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & data)949 inline std::ostream& operator<<(std::ostream& s,
950   const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data)
951 { write_data(s, data, true, true, true); return s; }
952 
953 
954 /// std::ostream insertion operator for std::vector (Pecos namespace)
955 template <typename T>
operator <<(std::ostream & s,const std::vector<T> & data)956 std::ostream& operator<<(std::ostream& s, const std::vector<T>& data)
957 {
958   s << std::scientific << std::setprecision(WRITE_PRECISION);
959   size_t i=0, len = data.size();
960   for (i=0; i<len; ++i)
961     s << "                     " << std::setw(WRITE_PRECISION+7)
962       << data[i] << '\n';
963   return s;
964 }
965 
966 
967 /// std::ostream insertion operator for std::set (Pecos namespace)
968 template <typename T>
operator <<(std::ostream & s,const std::set<T> & data)969 std::ostream& operator<<(std::ostream& s, const std::set<T>& data)
970 {
971   for (typename std::set<T>::const_iterator cit = data.begin();
972        cit != data.end(); ++cit)
973     s << "                     " << std::setw(WRITE_PRECISION+7)
974       << *cit << '\n';
975   return s;
976 }
977 
978 } // namespace Pecos
979 
980 #endif // PECOS_DATA_TYPES_H
981