Doxygen 1.9.1
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2 (development)
tsgCandidateManager.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Miroslav Stoyanov
3  *
4  * This file is part of
5  * Toolkit for Adaptive Stochastic Modeling And Non-Intrusive ApproximatioN: TASMANIAN
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
12  * and the following disclaimer in the documentation and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * UT-BATTELLE, LLC AND THE UNITED STATES GOVERNMENT MAKE NO REPRESENTATIONS AND DISCLAIM ALL WARRANTIES, BOTH EXPRESSED AND IMPLIED.
25  * THERE ARE NO EXPRESS OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY PATENT,
26  * COPYRIGHT, TRADEMARK, OR OTHER PROPRIETARY RIGHTS, OR THAT THE SOFTWARE WILL ACCOMPLISH THE INTENDED RESULTS OR THAT THE SOFTWARE OR ITS USE WILL NOT RESULT IN INJURY OR DAMAGE.
27  * THE USER ASSUMES RESPONSIBILITY FOR ALL LIABILITIES, PENALTIES, FINES, CLAIMS, CAUSES OF ACTION, AND COSTS AND EXPENSES, CAUSED BY, RESULTING FROM OR ARISING OUT OF,
28  * IN WHOLE OR IN PART THE USE, STORAGE OR DISPOSAL OF THE SOFTWARE.
29  */
30 
31 #ifndef __TASMANIAN_ADDONS_CMANAGER_HPP
32 #define __TASMANIAN_ADDONS_CMANAGER_HPP
33 
45 #include "tsgAddonsCommon.hpp"
46 
59 namespace TasGrid{
60 
71 protected:
73  enum TypeStatus{ free, running, done };
74 public:
76  template<typename IntTypeDim, typename IntTypeBatch>
77  CandidateManager(IntTypeDim dimensions, IntTypeBatch batch_size) : num_dimensions(static_cast<size_t>(dimensions)),
78  num_batch(batch_size), num_candidates(0), num_running(0), num_done(0){}
81 
89  void operator=(std::vector<double> &&new_candidates){
90  candidates = std::move(new_candidates);
91  num_candidates = candidates.size() / num_dimensions;
92  num_done = 0;
93  if (num_candidates == 0) return;
94 
96  status.resize(num_candidates);
97  std::fill(status.begin(), status.end(), free);
98  for(auto const &p : running_jobs){
99  size_t i = find(p.data());
100  if (i < num_candidates) status[sorted[i]] = running;
101  }
102  }
103 
105  void complete(std::vector<double> const &p){
106  size_t num_complete = p.size() / num_dimensions;
107  num_done += num_complete;
108  num_running -= num_complete;
109 
110  for(auto ip = p.begin(); ip != p.end(); std::advance(ip, num_dimensions)){
111  auto i = find(&*ip);
112  // there is a scenario where a point is checked out
113  // then while computing another point is done which changes the surpluses
114  // and then the checked out point is no longer a candidate
115  if (i < num_candidates) status[sorted[i]] = done;
116  }
117 
118  // takes an iterator and returns an iterator to the next entry
119  auto inext = [](std::forward_list<std::vector<double>>::iterator ib)->
120  std::forward_list<std::vector<double>>::iterator{
121  return ++ib;
122  };
123 
124  for(size_t i=0; i<num_complete; i++){
125  auto ib = running_jobs.before_begin();
126  while(not match(&p[i * num_dimensions], inext(ib)->data())) ib++;
127  running_jobs.erase_after(ib);
128  }
129  }
130 
132  std::vector<double> next(size_t remaining_budget){
133  size_t this_batch = std::min(remaining_budget, num_batch);
134  size_t i = 0;
135  while((i < num_candidates) && (status[i] != free)) i++;
136  if (i == num_candidates) return std::vector<double>();
137  num_running++;
138  status[i] = running;
139  std::vector<double> result(&candidates[i*num_dimensions], &candidates[i*num_dimensions] + num_dimensions);
140  running_jobs.push_front(result);
141 
142  size_t num_next = 1;
143  while((i < num_candidates) && (num_next < this_batch)){
144  while((i < num_candidates) && (status[i] != free)) i++;
145  if (i < num_candidates){
146  running_jobs.push_front(std::vector<double>(&candidates[i*num_dimensions], &candidates[i*num_dimensions] + num_dimensions));
147  result.insert(result.end(), &candidates[i*num_dimensions], &candidates[i*num_dimensions] + num_dimensions);
148  num_next++;
149  num_running++;
150  status[i++] = running;
151  }
152  }
153  return result;
154  }
155 
157  size_t getNumRunning() const{ return num_running; }
158 
160  size_t getNumDone() const{ return num_done; }
161 
163  size_t getNumCandidates() const{ return num_candidates; }
164 
165 protected:
167  bool match(double const a[], double const b[]) const{
168  for(size_t i=0; i<num_dimensions; i++)
169  if (std::abs(a[i] - b[i]) > Maths::num_tol) return false;
170  return true;
171  }
172 
174  bool compare(double const a[], double const b[]) const{
175  for(size_t i=0; i<num_dimensions; i++){
176  if (a[i] < b[i] - Maths::num_tol) return true;
177  if (a[i] > b[i] + Maths::num_tol) return false;
178  }
179  return false;
180  }
181 
184  sorted.resize(num_candidates);
185  std::iota(sorted.begin(), sorted.end(), 0);
186  std::sort(sorted.begin(), sorted.end(), [&](size_t a, size_t b)->bool{ return compare(&candidates[a*num_dimensions], &candidates[b*num_dimensions]); });
187  }
188 
190  size_t find(double const point[]) const{
191  // if the point precedes the entire list, then send will craw back to -1
192  // if send reaches -1 in unsigned arithmetic the method will segfault
193  int sstart = 0, send = (int) num_candidates - 1, current = (sstart + send) / 2;
194  while (sstart <= send){
195  const double *cp = &candidates[sorted[current]*num_dimensions];
196  if (compare(cp, point)){
197  sstart = current + 1;
198  }else if (compare(point, cp)){
199  send = current - 1;
200  }else{
201  return (size_t) current;
202  }
203  current = (sstart + send) / 2;
204  }
205  return num_candidates;
206  }
207 
208 private:
209  size_t const num_dimensions, num_batch;
210  size_t num_candidates, num_running, num_done;
211  std::vector<double> candidates;
212  std::vector<size_t> sorted;
213  std::vector<TypeStatus> status;
214  std::forward_list<std::vector<double>> running_jobs;
215 };
216 
228 public:
230  template<typename IntType>
231  CompleteStorage(IntType dimensions) : num_dimensions((size_t) dimensions){}
234 
236  void write(std::ostream &os) const{
237  IO::writeNumbers<mode_binary, IO::pad_auto>(os, points.size(), values.size());
238  IO::writeVector<mode_binary, IO::pad_auto>(points, os);
239  IO::writeVector<mode_binary, IO::pad_auto>(values, os);
240  }
241 
243  void read(std::istream &is){
244  points.resize(IO::readNumber<IO::mode_binary_type, size_t>(is));
245  values.resize(IO::readNumber<IO::mode_binary_type, size_t>(is));
246  IO::readVector<IO::mode_binary_type>(is, points);
247  IO::readVector<IO::mode_binary_type>(is, values);
248  }
249 
251  void add(std::vector<double> const &x, std::vector<double> const &y){
252  points.insert(points.end(), x.begin(), x.end());
253  values.insert(values.end(), y.begin(), y.end());
254  }
255 
258  if (points.empty()) return;
259  grid.loadConstructedPoints(points, values);
260  points.clear();
261  values.clear();
262  }
263 
265  size_t getNumStored() const{ return points.size() / num_dimensions; }
266 
267 private:
268  size_t const num_dimensions;
269  std::vector<double> points, values;
270 };
271 
272 }
273 
274 #endif
Manages candidate points.
Definition: tsgCandidateManager.hpp:70
size_t getNumDone() const
Returns the number of complete jobs.
Definition: tsgCandidateManager.hpp:160
CandidateManager(IntTypeDim dimensions, IntTypeBatch batch_size)
Constructor, accepts number of dimensions as a constant parameter.
Definition: tsgCandidateManager.hpp:77
~CandidateManager()
Default destructor.
Definition: tsgCandidateManager.hpp:80
void operator=(std::vector< double > &&new_candidates)
Assign a new set of candidate points.
Definition: tsgCandidateManager.hpp:89
size_t getNumRunning() const
Returns the number of running jobs.
Definition: tsgCandidateManager.hpp:157
TypeStatus
Jobs are divided into already checked-out (running), checked-in (done), and available (free).
Definition: tsgCandidateManager.hpp:73
size_t getNumCandidates() const
Returns the number of all candidate jobs.
Definition: tsgCandidateManager.hpp:163
void sort_candidates()
Creates a sorted list of all candidates.
Definition: tsgCandidateManager.hpp:183
void complete(std::vector< double > const &p)
Mark a point as "complete".
Definition: tsgCandidateManager.hpp:105
std::vector< double > next(size_t remaining_budget)
Returns the next best point to compute, returns empty vector if no points are available.
Definition: tsgCandidateManager.hpp:132
size_t find(double const point[]) const
Find the index of the point within the canidates vector, returns num_candidates if not found.
Definition: tsgCandidateManager.hpp:190
bool match(double const a[], double const b[]) const
Returns true if entries in a and b match to Maths::num_tol, assumes sizes match already.
Definition: tsgCandidateManager.hpp:167
bool compare(double const a[], double const b[]) const
Returns true if the lexicographical order of a is before b.
Definition: tsgCandidateManager.hpp:174
Stores complete set of points before adding to the sparse grid.
Definition: tsgCandidateManager.hpp:227
void add(std::vector< double > const &x, std::vector< double > const &y)
Add a point to the stored list.
Definition: tsgCandidateManager.hpp:251
void read(std::istream &is)
Read the stored samples from the stream.
Definition: tsgCandidateManager.hpp:243
size_t getNumStored() const
Returns the number of stored points.
Definition: tsgCandidateManager.hpp:265
~CompleteStorage()
Default destructor.
Definition: tsgCandidateManager.hpp:233
CompleteStorage(IntType dimensions)
Constructor, accepts number of dimensions as a constant parameter.
Definition: tsgCandidateManager.hpp:231
void write(std::ostream &os) const
Write the stored samples to a stream.
Definition: tsgCandidateManager.hpp:236
void load(TasmanianSparseGrid &grid)
Move the stored points into the grid.
Definition: tsgCandidateManager.hpp:257
The master-class that represents an instance of a Tasmanian sparse grid.
Definition: TasmanianSparseGrid.hpp:293
void loadConstructedPoints(std::vector< double > const &x, std::vector< double > const &y)
Add pairs of points with associated model values.
constexpr double num_tol
Numerical tolerance for various algorithms.
Definition: tsgMathUtils.hpp:132
Encapsulates the Tasmanian Sparse Grid module.
Definition: TasmanianSparseGrid.hpp:68
Common includes and methods for all addons.