QMCPACK
VariableSet.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source License.
3 // See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2016 Jeongnim Kim and QMCPACK developers.
6 //
7 // File developed by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
8 // Jeremy McMinnis, jmcminis@gmail.com, University of Illinois at Urbana-Champaign
9 // Mark A. Berrill, berrillma@ornl.gov, Oak Ridge National Laboratory
10 //
11 // File created by: Jeongnim Kim, jeongnim.kim@gmail.com, University of Illinois at Urbana-Champaign
12 //////////////////////////////////////////////////////////////////////////////////////
13 
14 
15 #include "VariableSet.h"
16 #include "io/hdf/hdf_archive.h"
17 #include "Host/sysutil.h"
18 #include <map>
19 #include <stdexcept>
20 #include <iomanip>
21 #include <ios>
22 #include <algorithm>
23 
24 using std::setw;
25 
26 namespace optimize
27 {
29 {
30  num_active_vars = 0;
31  Index.clear();
32  NameAndValue.clear();
33  Recompute.clear();
34  ParameterType.clear();
35 }
36 
38 {
39  for (int i = 0; i < input.size(); ++i)
40  {
41  iterator loc = find(input.name(i));
42  if (loc == NameAndValue.end())
43  {
44  Index.push_back(input.Index[i]);
45  NameAndValue.push_back(input.NameAndValue[i]);
46  ParameterType.push_back(input.ParameterType[i]);
47  Recompute.push_back(input.Recompute[i]);
48  }
49  else
50  (*loc).second = input.NameAndValue[i].second;
51  }
52  num_active_vars = input.num_active_vars;
53 }
54 
55 void VariableSet::insertFromSum(const VariableSet& input_1, const VariableSet& input_2)
56 {
57  real_type sum_val;
58  std::string vname;
59 
60  // Check that objects to be summed together have the same number of active
61  // variables.
62  if (input_1.num_active_vars != input_2.num_active_vars)
63  throw std::runtime_error("Inconsistent number of parameters in two provided "
64  "variable sets.");
65 
66  for (int i = 0; i < input_1.size(); ++i)
67  {
68  // Check that each of the equivalent variables in both VariableSet objects
69  // have the same name - otherwise we certainly shouldn't be adding them.
70  if (input_1.NameAndValue[i].first != input_2.NameAndValue[i].first)
71  throw std::runtime_error("Inconsistent parameters exist in the two provided "
72  "variable sets.");
73 
74  sum_val = input_1.NameAndValue[i].second + input_2.NameAndValue[i].second;
75 
76  iterator loc = find(input_1.name(i));
77  if (loc == NameAndValue.end())
78  {
79  Index.push_back(input_1.Index[i]);
80  ParameterType.push_back(input_1.ParameterType[i]);
81  Recompute.push_back(input_1.Recompute[i]);
82 
83  // We can reuse the above values, which aren't summed between the
84  // objects, but the parameter values themselves need to use the summed
85  // values.
86  vname = input_1.NameAndValue[i].first;
87  NameAndValue.push_back(pair_type(vname, sum_val));
88  }
89  else
90  (*loc).second = sum_val;
91  }
93 }
94 
95 void VariableSet::insertFromDiff(const VariableSet& input_1, const VariableSet& input_2)
96 {
97  real_type diff_val;
98  std::string vname;
99 
100  // Check that objects to be subtracted have the same number of active
101  // variables.
102  if (input_1.num_active_vars != input_2.num_active_vars)
103  throw std::runtime_error("Inconsistent number of parameters in two provided "
104  "variable sets.");
105 
106  for (int i = 0; i < input_1.size(); ++i)
107  {
108  // Check that each of the equivalent variables in both VariableSet objects
109  // have the same name - otherwise we certainly shouldn't be subtracting them.
110  if (input_1.NameAndValue[i].first != input_2.NameAndValue[i].first)
111  throw std::runtime_error("Inconsistent parameters exist in the two provided "
112  "variable sets.");
113 
114  diff_val = input_1.NameAndValue[i].second - input_2.NameAndValue[i].second;
115 
116  iterator loc = find(input_1.name(i));
117  if (loc == NameAndValue.end())
118  {
119  Index.push_back(input_1.Index[i]);
120  ParameterType.push_back(input_1.ParameterType[i]);
121  Recompute.push_back(input_1.Recompute[i]);
122 
123  // We can reuse the above values, which aren't subtracted between the
124  // objects, but the parameter values themselves need to use the
125  // subtracted values.
126  vname = input_1.NameAndValue[i].first;
127  NameAndValue.push_back(pair_type(vname, diff_val));
128  }
129  else
130  (*loc).second = diff_val;
131  }
133 }
134 
136 {
137  std::vector<int> valid(Index);
138  std::vector<pair_type> acopy(NameAndValue);
139  std::vector<index_pair_type> bcopy(Recompute), ccopy(ParameterType);
140  num_active_vars = 0;
141  Index.clear();
142  NameAndValue.clear();
143  Recompute.clear();
144  ParameterType.clear();
145  for (int i = 0; i < valid.size(); ++i)
146  {
147  if (valid[i] > -1)
148  {
149  Index.push_back(num_active_vars++);
150  NameAndValue.push_back(acopy[i]);
151  Recompute.push_back(bcopy[i]);
152  ParameterType.push_back(ccopy[i]);
153  }
154  }
155 }
156 
158 {
159  num_active_vars = 0;
160  for (int i = 0; i < Index.size(); ++i)
161  {
162  Index[i] = (Index[i] < 0) ? -1 : num_active_vars++;
163  }
164 }
165 
166 void VariableSet::getIndex(const VariableSet& selected)
167 {
168  num_active_vars = 0;
169  for (int i = 0; i < NameAndValue.size(); ++i)
170  {
171  Index[i] = selected.getIndex(NameAndValue[i].first);
172  if (Index[i] >= 0)
173  num_active_vars++;
174  }
175 }
176 
177 int VariableSet::getIndex(const std::string& vname) const
178 {
179  int loc = 0;
180  while (loc != NameAndValue.size())
181  {
182  if (NameAndValue[loc].first == vname)
183  return Index[loc];
184  ++loc;
185  }
186  return -1;
187 }
188 
190 {
191  for (int i = 0; i < Index.size(); ++i)
192  Index[i] = i;
193 }
194 
195 void VariableSet::print(std::ostream& os, int leftPadSpaces, bool printHeader) const
196 {
197  std::string pad_str = std::string(leftPadSpaces, ' ');
198  int max_name_len = 0;
199  if (NameAndValue.size() > 0)
200  max_name_len =
201  std::max_element(NameAndValue.begin(), NameAndValue.end(), [](const pair_type& e1, const pair_type& e2) {
202  return e1.first.length() < e2.first.length();
203  })->first.length();
204 
205  int max_value_len = 28; // 6 for the precision and 7 for minus sign, leading value, period, and exponent.
206  int max_type_len = 1;
207  int max_recompute_len = 1;
208  int max_use_len = 3;
209  int max_index_len = 1;
210  if (printHeader)
211  {
212  max_name_len = std::max(max_name_len, 4); // size of "Name" header
213  max_type_len = 4;
214  max_recompute_len = 9;
215  max_index_len = 5;
216  os << pad_str << setw(max_name_len) << "Name"
217  << " " << setw(max_value_len) << "Value"
218  << " " << setw(max_type_len) << "Type"
219  << " " << setw(max_recompute_len) << "Recompute"
220  << " " << setw(max_use_len) << "Use"
221  << " " << setw(max_index_len) << "Index" << std::endl;
222  os << pad_str << std::setfill('-') << setw(max_name_len) << ""
223  << " " << setw(max_value_len) << ""
224  << " " << setw(max_type_len) << ""
225  << " " << setw(max_recompute_len) << ""
226  << " " << setw(max_use_len) << ""
227  << " " << setw(max_index_len) << "" << std::endl;
228  os << std::setfill(' ');
229  }
230 
231  for (int i = 0; i < NameAndValue.size(); ++i)
232  {
233  os << pad_str << setw(max_name_len) << NameAndValue[i].first << " " << std::setprecision(6) << std::scientific
234  << setw(max_value_len) << NameAndValue[i].second << " " << setw(max_type_len) << ParameterType[i].second << " "
235  << setw(max_recompute_len) << Recompute[i].second << " ";
236 
237  os << std::defaultfloat;
238 
239  if (Index[i] < 0)
240  os << setw(max_use_len) << "OFF" << std::endl;
241  else
242  os << setw(max_use_len) << "ON"
243  << " " << setw(max_index_len) << Index[i] << std::endl;
244  }
245 }
246 
247 void VariableSet::writeToHDF(const std::string& filename, qmcplusplus::hdf_archive& hout) const
248 {
249  hout.create(filename);
250 
251  // File Versioning
252  // 1.0.0 Initial file version
253  // 1.1.0 Files could have object-specific data from OptimizableObject::read/writeVariationalParameters
254  std::vector<int> vp_file_version{1, 1, 0};
255  hout.write(vp_file_version, "version");
256 
257  std::string timestamp(getDateAndTime("%Y-%m-%d %H:%M:%S %Z"));
258  hout.write(timestamp, "timestamp");
259 
260  hout.push("name_value_lists");
261 
262  std::vector<qmcplusplus::QMCTraits::RealType> param_values;
263  std::vector<std::string> param_names;
264  for (auto& pair_it : NameAndValue)
265  {
266  param_names.push_back(pair_it.first);
267  param_values.push_back(pair_it.second);
268  }
269 
270  hout.write(param_names, "parameter_names");
271  hout.write(param_values, "parameter_values");
272  hout.pop();
273 }
274 
275 void VariableSet::readFromHDF(const std::string& filename, qmcplusplus::hdf_archive& hin)
276 {
277  if (!hin.open(filename, H5F_ACC_RDONLY))
278  {
279  std::ostringstream err_msg;
280  err_msg << "Unable to open VP file: " << filename;
281  throw std::runtime_error(err_msg.str());
282  }
283 
284  try
285  {
286  hin.push("name_value_lists", false);
287  }
288  catch (std::runtime_error&)
289  {
290  std::ostringstream err_msg;
291  err_msg << "The group name_value_lists in not present in file: " << filename;
292  throw std::runtime_error(err_msg.str());
293  }
294 
295  std::vector<qmcplusplus::QMCTraits::RealType> param_values;
296  hin.read(param_values, "parameter_values");
297 
298  std::vector<std::string> param_names;
299  hin.read(param_names, "parameter_names");
300 
301  for (int i = 0; i < param_names.size(); i++)
302  {
303  std::string& vp_name = param_names[i];
304  // Find and set values by name.
305  // Values that are not present do not get added.
306  if (find(vp_name) != end())
307  (*this)[vp_name] = param_values[i];
308  }
309 
310  hin.pop();
311 }
312 
313 
314 } // namespace optimize
iterator find(const std::string &vname)
return the iterator of a named parameter
Definition: VariableSet.h:98
void writeToHDF(const std::string &filename, qmcplusplus::hdf_archive &hout) const
void write(T &data, const std::string &aname)
write the data to the group aname and check status runtime error is issued on I/O error ...
Definition: hdf_archive.h:259
bool open(const std::filesystem::path &fname, unsigned flags=H5F_ACC_RDWR)
open a file
void setIndexDefault()
set default Indices, namely all the variables are active
const_iterator end() const
return the last const_iterator
Definition: VariableSet.h:82
string getDateAndTime()
Definition: sysutil.cpp:31
std::vector< pair_type >::iterator iterator
Definition: VariableSet.h:55
void readFromHDF(const std::string &filename, qmcplusplus::hdf_archive &hin)
Read variational parameters from an HDF file.
std::vector< int > Index
store locator of the named variable
Definition: VariableSet.h:65
class to handle hdf file
Definition: hdf_archive.h:51
void resetIndex()
reset Index
void insertFromDiff(const VariableSet &input_1, const VariableSet &input_2)
take the difference (input_1-input_2) of values of the optimizable parameter values in two VariableSe...
Definition: VariableSet.cpp:95
std::pair< std::string, real_type > pair_type
Definition: VariableSet.h:53
class to handle a set of variables that can be modified during optimizations
Definition: VariableSet.h:49
void clear()
clear the variable set
Definition: VariableSet.cpp:28
size_type size() const
return the size
Definition: VariableSet.h:88
void insertFromSum(const VariableSet &input_1, const VariableSet &input_2)
sum together the values of the optimizable parameter values in two VariableSet objects, and set this object&#39;s values to equal them.
Definition: VariableSet.cpp:55
void push(const std::string &gname, bool createit=true)
push a group to the group stack
bool create(const std::filesystem::path &fname, unsigned flags=H5F_ACC_TRUNC)
create a file
std::vector< pair_type > NameAndValue
Definition: VariableSet.h:66
qmcplusplus::QMCTraits::RealType real_type
Definition: VariableSet.h:51
const std::string & name(int i) const
return the name of i-th variable
Definition: VariableSet.h:189
std::vector< index_pair_type > ParameterType
Definition: VariableSet.h:67
void read(T &data, const std::string &aname)
read the data from the group aname and check status runtime error is issued on I/O error ...
Definition: hdf_archive.h:306
void insertFrom(const VariableSet &input)
insert a VariableSet to the list
Definition: VariableSet.cpp:37
testing::ValidSpinDensityInput input
void removeInactive()
remove inactive variables and trim the internal data
void print(std::ostream &os, int leftPadSpaces=0, bool printHeader=false) const
int getIndex(const std::string &vname) const
return the Index vaule for the named parameter
std::vector< index_pair_type > Recompute
Definition: VariableSet.h:68
int num_active_vars
number of active variables
Definition: VariableSet.h:60