1 /*  _______________________________________________________________________
2 
3     DAKOTA: Design Analysis Kit for Optimization and Terascale Applications
4     Copyright 2014-2020 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
5     This software is distributed under the GNU Lesser General Public License.
6     For more information, see the README file in the top Dakota directory.
7     _______________________________________________________________________ */
8 
9 #ifndef DAKOTA_DATA_IO_H
10 #define DAKOTA_DATA_IO_H
11 
12 #include "dakota_system_defs.hpp"
13 #include "dakota_global_defs.hpp"  // for Cerr, write_precision
14 #include "dakota_data_types.hpp"
15 #include "ExperimentDataUtils.hpp"
16 #include "MPIPackBuffer.hpp"
17 #include <boost/archive/binary_oarchive.hpp>
18 #include <boost/archive/binary_iarchive.hpp>
19 #include <boost/serialization/split_free.hpp>
20 
21 namespace boost {
22 namespace serialization {
23 
24 // this is NOT the recommend way to read contiguous arrays, but it's a start
25 // http://www.boost.org/doc/libs/1_54_0/libs/serialization/doc/wrappers.html#arrays
26 /// Load a Teuchos::SerialDenseVector from an archive
27 template <class Archive, typename OrdinalType, typename ScalarType>
load(Archive & ar,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const unsigned int version)28 void load(Archive& ar, Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
29      const unsigned int version)
30 {
31   OrdinalType i, len;
32   ar & len;
33   if( len != v.length() )
34     v.sizeUninitialized(len);
35   for (i=0; i<len; ++i)
36     ar & v[i];
37 }
38 
39 /// Save a Teuchos::SerialDenseVector  an archive
40 template <class Archive, typename OrdinalType, typename ScalarType>
save(Archive & ar,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const unsigned int version)41 void save(Archive& ar,
42 	  const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
43 	  const unsigned int version)
44 {
45   OrdinalType i, len = v.length();
46   ar & len;
47   // make a temporary array for serialization
48   //  ar & make_array(v.values(), len);
49   for (i=0; i<len; ++i)
50     ar & v[i];
51 }
52 
53 /// Serialize a symmetric matrix (pre-sized) to/from an archive
54 template<class Archive, typename OrdinalType, typename ScalarType>
serialize(Archive & ar,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & sm,const unsigned int version)55 void serialize(Archive& ar,
56 	       Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& sm,
57 	       const unsigned int version)
58 {
59   OrdinalType i, j, nrows = sm.numRows();
60   for (i=0; i<nrows; ++i)
61     for (j=0; j<=i; ++j)
62       ar & sm(i,j);
63 }
64 
65 /// serialization save for 1-D boost::multi_array
66 template<typename T, class Archive>
save(Archive & ar,const boost::multi_array<T,1> & ma_1d,const unsigned int version)67 void save(Archive& ar, const boost::multi_array<T, 1>& ma_1d,
68 	  const unsigned int version)
69 {
70   typename boost::multi_array<T, 1>::size_type size0 = ma_1d.shape()[0];
71   ar << size0;
72   ar << boost::serialization::make_array(ma_1d.data(), ma_1d.num_elements());
73 }
74 
75 /// serialization load for 1-D boost::multi_array
76 template<typename T, class Archive>
load(Archive & ar,boost::multi_array<T,1> & ma_1d,const unsigned int version)77 void load(Archive& ar, boost::multi_array<T,1>& ma_1d,
78 	  const unsigned int version)
79 {
80   typename boost::multi_array<T, 1>::size_type size0;
81   ar >> size0;
82   ma_1d.resize(boost::extents[size0]);
83   ar >> boost::serialization::make_array(ma_1d.data(), ma_1d.num_elements());
84 }
85 
86 
87 /// save a boost dynamic bitset, size, then contents
88 template <class Archive, typename Block, typename Allocator>
save(Archive & ar,const boost::dynamic_bitset<Block,Allocator> & bs,const unsigned int version)89 inline void save(Archive &ar,
90 		 const boost::dynamic_bitset<Block, Allocator>& bs,
91 		 const unsigned int version)
92 {
93   size_t size = bs.size();
94   ar & size;
95 
96   // create a vector of blocks and serialize it
97   std::vector<Block> vec_block(bs.num_blocks());
98   to_block_range(bs, vec_block.begin());
99   ar & vec_block;
100 }
101 
102 /// load a boost dynamic bitset, size, then contents
103 template <class Archive, typename Block, typename Allocator>
load(Archive & ar,boost::dynamic_bitset<Block,Allocator> & bs,const unsigned int version)104 inline void load(Archive &ar,
105 		 boost::dynamic_bitset<Block, Allocator> &bs,
106 		 const unsigned int version)
107 {
108   size_t size;
109   ar & size;
110 
111   bs.resize(size);
112 
113   // Load vector
114   std::vector<Block> vec_block;
115   ar & vec_block;
116 
117   // Convert vector into a bitset
118   from_block_range(vec_block.begin(), vec_block.end(), bs);
119 }
120 
121 }  // namespace serialization
122 }  // namespace boost
123 
124 /// Register separate load/save for IntVector type
125 BOOST_SERIALIZATION_SPLIT_FREE(Dakota::IntVector)
126 /// Register separate load/save for RealVector type
127 BOOST_SERIALIZATION_SPLIT_FREE(Dakota::RealVector)
128 /// Register separate load/save for BitArray type
129 BOOST_SERIALIZATION_SPLIT_FREE(Dakota::BitArray)
130 /// Register separate load/save for StringMultiArray type
131 BOOST_SERIALIZATION_SPLIT_FREE(Dakota::StringMultiArray)
132 
133 
134 namespace Dakota {
135 
136 
137 // Forward declarations since these operators are used in read/write data and vice-versa
138 
139 /// global std::istream extraction operator for std::vector
140 template <typename T>
141 std::istream& operator>>(std::istream& s, std::vector<T>& data);
142 
143 /// global std::ostream insertion operator for std::vector
144 template <typename T>
145 std::ostream& operator<<(std::ostream& s, const std::vector<T>& data);
146 
147 /// global std::ostream insertion operator for std::list
148 template <typename T>
149 std::ostream& operator<<(std::ostream& s, const std::list<T>& data);
150 
151 /// global ostream insertion operator for std::pair
152 template <typename U, typename V>
153 std::ostream& operator<<(std::ostream& s, const std::pair<U,V>& data);
154 
155 /// global std::ostream insertion operator for std::set
156 template <typename T>
157 std::ostream& operator<<(std::ostream& s, const std::set<T>& data);
158 
159 /// global std::ostream insertion operator for std::map
160 template <typename KeyT, typename ValueT>
161 std::ostream& operator<<(std::ostream& s, const std::map<KeyT, ValueT>& data);
162 
163 /// global std::istream extraction operator for SerialDenseVector
164 template <typename OrdinalType, typename ScalarType>
165 std::istream& operator>>(std::istream& s,
166 			 Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data);
167 
168 /// global std::ostream insertion operator for SerialDenseVector
169 template <typename OrdinalType, typename ScalarType>
170 std::ostream& operator<<(std::ostream& s,
171 			 const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data);
172 
173 /// global std::istream extraction operator for SerialDenseMatrix
174 template <typename OrdinalType, typename ScalarType>
175 std::istream& operator>>(std::istream& s,
176 			 Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data);
177 
178 /// global std::ostream insertion operator for SerialDenseMatrix
179 template <typename OrdinalType, typename ScalarType>
180 std::ostream& operator<<(std::ostream& s,
181 			 const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data);
182 
183 /// global std::istream extraction operator for SerialSymDenseMatrix
184 template <typename OrdinalType, typename ScalarType>
185 std::istream& operator>>(std::istream& s,
186 			 Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data);
187 
188 /// global std::ostream insertion operator for SerialSymDenseMatrix
189 template <typename OrdinalType, typename ScalarType>
190 std::ostream& operator<<(std::ostream& s,
191 			 const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data);
192 
193 
194 /// simple utility to convert intrinsics to strings
195 template <typename T>
convert_to_string(const T & value)196   inline std::string convert_to_string(const T &value) {
197     std::ostringstream out;
198     out << value;
199     return out.str();
200   }
201 
202 /// istream extraction operator for configuration data of known dim and length
203 void read_sized_data(std::istream& s,
204                      RealVectorArray& va,
205                      size_t num_experiments,
206                      int num_state_variables);
207 
208 /// istream extraction operator for response data of known dim and
209 /// unknown length
210 void read_fixed_rowsize_data(std::istream& s,
211                              RealVectorArray& va,
212                              int num_responses,
213                              bool row_major = true);
214 
215 /// istream extraction operator for coordinate data of unknown dim and
216 /// unknown length
217 void read_unsized_data(std::istream& s,
218                        RealVectorArray& va,
219                        bool row_major = true);
220 
221 /// file reader for configuration data supplied via multiple files
222 void read_config_vars_multifile(const std::string& basename,
223                                 int num_expts,
224                                 int ncv,
225                                 RealVectorArray& config_vars);
226 
227 /// file reader for configuration data supplied via a single file
228 void read_config_vars_singlefile(const std::string& basename,
229                                  int num_expts,
230                                  int ncv,
231                                  RealVectorArray& config_vars);
232 
233 /// file reader for vector field (response) data
234 void read_field_values(const std::string& basename,
235                        int expt_num,
236                        RealVectorArray& field_vars);
237 
238 /// file reader for scalar field (response) data
239 void read_field_values(const std::string& basename,
240                        int expt_num,
241                        RealVector& field_vars);
242 
243 /// file reader for simulation coordinate data
244 void read_coord_values(const std::string& basename,
245                        RealMatrix& coords);
246 
247 /// file reader for experimental coordinate data
248 void read_coord_values(const std::string& basename,
249                        int expt_num,
250                        RealMatrix& coords);
251 
252 /// file reader for CONSTANT covariance data
253 void read_covariance(const std::string& basename,
254                      int expt_num,
255                      RealMatrix& cov_vals);
256 
257 /// file reader for VECTOR and MATRIX covariance data
258 void read_covariance(const std::string& basename,
259                      int expt_num,
260                      Dakota::CovarianceMatrix::FORMAT,
261                      int num_vals,
262                      RealMatrix& cov_vals);
263 
264 
265 // --------------------------------
266 // templated istream read functions (some called from operator>>)
267 // --------------------------------
268 
269 
270 /// standard istream extraction operator for full SerialDenseVector
271 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v)272 void read_data(std::istream& s,
273 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v)
274 {
275   OrdinalType i, len = v.length();
276   std::string token;
277   for (i=0; i<len; ++i)
278     { s >> token; v[i] = std::atof(token.c_str()); }
279 }
280 
281 
282 /// standard istream extraction operator for SerialSymDenseMatrix
283 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & m)284 void read_data(std::istream& s,
285                Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& m)
286 {
287   // for istream, read full matrix
288   OrdinalType i, j, nrows = m.numRows(), ncols = m.numCols();
289   std::string token;
290   for (i=0; i<nrows; ++i)
291     for (j=0; j<ncols; ++j)
292       { s >> token; m(i,j) = std::atof(token.c_str()); }
293 }
294 
295 
296 /// standard istream extraction operator for SerialSymDenseMatrix
297 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & m)298 void read_data(std::istream& s,
299                Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& m)
300 {
301   // for istream, read full matrix
302   OrdinalType i, j, nrows = m.numRows();
303   std::string token;
304   for (i=0; i<nrows; ++i)
305     for (j=0; j<nrows; ++j)
306       { s >> token; m(i,j) = std::atof(token.c_str()); }
307 }
308 
309 
310 /// standard istream extraction operator for std::vector of SerialDenseVectors
311 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,std::vector<Teuchos::SerialDenseVector<OrdinalType,ScalarType>> & va)312 void read_data(std::istream& s,
313   std::vector<Teuchos::SerialDenseVector<OrdinalType, ScalarType> >& va)
314 {
315   OrdinalType i, j, nrows = va.size(), ncols = (nrows > 0) ? va[0].length() : 0;
316   std::string token;
317   for (i=0; i<nrows; ++i)
318     for (j=0; j<ncols; ++j)
319       { s >> token; va[i][j] = std::atof(token.c_str()); }
320 }
321 
322 
323 /// standard istream extraction operator for full SerialDenseVector with labels
324 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArray & label_array)325 void read_data(std::istream& s,
326 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
327 	       StringMultiArray& label_array)
328 {
329   OrdinalType i, len = v.length();
330   if (label_array.size() != len)
331     label_array.resize(boost::extents[len]);
332   for (i=0; i<len; ++i)
333     s >> v[i] >> label_array[i];
334 }
335 
336 
337 /// standard istream extraction operator for full SerialDenseVector with labels
338 template <typename OrdinalType, typename ScalarType>
read_data(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArrayView label_array)339 void read_data(std::istream& s,
340 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
341 	       StringMultiArrayView label_array)
342 {
343   OrdinalType i, len = v.length();
344   if (label_array.size() != len) {
345     Cerr << "Error: size of label_array in read_data(std::istream) does not "
346 	 << "equal length of SerialDenseVector." << std::endl;
347     abort_handler(-1);
348   }
349   for (i=0; i<len; ++i)
350     s >> v[i] >> label_array[i];
351 }
352 
353 
354 /// standard istream extraction operator for StringMultiArray with labels
read_data(std::istream & s,StringMultiArray & v,StringMultiArrayView label_array)355 inline void read_data(std::istream& s, StringMultiArray& v,
356 		      StringMultiArrayView label_array)
357 {
358   size_t i, len = v.size();
359   if (label_array.size() != len) {
360     Cerr << "Error: size of label_array in read_data(std::istream) does not "
361 	 << "equal length of StringMultiArray." << std::endl;
362     abort_handler(-1);
363   }
364   for (i=0; i<len; ++i)
365     s >> v[i] >> label_array[i];
366 }
367 
368 
369 /// standard istream extraction operator for partial SerialDenseVector
370 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
read_data_partial(std::istream & s,OrdinalType2 start_index,OrdinalType2 num_items,Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v)371 void read_data_partial(std::istream& s,
372 		       OrdinalType2 start_index, OrdinalType2 num_items,
373 		       Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v)
374 {
375   OrdinalType2 i, end = start_index + num_items;
376   if (end > v.length()) {
377     Cerr << "Error: indexing in Vector<T>::read_data_partial(istream) exceeds "
378 	 << "length of SerialDenseVector." << std::endl;
379     abort_handler(-1);
380   }
381   for (i=start_index; i<end; ++i)
382     s >> v[i];
383 }
384 
385 
386 /// standard istream extraction operator for partial SerialDenseVector
387 /// with labels (as StringMultiArray&)
388 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
read_data_partial(std::istream & s,OrdinalType2 start_index,OrdinalType2 num_items,Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v,StringMultiArray & label_array)389 void read_data_partial(std::istream& s,
390 		       OrdinalType2 start_index, OrdinalType2 num_items,
391 		       Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v,
392 		       StringMultiArray& label_array)
393 {
394   OrdinalType1 len = v.length();
395   OrdinalType2 i, end = start_index + num_items;
396   if (end > len) {
397     Cerr << "Error: indexing in read_data_partial(std::istream) exceeds "
398 	 << "length of SerialDenseVector." << std::endl;
399     abort_handler(-1);
400   }
401   if (label_array.size() != len)
402     label_array.resize(boost::extents[len]);
403   for (i=start_index; i<end; ++i)
404     s >> v[i] >> label_array[i];
405 }
406 
407 
408 /// standard istream extraction operator for partial SerialDenseVector
409 /// with labels (as StringMultiArrayView)
410 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
read_data_partial(std::istream & s,OrdinalType2 start_index,OrdinalType2 num_items,Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v,StringMultiArrayView label_array)411 void read_data_partial(std::istream& s,
412 		       OrdinalType2 start_index, OrdinalType2 num_items,
413 		       Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v,
414 		       StringMultiArrayView label_array)
415 {
416   OrdinalType1 len = v.length();
417   OrdinalType2 i, end = start_index + num_items;
418   if (end > len) {
419     Cerr << "Error: indexing in read_data_partial(std::istream) exceeds "
420 	 << "length of SerialDenseVector." << std::endl;
421     abort_handler(-1);
422   }
423   if (label_array.size() != len) {
424     Cerr << "Error: size of label_array in read_data_partial(std::istream) "
425 	 << "does not equal length of SerialDenseVector." << std::endl;
426     abort_handler(-1);
427   }
428   for (i=start_index; i<end; ++i)
429     s >> v[i] >> label_array[i];
430 }
431 
432 
433 /// standard istream extraction operator for partial StringMultiArray
434 /// with labels (as StringMultiArrayView)
435 template <typename OrdinalType>
read_data_partial(std::istream & s,OrdinalType start_index,OrdinalType num_items,StringMultiArray & v,StringMultiArrayView label_array)436 void read_data_partial(std::istream& s, OrdinalType start_index,
437 		       OrdinalType num_items, StringMultiArray& v,
438 		       StringMultiArrayView label_array)
439 {
440   OrdinalType i, len = v.size(), end = start_index + num_items;
441   if (end > len) {
442     Cerr << "Error: indexing in read_data_partial(std::istream) exceeds "
443 	 << "length of StringMultiArray." << std::endl;
444     abort_handler(-1);
445   }
446   if (label_array.size() != len) {
447     Cerr << "Error: size of label_array in read_data_partial(std::istream) "
448 	 << "does not equal length of StringMultiArray." << std::endl;
449     abort_handler(-1);
450   }
451   for (i=start_index; i<end; ++i)
452     s >> v[i] >> label_array[i];
453 }
454 
455 
456 /// tabular istream extraction operator for full SerialDenseVector
457 template <typename OrdinalType, typename ScalarType>
read_data_tabular(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v)458 void read_data_tabular(std::istream& s,
459 		       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v)
460 {
461   // differs from read_data(std::istream& s) only in exception handling
462   OrdinalType i, len = v.length();
463   s >> std::ws;
464   for (i=0; i<len; ++i) {
465     if (s && !s.eof()) {
466       s >> v[i];
467       s >> std::ws;
468     }
469     else {
470       std::string err =
471 	"At EOF: insufficient tabular data for SerialDenseVector[" +
472 	std::to_string(i) + "]";
473       throw TabularDataTruncated(err);
474     }
475   }
476 }
477 
478 
479 /// tabular istream extraction operator for partial SerialDenseVector
480 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
read_data_partial_tabular(std::istream & s,OrdinalType2 start_index,OrdinalType2 num_items,Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v)481 void read_data_partial_tabular(std::istream& s,
482   OrdinalType2 start_index, OrdinalType2 num_items,
483   Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v)
484 {
485   OrdinalType2 i, end = start_index + num_items;
486   if (end > v.length()) {
487     Cerr << "Error: indexing in Vector<T>::read_data_partial_tabular(istream) "
488 	 << "exceeds length of SerialDenseVector." << std::endl;
489     abort_handler(-1);
490   }
491   for (i=start_index; i<end; ++i) {
492     if (s)
493       s >> v[i];
494     else {
495       std::string err =
496 	"At EOF: insufficient tabular data for SerialDenseVector[" +
497 	std::to_string(i) + "]";
498       throw TabularDataTruncated(err);
499     }
500   }
501 }
502 
503 
504 /// tabular istream extraction operator for partial SerialDenseVector
505 template <typename OrdinalType>
read_data_partial_tabular(std::istream & s,OrdinalType start_index,OrdinalType num_items,StringMultiArray & v)506 void read_data_partial_tabular(std::istream& s, OrdinalType start_index,
507 			       OrdinalType num_items, StringMultiArray& v)
508 {
509   OrdinalType i, end = start_index + num_items;
510   if (end > v.size()) {
511     Cerr << "Error: indexing in Vector<T>::read_data_partial_tabular(istream) "
512 	 << "exceeds length of StringMultiArray." << std::endl;
513     abort_handler(-1);
514   }
515   for (i=start_index; i<end; ++i) {
516     if (s)
517       s >> v[i];
518     else {
519       std::string err =
520 	"At EOF: insufficient tabular data for StringMultiArray[" +
521 	std::to_string(i) + "]";
522       throw TabularDataTruncated(err);
523     }
524   }
525 }
526 
527 
528 /// annotated istream extraction operator for full SerialDenseVector with labels
529 template <typename OrdinalType, typename ScalarType>
read_data_annotated(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArray & label_array)530 void read_data_annotated(std::istream& s,
531   Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
532   StringMultiArray& label_array)
533 {
534   OrdinalType i, len;
535   s >> len;
536   if( len != v.length() )
537     v.sizeUninitialized(len);
538   if( len != label_array.size() )
539     label_array.resize(boost::extents[len]);
540   for (i=0; i<len; ++i)
541     s >> v[i] >> label_array[i];
542 }
543 
544 
545 /// annotated istream extraction operator for full SerialDenseVector with labels
546 template <typename OrdinalType, typename ScalarType>
read_data_annotated(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArrayView label_array)547 void read_data_annotated(std::istream& s,
548   Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
549   StringMultiArrayView label_array)
550 {
551   OrdinalType i, len;
552   s >> len;
553   if( len != v.length() )
554     v.sizeUninitialized(len);
555   if( len != label_array.size() ) {
556     Cerr << "Error: size of label_array in read_data_annotated(std::istream) "
557 	 << "does not equal length of SerialDenseVector." << std::endl;
558     abort_handler(-1);
559   }
560   for (i=0; i<len; ++i)
561     s >> v[i] >> label_array[i];
562 }
563 
564 
565 /// annotated istream extraction operator for StringMultiArray with labels
read_data_annotated(std::istream & s,StringMultiArray & v,StringMultiArrayView label_array)566 inline void read_data_annotated(std::istream& s, StringMultiArray& v,
567 				StringMultiArrayView label_array)
568 {
569   size_t i, len;
570   s >> len;
571   if( len != v.size() )
572     v.resize(boost::extents[len]);
573   if( len != label_array.size() ) {
574     Cerr << "Error: size of label_array in read_data_annotated(std::istream) "
575 	 << "does not equal length of StringMultiArray." << std::endl;
576     abort_handler(-1);
577   }
578   for (i=0; i<len; ++i)
579     s >> v[i] >> label_array[i];
580 }
581 
582 
583 /// istream partial specialization for reading the lower triangle of a
584 /// SerialSymDenseMatrix
585 template <typename OrdinalType, typename ScalarType>
read_lower_triangle(std::istream & s,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & sm)586 void read_lower_triangle(std::istream& s,
587   Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& sm)
588 {
589   OrdinalType i, j, nrows = sm.numRows();
590   std::string token;
591   for (i=0; i<nrows; ++i)
592     for (j=0; j<=i; ++j)
593       { s >> token; sm(i,j) = std::atof(token.c_str()); }
594 }
595 
596 
597 /// generic input stream template for reading the lower triangle of a
598 /// SerialSymDenseMatrix
599 template <typename IStreamType, typename OrdinalType, typename ScalarType>
read_lower_triangle(IStreamType & s,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & sm)600 void read_lower_triangle(IStreamType& s,
601   Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& sm)
602 {
603   OrdinalType i, j, nrows = sm.numRows();
604   for (i=0; i<nrows; ++i)
605     for (j=0; j<=i; ++j)
606       s >> sm(i,j);
607 }
608 
609 
610 /// istream partial specialization for reading a column vector of a
611 /// SerialDenseMatrix
612 template <typename OrdinalType, typename ScalarType>
read_col_vector_trans(std::istream & s,OrdinalType col,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm)613 void read_col_vector_trans(std::istream& s, OrdinalType col,
614   Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm)
615 {
616   OrdinalType nr = sdm.numRows();
617   ScalarType* sdm_c = sdm[col]; // column vector
618   std::string token; // handles NaN and +/-Inf
619   for (OrdinalType row=0; row<nr; ++row)
620     { s >> token; sdm_c[row] = std::atof(token.c_str()); }
621 }
622 
623 
624 /// generic input stream template for reading a column vector of a
625 /// SerialDenseMatrix
626 template <typename IStreamType, typename OrdinalType, typename ScalarType>
read_col_vector_trans(IStreamType & s,OrdinalType col,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm)627 void read_col_vector_trans(IStreamType& s, OrdinalType col,
628   Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm)
629 {
630   OrdinalType nr = sdm.numRows();
631   ScalarType* sdm_c = sdm[col]; // column vector
632   for (OrdinalType row=0; row<nr; ++row)
633     s >> sdm_c[row];
634 }
635 
636 
637 /// read array from std::istream
638 template <typename ArrayT>
array_read(std::istream & s,ArrayT & v)639 inline void array_read(std::istream& s, ArrayT& v)
640 {
641   typename ArrayT::size_type len = v.size();
642   for (typename ArrayT::size_type i=0; i<len; ++i)
643     s >> v[i];
644 }
645 
646 
647 // ---------------------------------
648 // templated ostream write functions (some called from operator<<)
649 // ---------------------------------
650 
651 
652 /// standard ostream insertion operator for pointer
653 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const ScalarType * v,OrdinalType len)654 void write_data(std::ostream& s, const ScalarType* v, OrdinalType len)
655 {
656   s << std::scientific << std::setprecision(write_precision);
657   for (OrdinalType i=0; i<len; ++i)
658     s << "                     " << std::setw(write_precision+7) << v[i]
659       << '\n';
660 }
661 
662 
663 /// standard ostream insertion operator for full SerialDenseVector
664 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v)665 void write_data(std::ostream& s,
666 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v)
667 {
668   OrdinalType i, len = v.length();
669   s << std::scientific << std::setprecision(write_precision);
670   for (i=0; i<len; ++i)
671     s << "                     " << std::setw(write_precision+7) << v[i]
672       << '\n';
673 }
674 
675 
676 /// standard ostream insertion operator for full SerialDenseVector with labels
677 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const StringMultiArray & label_array)678 void write_data(std::ostream& s,
679 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
680 		const StringMultiArray& label_array)
681 {
682   OrdinalType i, len = v.length();
683   if (label_array.size() != len) {
684     Cerr << "Error: size of label_array in write_data(std::ostream) does not "
685 	 << "equal length of SerialDenseVector." << std::endl;
686     abort_handler(-1);
687   }
688   s << std::scientific << std::setprecision(write_precision);
689   for (i=0; i<len; ++i)
690     s << "                     " << std::setw(write_precision+7) << v[i] << ' '
691       << label_array[i] << '\n';
692 }
693 
694 
695 // BMA: Also needed for MSVS 2008, and probably in general as a
696 // const_array_view shouldn't be convertible to const multi_array&
697 // Could consider a single implementation with a forward from const &
698 // to const view
699 
700 /// standard ostream insertion operator for full SerialDenseVector with labels
701 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArrayConstView label_array)702 void write_data(std::ostream& s,
703 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
704 		StringMultiArrayConstView label_array)
705 {
706   OrdinalType i, len = v.length();
707   if (label_array.size() != len) {
708     Cerr << "Error: size of label_array in write_data(std::ostream) does not "
709 	 << "equal length of SerialDenseVector." << std::endl;
710     abort_handler(-1);
711   }
712   s << std::scientific << std::setprecision(write_precision);
713   for (i=0; i<len; ++i)
714     s << "                     " << std::setw(write_precision+7) << v[i] << ' '
715       << label_array[i] << '\n';
716 }
717 //#endif
718 
719 
720 /// standard ostream insertion operator for full SerialDenseVector
721 /// with alternate labels
722 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const StringArray & label_array)723 void write_data(std::ostream& s,
724 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
725 		const StringArray& label_array)
726 {
727   OrdinalType i, len = v.length();
728   if (label_array.size() != len) {
729     Cerr << "Error: size of label_array in write_data(std::ostream) does not "
730 	 << "equal length of SerialDenseVector." << std::endl;
731     abort_handler(-1);
732   }
733   s << std::scientific << std::setprecision(write_precision);
734   for (i=0; i<len; ++i)
735     s << "                     " << std::setw(write_precision+7) << v[i] << ' '
736       << label_array[i] << '\n';
737 }
738 
739 
740 /// standard ostream insertion operator for StringMultiArray
write_data(std::ostream & s,const StringMultiArray & v)741 inline void write_data(std::ostream& s, const StringMultiArray& v)
742 {
743   size_t i, len = v.size();
744   //s << std::scientific << std::setprecision(write_precision);
745   for (i=0; i<len; ++i)
746     s << "                     " << std::setw(write_precision+7) << v[i] <<'\n';
747 }
748 
749 
750 /// aprepro ostream insertion operator for full SerialDenseVector with labels
751 template <typename OrdinalType, typename ScalarType>
write_data_aprepro(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const StringMultiArray & label_array)752 void write_data_aprepro(std::ostream& s,
753   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
754   const StringMultiArray& label_array)
755 {
756   OrdinalType i, len = v.length();
757   if (label_array.size() != len) {
758     Cerr << "Error: size of label_array in write_data_aprepro(std::ostream) "
759 	 << "does not equal length of SerialDenseVector." << std::endl;
760     abort_handler(-1);
761   }
762   s << std::scientific << std::setprecision(write_precision);
763   for (i=0; i<len; ++i)
764     s << "                    { " << std::setw(15)
765       << std::setiosflags(std::ios::left)
766       << label_array[i].data() << std::resetiosflags(std::ios::adjustfield)
767       << " = " << std::setw(write_precision+7) << v[i] <<" }\n";
768 }
769 
770 
771 /// standard ostream insertion operator for partial std::vector
772 template <typename OrdinalType, typename ScalarType>
write_data_partial(std::ostream & s,OrdinalType start_index,OrdinalType num_items,const std::vector<ScalarType> & v)773 void write_data_partial(std::ostream& s, OrdinalType start_index,
774 			OrdinalType num_items, const std::vector<ScalarType>& v)
775 {
776   OrdinalType i, end = start_index + num_items;
777   if (end > v.size()) {
778     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
779 	 << "length of std::vector." << std::endl;
780     abort_handler(-1);
781   }
782   s << std::scientific << std::setprecision(write_precision);
783   for (i=start_index; i<end; ++i)
784     s << "                     " << std::setw(write_precision+7) << v[i] <<'\n';
785 }
786 
787 
788 /// standard ostream insertion operator for partial SerialDenseVector
789 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
write_data_partial(std::ostream & s,OrdinalType2 start_index,OrdinalType2 num_items,const Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v)790 void write_data_partial(std::ostream& s,
791   OrdinalType2 start_index, OrdinalType2 num_items,
792   const Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v)
793 {
794   OrdinalType2 end = start_index + num_items;
795   if (end > v.length()) {
796     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
797 	 << "length of SerialDenseVector." << std::endl;
798     abort_handler(-1);
799   }
800   s << std::scientific << std::setprecision(write_precision);
801   for (OrdinalType2 i=start_index; i<end; ++i)
802     s << "                     " << std::setw(write_precision+7) << v[i] <<'\n';
803 }
804 
805 
806 /// standard ostream insertion operator for partial SerialDenseVector
807 /// with labels (StringMultiArray or StringArray)
808 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType,
809 	  typename LabelArrayType>
write_data_partial(std::ostream & s,OrdinalType2 start_index,OrdinalType2 num_items,const Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v,const LabelArrayType & label_array)810 void write_data_partial(std::ostream& s,
811   OrdinalType2 start_index, OrdinalType2 num_items,
812   const Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v,
813   const LabelArrayType& label_array)
814 {
815   OrdinalType2 i, end = start_index + num_items;
816   OrdinalType1 len = v.length();
817   if (end > len) {
818     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
819 	 << "length of SerialDenseVector." << std::endl;
820     abort_handler(-1);
821   }
822   if (label_array.size() != len) {
823     Cerr << "Error: size of label_array in write_data_partial(std::ostream) "
824 	 << "does not equal length of SerialDenseVector." << std::endl;
825     abort_handler(-1);
826   }
827   s << std::scientific << std::setprecision(write_precision);
828   for (i=start_index; i<end; ++i)
829     s << "                     " << std::setw(write_precision+7) << v[i] << ' '
830       << label_array[i] << '\n';
831 }
832 
833 
834 /// standard ostream insertion operator for partial StringMultiArray
835 template <typename OrdinalType>
write_data_partial(std::ostream & s,OrdinalType start_index,OrdinalType num_items,const StringMultiArray & v)836 void write_data_partial(std::ostream& s, OrdinalType start_index,
837 			OrdinalType num_items, const StringMultiArray& v)
838 {
839   OrdinalType i, end = start_index + num_items, len = v.size();
840   if (end > len) {
841     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
842 	 << "length of StringMultiArray." << std::endl;
843     abort_handler(-1);
844   }
845   //s << std::scientific << std::setprecision(write_precision);
846   for (i=start_index; i<end; ++i)
847     s << "                     " << std::setw(write_precision+7) << v[i] <<'\n';
848 }
849 
850 
851 // BMA: Implementation accepting a const_array_view since can't
852 // convert to const& prototype above.  Could convert const & to a view
853 // and pass to this function to have a single implementation...
854 
855 /// standard ostream insertion operator for partial StringMultiArray
856 template <typename OrdinalType>
write_data_partial(std::ostream & s,OrdinalType start_index,OrdinalType num_items,StringMultiArrayConstView v)857 void write_data_partial(std::ostream& s, OrdinalType start_index,
858 			OrdinalType num_items, StringMultiArrayConstView v)
859 {
860   OrdinalType i, end = start_index + num_items, len = v.size();
861   if (end > len) {
862     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
863 	 << "length of StringMultiArray." << std::endl;
864     abort_handler(-1);
865   }
866   //s << std::scientific << std::setprecision(write_precision);
867   for (i=start_index; i<end; ++i)
868     s << "                     " << std::setw(write_precision+7) << v[i] <<'\n';
869 }
870 
871 
872 /// standard ostream insertion operator for partial StringMultiArray
873 /// with labels
874 template <typename OrdinalType>
write_data_partial(std::ostream & s,OrdinalType start_index,OrdinalType num_items,const StringMultiArray & v,StringMultiArrayConstView label_array)875 void write_data_partial(std::ostream& s, OrdinalType start_index,
876 			OrdinalType num_items, const StringMultiArray& v,
877 			StringMultiArrayConstView label_array)
878 {
879   OrdinalType i, end = start_index + num_items, len = v.size();
880   if (end > len) {
881     Cerr << "Error: indexing in write_data_partial(std::ostream) exceeds "
882 	 << "length of StringMultiArray." << std::endl;
883     abort_handler(-1);
884   }
885   if (label_array.size() != len) {
886     Cerr << "Error: size of label_array in write_data_partial(std::ostream) "
887 	 << "does not equal length of StringMultiArray." << std::endl;
888     abort_handler(-1);
889   }
890   //s << std::scientific << std::setprecision(write_precision);
891   for (i=start_index; i<end; ++i)
892     s << "                     " << std::setw(write_precision+7) << v[i] << ' '
893       << label_array[i] << '\n';
894 }
895 
896 
897 /// aprepro ostream insertion operator for partial SerialDenseVector with labels
898 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
write_data_partial_aprepro(std::ostream & s,OrdinalType2 start_index,OrdinalType2 num_items,const Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v,const StringMultiArray & label_array)899 void write_data_partial_aprepro(std::ostream& s, OrdinalType2 start_index,
900   OrdinalType2 num_items,
901   const Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v,
902   const StringMultiArray& label_array)
903 {
904   OrdinalType2 i, end = start_index + num_items;
905   OrdinalType1 len = v.length();
906   if (end > len) {
907     Cerr << "Error: indexing in write_data_partial_aprepro(std::ostream) "
908 	 << "exceeds length of SerialDenseVector." << std::endl;
909     abort_handler(-1);
910   }
911   if (label_array.size() != len) {
912     Cerr << "Error: size of label_array in write_data_partial_aprepro"
913 	 << "(std::ostream) does not equal length of Vector." << std::endl;
914     abort_handler(-1);
915   }
916   s << std::scientific << std::setprecision(write_precision);
917   for (i=start_index; i<end; ++i)
918     s << "                    { " << std::setw(15)
919       << std::setiosflags(std::ios::left)
920       << label_array[i].data() << std::resetiosflags(std::ios::adjustfield)
921       << " = " << std::setw(write_precision+7) << v[i] <<" }\n";
922 }
923 
924 
925 /// aprepro ostream insertion operator for partial StringMultiArray with labels
926 /// (string variables must be quoted for use with aprepro)
927 template <typename OrdinalType>
write_data_partial_aprepro(std::ostream & s,OrdinalType start_index,OrdinalType num_items,const StringMultiArray & v,StringMultiArrayConstView label_array)928 void write_data_partial_aprepro(std::ostream& s, OrdinalType start_index,
929   OrdinalType num_items, const StringMultiArray& v,
930   StringMultiArrayConstView label_array)
931 {
932   OrdinalType i, end = start_index + num_items, len = v.size();
933   if (end > len) {
934     Cerr << "Error: indexing in write_data_partial_aprepro(std::ostream) "
935 	 << "exceeds length of StringMultiArray." << std::endl;
936     abort_handler(-1);
937   }
938   if (label_array.size() != len) {
939     Cerr << "Error: size of label_array in write_data_partial_aprepro(std::"
940 	 << "ostream) does not equal length of StringMultiArray." << std::endl;
941     abort_handler(-1);
942   }
943   //s << std::scientific << std::setprecision(write_precision);
944   for (i=start_index; i<end; ++i)
945     s << "                    { " << std::setw(15)
946       << std::setiosflags(std::ios::left)
947       << label_array[i].data() << std::resetiosflags(std::ios::adjustfield)
948       << " = " << std::setw(write_precision+7) << '"' << v[i] << '"' << " }\n";
949 }
950 
951 
952 /// annotated ostream insertion operator for full SerialDenseVector with labels
953 template <typename OrdinalType, typename ScalarType>
write_data_annotated(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const StringMultiArray & label_array)954 void write_data_annotated(std::ostream& s,
955   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
956   const StringMultiArray& label_array)
957 {
958   OrdinalType i, len = v.length();
959   if (label_array.size() != len) {
960     Cerr << "Error: size of label_array in write_data_annotated(std::ostream) "
961 	 << "does not equal length of SerialDenseVector." << std::endl;
962     abort_handler(-1);
963   }
964   s << len << ' ' << std::scientific << std::setprecision(write_precision);
965   for (i=0; i<len; ++i)
966     s << v[i] << ' ' << label_array[i] << ' ';
967 }
968 
969 
970 /// annotated ostream insertion operator for StringMultiArray with labels
write_data_annotated(std::ostream & s,const StringMultiArray & v,StringMultiArrayConstView label_array)971 inline void write_data_annotated(std::ostream& s, const StringMultiArray& v,
972 				 StringMultiArrayConstView label_array)
973 {
974   size_t i, len = v.size();
975   if (label_array.size() != len) {
976     Cerr << "Error: size of label_array in write_data_annotated(std::ostream) "
977 	 << "does not equal length of StringMultiArray." << std::endl;
978     abort_handler(-1);
979   }
980   s << len << ' ';// << std::scientific << std::setprecision(write_precision);
981   for (i=0; i<len; ++i)
982     s << v[i] << ' ' << label_array[i] << ' ';
983 }
984 
985 
986 /// tabular ostream insertion operator for full SerialDenseVector
987 template <typename OrdinalType, typename ScalarType>
write_data_tabular(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v)988 void write_data_tabular(std::ostream& s,
989   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v)
990 {
991   OrdinalType i, len = v.length();
992   s << std::setprecision(write_precision)
993     << std::resetiosflags(std::ios::floatfield);
994   for (i=0; i<len; ++i)
995     s << std::setw(write_precision+4) << v[i] << ' ';
996 }
997 
998 
999 /// tabular ostream insertion operator for pointer
1000 template <typename OrdinalType, typename ScalarType>
write_data_tabular(std::ostream & s,const ScalarType * ptr,OrdinalType num_items)1001 void write_data_tabular(std::ostream& s, const ScalarType* ptr,
1002 			OrdinalType num_items)
1003 {
1004   s << std::setprecision(write_precision)
1005     << std::resetiosflags(std::ios::floatfield);
1006   for (OrdinalType i=0; i<num_items; ++i)
1007     s << std::setw(write_precision+4) << ptr[i] << ' ';
1008 }
1009 
1010 
1011 /// tabular ostream insertion operator for partial SerialDenseVector
1012 template <typename OrdinalType1, typename OrdinalType2, typename ScalarType>
write_data_partial_tabular(std::ostream & s,OrdinalType2 start_index,OrdinalType2 num_items,const Teuchos::SerialDenseVector<OrdinalType1,ScalarType> & v)1013 void write_data_partial_tabular(std::ostream& s,
1014   OrdinalType2 start_index, OrdinalType2 num_items,
1015   const Teuchos::SerialDenseVector<OrdinalType1, ScalarType>& v)
1016 {
1017   OrdinalType2 end = start_index + num_items;
1018   if (end > v.length()) {
1019     Cerr << "Error: indexing in write_data_partial_tabular(std::ostream) "
1020 	 << "exceeds length of SerialDenseVector." << std::endl;
1021     abort_handler(-1);
1022   }
1023   s << std::setprecision(write_precision)
1024     << std::resetiosflags(std::ios::floatfield);
1025   for (OrdinalType2 i=start_index; i<end; ++i)
1026     s << std::setw(write_precision+4) << v[i] << ' ';
1027 }
1028 
1029 
1030 /// tabular ostream insertion operator for partial StringMultiArray (const &)
1031 template <typename OrdinalType>
write_data_partial_tabular(std::ostream & s,OrdinalType start_index,OrdinalType num_items,const StringMultiArray & v)1032 void write_data_partial_tabular(std::ostream& s,
1033   OrdinalType start_index, OrdinalType num_items, const StringMultiArray& v)
1034 {
1035   OrdinalType end = start_index + num_items;
1036   if (end > v.size()) {
1037     Cerr << "Error: indexing in write_data_partial_tabular(std::ostream) "
1038 	 << "exceeds length of StringMultiArray." << std::endl;
1039     abort_handler(-1);
1040   }
1041   //s << std::setprecision(write_precision)
1042   //  << std::resetiosflags(std::ios::floatfield);
1043   for (OrdinalType i=start_index; i<end; ++i)
1044     s << std::setw(write_precision+4) << v[i] << ' ';
1045 }
1046 
1047 
1048 // BMA: Implementation accepting a const_array_view since can't
1049 // convert to const& prototype above.  Could convert const & to a view
1050 // and pass to this function to have a single implementation...
1051 
1052 /// tabular ostream insertion operator for partial StringMultiArray (const view)
1053 template <typename OrdinalType>
write_data_partial_tabular(std::ostream & s,OrdinalType start_index,OrdinalType num_items,StringMultiArrayConstView v)1054 void write_data_partial_tabular(std::ostream& s,
1055   OrdinalType start_index, OrdinalType num_items, StringMultiArrayConstView v)
1056 {
1057   OrdinalType end = start_index + num_items;
1058   if (end > v.size()) {
1059     Cerr << "Error: indexing in write_data_partial_tabular(std::ostream) "
1060 	 << "exceeds length of StringMultiArray." << std::endl;
1061     abort_handler(-1);
1062   }
1063   //s << std::setprecision(write_precision)
1064   //  << std::resetiosflags(std::ios::floatfield);
1065   for (OrdinalType i=start_index; i<end; ++i)
1066     s << std::setw(write_precision+4) << v[i] << ' ';
1067 }
1068 
1069 
1070 /// tabular ostream insertion operator for vector of strings
write_data_tabular(std::ostream & s,const StringArray & sa)1071 inline void write_data_tabular(std::ostream& s, const StringArray& sa)
1072 {
1073   s << std::setprecision(write_precision)
1074     << std::resetiosflags(std::ios::floatfield);
1075   size_t size_sa = sa.size();
1076   for (size_t i=0; i<size_sa; ++i)
1077     s << std::setw(write_precision+4) << sa[i] << ' ';
1078 }
1079 
1080 
1081 /// tabular ostream insertion operator for view of StringMultiArray
write_data_tabular(std::ostream & s,StringMultiArrayConstView ma)1082 inline void write_data_tabular(std::ostream& s, StringMultiArrayConstView ma)
1083 {
1084   s << std::setprecision(write_precision)
1085     << std::resetiosflags(std::ios::floatfield);
1086   size_t size_ma = ma.size();
1087   for (size_t i=0; i<size_ma; ++i)
1088     s << std::setw(write_precision+4) << ma[i] << ' ';
1089 }
1090 
1091 
1092 /// formatted ostream insertion operator for SerialDenseMatrix
1093 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)1094 void write_data(std::ostream& s,
1095                 const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& m,
1096                 bool brackets = true, bool row_rtn = true,
1097 		bool final_rtn = true)
1098 {
1099   OrdinalType i, j, nrows = m.numRows(), ncols = m.numCols();
1100   s << std::scientific << std::setprecision(write_precision);
1101   if (brackets) s << "[[ ";
1102   else          s << "   ";
1103   for (i=0; i<nrows; ++i) {
1104     for (j=0; j<ncols; ++j)
1105       s << std::setw(write_precision+7) << m(i,j) << ' ';
1106     // NOTE: newlines on every 4th component (as in the row vector case)
1107     // could lead to ambiguity in the matrix case.
1108     if (row_rtn && i!=m.numRows()-1)
1109       s << "\n   ";
1110   }
1111   if (brackets)  s << "]] ";
1112   if (final_rtn) s << '\n';
1113 }
1114 
1115 
1116 /// formatted ostream insertion operator for SerialSymDenseMatrix
1117 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)1118 void write_data(std::ostream& s,
1119                 const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& m,
1120                 bool brackets = true, bool row_rtn = true,
1121 		bool final_rtn = true)
1122 {
1123   OrdinalType i, j, nrows = m.numRows();
1124   s << std::scientific << std::setprecision(write_precision);
1125   if (brackets) s << "[[ ";
1126   else          s << "   ";
1127   for (i=0; i<nrows; ++i) {
1128     for (j=0; j<nrows; ++j)
1129       s << std::setw(write_precision+7) << m(i,j) << ' ';
1130     // NOTE: newlines on every 4th component (as in the row vector case)
1131     // could lead to ambiguity in the matrix case.
1132     if (row_rtn && i!=nrows-1)
1133       s << "\n   ";
1134   }
1135   if (brackets)  s << "]] ";
1136   if (final_rtn) s << '\n';
1137 }
1138 
1139 
1140 /// ostream insertion operator for SerialDenseMatrix with row/col labels
1141 template <typename OrdinalType, typename ScalarType>
write_data(std::ostream & s,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & m,const StringArray & row_labels,const StringArray & col_labels)1142 void write_data(std::ostream& s,
1143                 const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& m,
1144                 const StringArray& row_labels, const StringArray& col_labels)
1145 {
1146   OrdinalType i, j, nrows = m.numRows(), ncols = m.numCols();
1147   s << std::scientific << std::setprecision(write_precision)
1148     << "                 ";
1149   for (j=0; j<ncols; ++j)
1150     s << std::setw(write_precision+7) << col_labels[j] << ' ';
1151   s << '\n';
1152   for (i=0; i<nrows; ++i) {
1153     s << std::setw(15) << row_labels[i] << "  ";
1154     for (j=0; j<ncols; ++j)
1155       s << std::setw(write_precision+7) << m(i,j) << ' ';
1156     s << '\n';
1157   }
1158 }
1159 
1160 
1161 /// ostream version for writing the lower triangle of a SerialSymDenseMatrix
1162 template <typename OrdinalType, typename ScalarType>
write_lower_triangle(std::ostream & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & sm,bool row_rtn=true)1163 void write_lower_triangle(std::ostream& s,
1164   const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& sm,
1165   bool row_rtn = true)
1166 {
1167   OrdinalType i, j, nrows = sm.numRows();
1168   s << std::scientific << std::setprecision(write_precision);
1169   for (i=0; i<nrows; ++i) {
1170     for (j=0; j<=i; ++j)
1171       s << std::setw(write_precision+7) << sm(i,j) << ' ';
1172     if (row_rtn)
1173       s << '\n';
1174   }
1175 }
1176 
1177 
1178 /// generic output stream template for writing the lower triangle of a
1179 /// SerialSymDenseMatrix
1180 template <typename OStreamType, typename OrdinalType, typename ScalarType>
write_lower_triangle(OStreamType & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & sm)1181 void write_lower_triangle(OStreamType& s,
1182   const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& sm)
1183 {
1184   OrdinalType i, j, nrows = sm.numRows();
1185   for (i=0; i<nrows; ++i)
1186     for (j=0; j<=i; ++j)
1187       s << sm(i,j);
1188 }
1189 
1190 
1191 /// ostream insertion operator for a column vector from a SerialDenseMatrix
1192 template <typename OrdinalType, typename ScalarType>
write_col_vector_trans(std::ostream & s,OrdinalType col,OrdinalType num_items,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm,bool brackets=true,bool break_line=true,bool final_rtn=true)1193 void write_col_vector_trans(std::ostream& s, OrdinalType col,
1194   OrdinalType num_items,
1195   const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType>& sdm,
1196   bool brackets = true, bool break_line = true, bool final_rtn = true)
1197 {
1198   s << std::scientific << std::setprecision(write_precision);
1199   if (brackets) s << " [ ";
1200   else          s << "   ";
1201   for (OrdinalType row=0; row < num_items; ++row) {
1202     s << std::setw(write_precision+7) << sdm(row,col) << ' ';
1203     if (break_line && (row+1)%4 == 0)
1204       s << "\n   "; // Output 4 gradient components per line
1205   }
1206   if (brackets)  s << "] ";
1207   if (final_rtn) s << '\n';
1208 }
1209 
1210 
1211 /// ostream insertion operator for a column vector from a SerialDenseMatrix
1212 template <typename OrdinalType, typename ScalarType>
write_col_vector_trans(std::ostream & s,OrdinalType col,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm,bool brackets=true,bool break_line=true,bool final_rtn=true)1213 void write_col_vector_trans(std::ostream& s, OrdinalType col,
1214   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm,
1215   bool brackets = true, bool break_line = true, bool final_rtn = true)
1216 {
1217   write_col_vector_trans(s, col, sdm.numRows(), sdm, brackets, break_line,
1218                          final_rtn);
1219 }
1220 
1221 
1222 /// ostream insertion operator for a column vector from a SerialDenseMatrix
1223 template <typename OStreamType, typename OrdinalType, typename ScalarType>
write_col_vector_trans(OStreamType & s,OrdinalType col,OrdinalType num_items,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm)1224 void write_col_vector_trans(OStreamType& s, OrdinalType col,
1225   OrdinalType num_items,
1226   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm)
1227 { for (OrdinalType row=0; row < num_items; ++row) s << sdm(row,col); }
1228 
1229 
1230 /// ostream insertion operator for a column vector from a SerialDenseMatrix
1231 template <typename OStreamType, typename OrdinalType, typename ScalarType>
write_col_vector_trans(OStreamType & s,OrdinalType col,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & sdm)1232 void write_col_vector_trans(OStreamType& s, OrdinalType col,
1233   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& sdm)
1234 { write_col_vector_trans(s, col, sdm.numRows(), sdm); }
1235 
1236 
1237 /// write array to std::ostream
1238 template <typename ArrayT>
array_write(std::ostream & s,const ArrayT & v)1239 inline void array_write(std::ostream& s, const ArrayT& v)
1240 {
1241   s << std::scientific << std::setprecision(write_precision);
1242   typename ArrayT::size_type len = v.size();
1243   for (typename ArrayT::size_type i=0; i<len; ++i)
1244     s << "                     " << std::setw(write_precision+7)
1245       << v[i] << '\n';
1246 }
1247 
1248 
1249 /// write array to std::ostream with labels
1250 template <typename ArrayT>
array_write(std::ostream & s,const ArrayT & v,const std::vector<String> & label_array)1251 inline void array_write(std::ostream& s, const ArrayT& v,
1252                         const std::vector<String>& label_array)
1253 {
1254   s << std::scientific << std::setprecision(write_precision);
1255   typename ArrayT::size_type len = v.size();
1256   if (label_array.size() != len) {
1257     Cerr << "Error: size of label_array in vector<T>::write() does not equal "
1258 	 << "length of vector." << std::endl;
1259     abort_handler(-1);
1260   }
1261   for (typename ArrayT::size_type i=0; i<len; ++i)
1262     s << "                     " << std::setw(write_precision+7)
1263       << v[i] << ' ' << label_array[i] << '\n';
1264 }
1265 
1266 
1267 /// write array to std::ostream (APREPRO format)
1268 /// specialize for StringArray: values need quoting
array_write_aprepro(std::ostream & s,const StringArray & v,const std::vector<String> & label_array)1269 inline void array_write_aprepro(std::ostream& s, const StringArray& v,
1270                                 const std::vector<String>& label_array)
1271 {
1272   s << std::scientific << std::setprecision(write_precision);
1273   StringArray::size_type len = v.size();
1274   if (label_array.size() != len) {
1275     Cerr << "Error: size of label_array in vector<T>::write() does not equal "
1276 	 << "length of vector." << std::endl;
1277     abort_handler(-1);
1278   }
1279   for (StringArray::size_type i=0; i<len; ++i)
1280     s << "                    { "
1281       << std::setw(15) << std::setiosflags(std::ios::left)
1282       << label_array[i].c_str() << std::resetiosflags(std::ios::adjustfield)
1283       << " = " << std::setw(write_precision+7)
1284       << '"' << v[i] << '"' << " }\n";
1285 }
1286 
1287 
1288 /// write array to std::ostream (APREPRO format)
1289 template <typename ArrayT>
array_write_aprepro(std::ostream & s,const ArrayT & v,const std::vector<String> & label_array)1290 inline void array_write_aprepro(std::ostream& s, const ArrayT& v,
1291                                 const std::vector<String>& label_array)
1292 {
1293   s << std::scientific << std::setprecision(write_precision);
1294   typename ArrayT::size_type len = v.size();
1295   if (label_array.size() != len) {
1296     Cerr << "Error: size of label_array in vector<T>::write() does not equal "
1297 	 << "length of vector." << std::endl;
1298     abort_handler(-1);
1299   }
1300   for (typename ArrayT::size_type i=0; i<len; ++i)
1301     s << "                    { "
1302       << std::setw(15) << std::setiosflags(std::ios::left)
1303       << label_array[i].c_str() << std::resetiosflags(std::ios::adjustfield)
1304       << " = " << std::setw(write_precision+7)
1305       << v[i] << " }\n";
1306 }
1307 
1308 
1309 // WJB: confer with MSE -- e.g. desired API? naming style of read/write funcs,
1310 //                              order of the argument list; mv to data_io.h??
1311 /// Write array to ostream as a row vector; precede with length if
1312 /// write_len = true
1313 template <typename ArrayT>
array_write_annotated(std::ostream & s,const ArrayT & v,bool write_len)1314 inline void array_write_annotated(std::ostream& s, const ArrayT& v,
1315 				  bool write_len)
1316 {
1317   s << std::scientific << std::setprecision(write_precision);
1318   typename ArrayT::size_type len = v.size();
1319   if (write_len)
1320     s << len << ' ';
1321   for (typename ArrayT::size_type i=0; i<len; ++i)
1322     s << v[i] << ' ';
1323 }
1324 
1325 
1326 // ----------------------------------------
1327 // templated MPIUnpackBuffer read functions
1328 // ----------------------------------------
1329 
1330 
1331 /// standard MPI buffer extraction operator for full SerialDenseVector
1332 /// with labels
1333 template <typename OrdinalType, typename ScalarType>
read_data(MPIUnpackBuffer & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArray & label_array)1334 void read_data(MPIUnpackBuffer& s,
1335 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
1336 	       StringMultiArray& label_array)
1337 {
1338   OrdinalType i, len;
1339   s >> len;
1340   if( len != v.length() )
1341     v.sizeUninitialized(len);
1342   if( len != label_array.size() )
1343     label_array.resize(boost::extents[len]);
1344   for (i=0; i<len; ++i)
1345     s >> v[i] >> label_array[i];
1346 }
1347 
1348 
1349 /// standard MPI buffer extraction operator for full SerialDenseVector
1350 /// with labels
1351 template <typename OrdinalType, typename ScalarType>
read_data(MPIUnpackBuffer & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,StringMultiArrayView label_array)1352 void read_data(MPIUnpackBuffer& s,
1353 	       Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
1354 	       StringMultiArrayView label_array)
1355 {
1356   OrdinalType i, len;
1357   s >> len;
1358   if( len != v.length() )
1359     v.sizeUninitialized(len);
1360   if( len != label_array.size() ) {
1361     Cerr << "Error: size of label_array in read_data(MPIUnpackBuffer&) does "
1362 	 << "not equal length of SerialDenseVector." << std::endl;
1363     abort_handler(-1);
1364   }
1365   for (i=0; i<len; ++i)
1366     s >> v[i] >> label_array[i];
1367 }
1368 
1369 
1370 /// standard MPI buffer extraction operator for StringMultiArray with labels
read_data(MPIUnpackBuffer & s,StringMultiArray & v,StringMultiArrayView label_array)1371 inline void read_data(MPIUnpackBuffer& s, StringMultiArray& v,
1372 		      StringMultiArrayView label_array)
1373 {
1374   size_t i, len;
1375   s >> len;
1376   if( len != v.size() )
1377     v.resize(boost::extents[len]);
1378   if( len != label_array.size() ) {
1379     Cerr << "Error: size of label_array in read_data(MPIUnpackBuffer&) does "
1380 	 << "not equal length of StringMultiArray." << std::endl;
1381     abort_handler(-1);
1382   }
1383   for (i=0; i<len; ++i)
1384     s >> v[i] >> label_array[i];
1385 }
1386 
1387 
1388 // ---------------------------------------
1389 // templated MPIPackBuffer write functions (in namespace Dakota)
1390 // ---------------------------------------
1391 
1392 
1393 /// standard MPI buffer insertion operator for full SerialDenseVector
1394 /// with labels
1395 template <typename OrdinalType, typename ScalarType>
write_data(MPIPackBuffer & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & v,const StringMultiArray & label_array)1396 void write_data(MPIPackBuffer& s,
1397 		const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& v,
1398 		const StringMultiArray& label_array)
1399 {
1400   OrdinalType i, len = v.length();
1401   if (label_array.size() != len) {
1402     Cerr << "Error: size of label_array in write_data(MPIPackBuffer) "
1403 	 << "does not equal length of SerialDenseVector." << std::endl;
1404     abort_handler(-1);
1405   }
1406   s << len;
1407   for (i=0; i<len; ++i)
1408     s << v[i] << label_array[i];
1409 }
1410 
1411 
1412 /// standard MPI buffer insertion operator for StringMultiArray with labels
write_data(MPIPackBuffer & s,const StringMultiArray & v,StringMultiArrayConstView label_array)1413 inline void write_data(MPIPackBuffer& s, const StringMultiArray& v,
1414 		       StringMultiArrayConstView label_array)
1415 {
1416   size_t i, len = v.size();
1417   if (label_array.size() != len) {
1418     Cerr << "Error: size of label_array in write_data(MPIPackBuffer) "
1419 	 << "does not equal length of StringMultiArray." << std::endl;
1420     abort_handler(-1);
1421   }
1422   s << len;
1423   for (i=0; i<len; ++i)
1424     s << v[i] << label_array[i];
1425 }
1426 
1427 
1428 // ----------------------------------------------------------------------------
1429 // templated MPIPackBuffer insertion/extraction operators (in namespace Dakota)
1430 // ----------------------------------------------------------------------------
1431 
1432 
1433 /// global MPIUnpackBuffer extraction operator for std::pair
1434 template <typename U, typename V>
operator >>(MPIUnpackBuffer & s,std::pair<U,V> & data)1435 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s, std::pair<U,V>& data)
1436 {
1437   U first; V second;
1438   s >> first >> second;
1439   data.first = first; data.second = second;
1440   return s;
1441 }
1442 
1443 
1444 /// global MPIPackBuffer insertion operator for std::pair
1445 template <typename U, typename V>
operator <<(MPIPackBuffer & s,const std::pair<U,V> & data)1446 MPIPackBuffer& operator<<(MPIPackBuffer& s, const std::pair<U,V>& data)
1447 {
1448   s << data.first << data.second;
1449   return s;
1450 }
1451 
1452 
1453 /*
1454 /// global MPIUnpackBuffer extraction operator for std::vector
1455 /// (specialization of ContainerT template in MPIPackBuffer.hpp)
1456 template <typename T>
1457 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s, std::vector<T>& data)
1458 {
1459   size_t i, len;
1460   s >> len;
1461   data.resize(len);
1462   for (i=0; i<len; ++i)
1463     s >> data[i];
1464   return s;
1465 }
1466 
1467 
1468 /// global MPIPackBuffer insertion operator for std::vector
1469 /// (specialization of ContainerT template in MPIPackBuffer.hpp)
1470 template <typename T>
1471 MPIPackBuffer& operator<<(MPIPackBuffer& s, const std::vector<T>& data)
1472 {
1473   size_t i, len = data.size();
1474   s << len;
1475   for (i=0; i<len; ++i)
1476     s << data[i];
1477   return s;
1478 }
1479 */
1480 
1481 
1482 /// global MPIUnpackBuffer extraction operator for std::set
1483 template <typename T>
operator >>(MPIUnpackBuffer & s,std::set<T> & data)1484 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s, std::set<T>& data)
1485 {
1486   data.clear();
1487   size_t i, len;
1488   s >> len;
1489   T val;
1490   for (i=0; i<len; ++i){
1491     s >> val;
1492     data.insert(val);
1493   }
1494   return s;
1495 }
1496 
1497 
1498 /// global MPIPackBuffer insertion operator for std::set
1499 template <typename T>
operator <<(MPIPackBuffer & s,const std::set<T> & data)1500 MPIPackBuffer& operator<<(MPIPackBuffer& s, const std::set<T>& data)
1501 {
1502   size_t len = data.size();
1503   s << len;
1504   for (typename std::set<T>::const_iterator cit = data.begin();
1505        cit != data.end(); ++cit)
1506     s << *cit;
1507   return s;
1508 }
1509 
1510 
1511 /// global MPIUnpackBuffer extraction operator for std::map
1512 template <typename KeyT, typename ValueT>
operator >>(MPIUnpackBuffer & s,std::map<KeyT,ValueT> & data)1513 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s, std::map<KeyT, ValueT>& data)
1514 {
1515   data.clear();
1516   size_t i, len; KeyT key; ValueT val;
1517   s >> len;
1518   for (i=0; i<len; ++i){
1519     s >> key >> val;
1520     data[key] = val;
1521   }
1522   return s;
1523 }
1524 
1525 
1526 /// global MPIPackBuffer insertion operator for std::map
1527 template <typename KeyT, typename ValueT>
operator <<(MPIPackBuffer & s,const std::map<KeyT,ValueT> & data)1528 MPIPackBuffer& operator<<(MPIPackBuffer& s, const std::map<KeyT, ValueT>& data)
1529 {
1530   size_t len = data.size();
1531   s << len;
1532   for (typename std::map<KeyT, ValueT>::const_iterator cit = data.begin();
1533        cit != data.end(); ++cit)
1534     s << cit->first << cit->second;
1535   return s;
1536 }
1537 
1538 
1539 /// global MPIPackBuffer insertion operator for Teuchos::SerialDenseVector
1540 template <typename OrdinalType, typename ScalarType>
operator <<(MPIPackBuffer & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & data)1541 MPIPackBuffer& operator<<(MPIPackBuffer& s,
1542   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data)
1543 {
1544   OrdinalType i, n = data.length();
1545   s << n;
1546   for (i=0; i<n; ++i)
1547     s << data[i];
1548   return s;
1549 }
1550 
1551 
1552 /// global MPIPackBuffer insertion operator for Teuchos::SerialDenseMatrix
1553 template <typename OrdinalType, typename ScalarType>
operator <<(MPIPackBuffer & s,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & data)1554 MPIPackBuffer& operator<<(MPIPackBuffer& s,
1555   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data)
1556 {
1557   OrdinalType i, j, n = data.numRows(), m = data.numCols();
1558   s << n << m;
1559   for (i=0; i<n; ++i)
1560     for (j=0; j<m; ++j)
1561       s << data(i,j);
1562   return s;
1563 }
1564 
1565 
1566 /// global MPIPackBuffer insertion operator for Teuchos::SerialSymDenseMatrix
1567 template <typename OrdinalType, typename ScalarType>
operator <<(MPIPackBuffer & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & data)1568 MPIPackBuffer& operator<<(MPIPackBuffer& s,
1569   const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data)
1570 {
1571   OrdinalType i, j, n = data.numRows();
1572   s << n;
1573   for (i=0; i<n; ++i)
1574     for (j=0; j<=i; ++j)
1575       s << data(i,j);
1576   return s;
1577 }
1578 
1579 
1580 /// global MPIUnpackBuffer extraction operator for Teuchos::SerialDenseVector
1581 template <typename OrdinalType, typename ScalarType>
operator >>(MPIUnpackBuffer & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & data)1582 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s,
1583   Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data)
1584 {
1585   OrdinalType i, n;
1586   s >> n;
1587   data.sizeUninitialized(n);
1588   for(i=0; i<n; ++i)
1589     s >> data[i];
1590   return s;
1591 }
1592 
1593 
1594 /// global MPIUnpackBuffer extraction operator for Teuchos::SerialDenseMatrix
1595 template <typename OrdinalType, typename ScalarType>
operator >>(MPIUnpackBuffer & s,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & data)1596 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s,
1597   Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data)
1598 {
1599   OrdinalType i, j, n, m;
1600   s >> n >> m;
1601   data.shapeUninitialized(n, m);
1602   for (i=0; i<n; ++i)
1603     for (j=0; j<m; ++j)
1604       s >> data(i,j);
1605   return s;
1606 }
1607 
1608 
1609 /// global MPIUnpackBuffer extraction operator for Teuchos::SerialSymDenseMatrix
1610 template <typename OrdinalType, typename ScalarType>
operator >>(MPIUnpackBuffer & s,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & data)1611 MPIUnpackBuffer& operator>>(MPIUnpackBuffer& s,
1612   Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data)
1613 {
1614   OrdinalType i, j, n;
1615   s >> n;
1616   data.shapeUninitialized(n);
1617   for (i=0; i<n; ++i)
1618     for (j=0; j<=i; ++j)
1619       s >> data(i,j);
1620   return s;
1621 }
1622 
1623 
1624 // -----------------------------------------------------------------------
1625 // templated iostream insertion/extraction operators (in namespace Dakota)
1626 // -----------------------------------------------------------------------
1627 
1628 
1629 /// global std::istream extraction operator for std::vector
1630 template <typename T>
operator >>(std::istream & s,std::vector<T> & data)1631 inline std::istream& operator>>(std::istream& s, std::vector<T>& data)
1632 { array_read(s, data); return s; }
1633 
1634 
1635 /// global std::ostream insertion operator for std::vector
1636 template <typename T>
operator <<(std::ostream & s,const std::vector<T> & data)1637 inline std::ostream& operator<<(std::ostream& s, const std::vector<T>& data)
1638 { array_write(s, data); return s; }
1639 
1640 
1641 /// global std::ostream insertion operator for std::list
1642 template <typename T>
operator <<(std::ostream & s,const std::list<T> & data)1643 inline std::ostream& operator<<(std::ostream& s, const std::list<T>& data)
1644 {
1645   for(const typename std::list<T>::value_type& entry : data)
1646     s << "                     " << entry << '\n';
1647   return s;
1648 }
1649 
1650 
1651 /// global ostream insertion operator for std::pair
1652 template <typename U, typename V>
operator <<(std::ostream & s,const std::pair<U,V> & data)1653 std::ostream& operator<<(std::ostream& s, const std::pair<U,V>& data)
1654 {
1655   size_t width = write_precision+7;
1656   s << "                     " << std::setw(width)
1657     << data.first << ' ' << data.second << '\n';
1658   return s;
1659 }
1660 
1661 
1662 /// global std::ostream insertion operator for std::set
1663 template <typename T>
operator <<(std::ostream & s,const std::set<T> & data)1664 std::ostream& operator<<(std::ostream& s, const std::set<T>& data)
1665 {
1666   size_t width = write_precision+7;
1667   for (typename std::set<T>::const_iterator cit = data.begin();
1668        cit != data.end(); ++cit)
1669     s << "                     " << std::setw(width) << *cit << '\n';
1670   return s;
1671 }
1672 
1673 
1674 /// global std::ostream insertion operator for std::map
1675 template <typename KeyT, typename ValueT>
operator <<(std::ostream & s,const std::map<KeyT,ValueT> & data)1676 std::ostream& operator<<(std::ostream& s, const std::map<KeyT, ValueT>& data)
1677 {
1678   size_t width = write_precision+7;
1679   for (typename std::map<KeyT, ValueT>::const_iterator cit = data.begin();
1680        cit != data.end(); ++cit)
1681     s << "                     " << std::setw(width) << cit->first
1682       << "  " << std::setw(width) << cit->second << '\n';
1683   return s;
1684 }
1685 
1686 
1687 /// global std::istream extraction operator for SerialDenseVector
1688 template <typename OrdinalType, typename ScalarType>
operator >>(std::istream & s,Teuchos::SerialDenseVector<OrdinalType,ScalarType> & data)1689 inline std::istream& operator>>(std::istream& s,
1690   Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data)
1691 { read_data(s, data); return s; }
1692 
1693 
1694 /// global std::ostream insertion operator for SerialDenseVector
1695 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialDenseVector<OrdinalType,ScalarType> & data)1696 inline std::ostream& operator<<(std::ostream& s,
1697   const Teuchos::SerialDenseVector<OrdinalType, ScalarType>& data)
1698 { write_data(s, data); return s; }
1699 
1700 
1701 /// global std::istream extraction operator for SerialDenseMatrix
1702 template <typename OrdinalType, typename ScalarType>
operator >>(std::istream & s,Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & data)1703 inline std::istream& operator>>(std::istream& s,
1704   Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data)
1705 { read_data(s, data); return s; }
1706 
1707 
1708 /// global std::ostream insertion operator for SerialDenseMatrix
1709 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialDenseMatrix<OrdinalType,ScalarType> & data)1710 inline std::ostream& operator<<(std::ostream& s,
1711   const Teuchos::SerialDenseMatrix<OrdinalType, ScalarType>& data)
1712 { write_data(s, data, true, true, true); return s; }
1713 
1714 
1715 /// global std::istream extraction operator for SerialSymDenseMatrix
1716 template <typename OrdinalType, typename ScalarType>
operator >>(std::istream & s,Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & data)1717 inline std::istream& operator>>(std::istream& s,
1718   Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data)
1719 { read_data(s, data); return s; }
1720 
1721 
1722 /// global std::ostream insertion operator for SerialSymDenseMatrix
1723 template <typename OrdinalType, typename ScalarType>
operator <<(std::ostream & s,const Teuchos::SerialSymDenseMatrix<OrdinalType,ScalarType> & data)1724 inline std::ostream& operator<<(std::ostream& s,
1725   const Teuchos::SerialSymDenseMatrix<OrdinalType, ScalarType>& data)
1726 { write_data(s, data, true, true, true); return s; }
1727 
1728 } // namespace Dakota
1729 
1730 #endif // DAKOTA_DATA_IO_H
1731