Doxygen 1.9.8
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2
 
Loading...
Searching...
No Matches
tsgHierarchyManipulator.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 __TSG_HIERARCHY_MANIPULATOR_HPP
32#define __TSG_HIERARCHY_MANIPULATOR_HPP
33
34#include "tsgRuleLocalPolynomial.hpp"
36
67namespace TasGrid{
68
74namespace HierarchyManipulations{
75
87template<RuleLocal::erule effrule>
97Data2D<int> computeDAGup(MultiIndexSet const &mset, RuleLocal::erule effrule);
108template<RuleLocal::erule effrule>
109Data2D<int> computeDAGup(MultiIndexSet const &mset, bool &is_complete);
110
122template<RuleLocal::erule effrule>
124
131template<RuleLocal::erule effrule>
132std::vector<int> computeLevels(MultiIndexSet const &mset);
139std::vector<int> computeLevels(MultiIndexSet const &mset, RuleLocal::erule effrule);
140
147template<RuleLocal::erule effrule>
148void completeToLower(MultiIndexSet const &mset, MultiIndexSet &refined);
149
156template<RuleLocal::erule effrule, typename callable_method>
157void touchAllImmediateRelatives(std::vector<int> &point, MultiIndexSet const &mset, callable_method apply){
158 int max_kids = RuleLocal::getMaxNumKids<effrule>();
159 for(auto &v : point){
160 int save = v; // replace one by one each index of p with either parent or kid
161
162 // check the parents
163 v = RuleLocal::getParent<effrule>(save);
164 if (v > -1){
165 int parent_index = mset.getSlot(point);
166 if (parent_index > -1)
167 apply(parent_index);
168 }
169
170 v = RuleLocal::getStepParent<effrule>(save);
171 if (v > -1){
172 int parent_index = mset.getSlot(point);
173 if (parent_index > -1)
174 apply(parent_index);
175 }
176
177 for(int k=0; k<max_kids; k++){
178 v = RuleLocal::getKid<effrule>(save, k);
179 if (v > -1){
180 int kid_index = mset.getSlot(point);
181 if (kid_index > -1)
182 apply(kid_index);
183 }
184 }
185
186 v = save; // restore the original index for the next iteration
187 }
188}
189
197template<RuleLocal::erule effrule>
198MultiIndexSet getLevelZeroPoints(size_t num_dimensions){
199 int num_parents = 0;
200 while(RuleLocal::getParent<effrule>(num_parents) == -1) num_parents++;
201 return MultiIndexManipulations::generateFullTensorSet(std::vector<int>(num_dimensions, num_parents));
202}
203
211template<RuleLocal::erule effrule>
213 if (candidates.empty()) return MultiIndexSet();
214 auto num_dimensions = candidates.getNumDimensions();
215
216 // always consider the points without parents
217 MultiIndexSet level_zero = getLevelZeroPoints<effrule>(num_dimensions);
218
219 MultiIndexSet result; // keep track of the cumulative result
220 MultiIndexSet total = current; // forms a working copy of the entire merged graph
221
222 // do not consider the points already included in total, complexity is level_zero.getNumIndexes()
223 if (!total.empty()) level_zero = level_zero - total;
224
225 if (level_zero.getNumIndexes() > 0){ // level zero nodes are missing from current
226 Data2D<int> roots(num_dimensions, 0);
227 for(int i=0; i<level_zero.getNumIndexes(); i++){
228 std::vector<int> p(level_zero.getIndex(i), level_zero.getIndex(i) + num_dimensions);
229 if (!candidates.missing(p))
230 roots.appendStrip(p);
231 }
232
233 result = MultiIndexSet(roots);
234 total += result;
235 }
236
237 if (total.empty()) return MultiIndexSet(); // current was empty and no roots could be added
238
239 int max_kids = RuleLocal::getMaxNumKids<effrule>();
240 int max_relatives = RuleLocal::getMaxNumParents<effrule>() + max_kids;
241 Data2D<int> update;
242 do{
243 update = Data2D<int>(num_dimensions, 0);
244
245 for(int i=0; i<total.getNumIndexes(); i++){
246 std::vector<int> relative(total.getIndex(i), total.getIndex(i) + num_dimensions);
247 for(auto &r : relative){
248 int k = r; // save the value
249 for(int j=0; j<max_relatives; j++){
250 r = (j < max_kids) ? RuleLocal::getKid<effrule>(k, j)
251 : ((j - max_kids == 0) ? RuleLocal::getParent<effrule>(k) : RuleLocal::getStepParent<effrule>(k));
252 if ((r != -1) && !candidates.missing(relative) && total.missing(relative))
253 update.appendStrip(relative);
254 }
255 r = k;
256 }
257 }
258
259 if (update.getNumStrips() > 0){
260 MultiIndexSet update_set(update);
261 result += update_set;
262 total += update_set;
263 }
264 }while(update.getNumStrips() > 0);
265
266 return result;
267}
268
269
277template<typename T>
278std::vector<Data2D<T>> splitByLevels(size_t stride, typename std::vector<T>::const_iterator ibegin, typename std::vector<T>::const_iterator iend, std::vector<int>::const_iterator ilevels){
279 size_t top_level = (size_t) *std::max_element(ilevels, ilevels + std::distance(ibegin, iend) / stride);
280
281 std::vector<Data2D<T>> split(top_level + 1, Data2D<T>(stride, 0));
282
283 for( struct { std::vector<int>::const_iterator il; typename std::vector<T>::const_iterator idata;} v = {ilevels, ibegin};
284 v.idata != iend;
285 v.il++, std::advance(v.idata, stride))
286 split[*v.il].appendStrip(v.idata);
287
288 return split;
289}
290
295inline std::vector<Data2D<int>> splitByLevels(MultiIndexSet const &mset, std::vector<int> const &levels){
296 return splitByLevels<int>(mset.getNumDimensions(), mset.begin(), mset.end(), levels.begin());
297}
298
303template<typename T>
304inline std::vector<Data2D<T>> splitByLevels(Data2D<T> const &data, std::vector<int> const &levels){
305 return splitByLevels<T>(data.getStride(), data.begin(), data.end(), levels.begin());
306}
307
312inline std::vector<Data2D<double>> splitByLevels(StorageSet const &stortage, std::vector<int> const &levels){
313 return splitByLevels<double>(stortage.getNumOutputs(), stortage.begin(), stortage.end(), levels.begin());
314}
315
324public:
329
331 int getNumJobs() const{ return (int) job_pnts.size(); }
333 int getJobDirection(int job) const{ return job_directions[job]; }
335 int getJobNumPoints(int job) const{ return (int) job_pnts[job].size(); }
337 const int* getJobPoints(int job) const{ return job_pnts[job].data(); }
339 int getMaxNumPoints() const { return (job_pnts.size() > 0) ? (int) std::max_element(job_pnts.begin(), job_pnts.end(),
340 [&](std::vector<int> const &a, std::vector<int> const& b)->bool{ return (a.size() < b.size()); })->size() : 0; }
341
342private:
343 std::vector<int> job_directions;
344 std::vector<std::vector<int>> job_pnts;
345};
346
347}
348
349}
350
351#endif
Generic 2D data structure divided into contiguous strips of fixed length (similar to a matrix).
Definition tsgIndexSets.hpp:104
std::vector< T >::iterator end()
Returns an iterator to the end of the internal data.
Definition tsgIndexSets.hpp:171
void appendStrip(typename std::vector< T >::const_iterator const &x)
Uses std::vector::insert to append the data.
Definition tsgIndexSets.hpp:179
std::vector< T >::iterator begin()
Returns an iterator to the beginning of the internal data.
Definition tsgIndexSets.hpp:167
int getNumStrips() const
Returns the number of strips.
Definition tsgIndexSets.hpp:149
size_t getStride() const
Returns the stride.
Definition tsgIndexSets.hpp:147
Reorganize the points into sets of nodes that align in one-dimension, used for directional localp ref...
Definition tsgHierarchyManipulator.hpp:323
int getJobDirection(int job) const
Return the direction for the job.
Definition tsgHierarchyManipulator.hpp:333
int getNumJobs() const
Returns the number of one dimensional jobs.
Definition tsgHierarchyManipulator.hpp:331
const int * getJobPoints(int job) const
Return the indexes of the points associated with the job.
Definition tsgHierarchyManipulator.hpp:337
~SplitDirections()
Destroy all data.
Definition tsgHierarchyManipulator.hpp:328
SplitDirections(const MultiIndexSet &points)
Constructor, deinfe the set to split into directions.
int getMaxNumPoints() const
Return the max number of points for any job.
Definition tsgHierarchyManipulator.hpp:339
int getJobNumPoints(int job) const
Return the number of points associated with the job.
Definition tsgHierarchyManipulator.hpp:335
Class that stores multi-indexes in sorted (lexicographical) order.
Definition tsgIndexSets.hpp:234
size_t getNumDimensions() const
Returns the number of dimensions.
Definition tsgIndexSets.hpp:263
int getSlot(const int *p) const
Returns the slot containing index p, returns -1 if not found.
bool missing(const std::vector< int > &p) const
Returns true if p is missing from the set, false otherwise.
Definition tsgIndexSets.hpp:291
std::vector< int >::const_iterator begin() const
Returns a const iterator to the beginning of the internal data.
Definition tsgIndexSets.hpp:277
int getNumIndexes() const
Returns the number of indexes.
Definition tsgIndexSets.hpp:265
bool empty() const
Returns true if there are no multi-indexes in the set, false otherwise.
Definition tsgIndexSets.hpp:260
const int * getIndex(int i) const
Returns the i-th index of the set, useful to loop over all indexes or to cross reference with values.
Definition tsgIndexSets.hpp:294
std::vector< int >::const_iterator end() const
Returns a const iterator to the end of the internal data.
Definition tsgIndexSets.hpp:279
Class that stores values, i.e., model outputs, the order of the values is in sync with the order of s...
Definition tsgIndexSets.hpp:334
size_t getNumOutputs() const
Returns the number of outputs.
Definition tsgIndexSets.hpp:366
std::vector< double >::const_iterator begin() const
Returns a const iterator to the beginning of the internal data.
Definition tsgIndexSets.hpp:387
std::vector< double >::const_iterator end() const
Returns a const iterator to the end of the internal data.
Definition tsgIndexSets.hpp:389
void completeToLower(MultiIndexSet const &mset, MultiIndexSet &refined)
Complete refined so that the union of refined and mset is lower w.r.t. the rule. .
std::vector< int > computeLevels(MultiIndexSet const &mset)
Returns a vector that is the sum of the one dimensional levels of each multi-index in the set....
Data2D< int > computeDAGup(MultiIndexSet const &mset)
Cache the indexes slot numbers of the parents of the multi-indexes in mset.
std::vector< Data2D< T > > splitByLevels(size_t stride, typename std::vector< T >::const_iterator ibegin, typename std::vector< T >::const_iterator iend, std::vector< int >::const_iterator ilevels)
Split the range between ibegin and iend into strips of stride and orders those by levels according to...
Definition tsgHierarchyManipulator.hpp:278
MultiIndexSet getLevelZeroPoints(size_t num_dimensions)
Return the tensor set of all points that sit on level zero (i.e., have no parents).
Definition tsgHierarchyManipulator.hpp:198
MultiIndexSet getLargestConnected(MultiIndexSet const &current, MultiIndexSet const &candidates)
Return the largest subset of candidates such that adding it to current will result in a connected gra...
Definition tsgHierarchyManipulator.hpp:212
void touchAllImmediateRelatives(std::vector< int > &point, MultiIndexSet const &mset, callable_method apply)
Will call apply() with the slot index in mset of each parent/child of point..
Definition tsgHierarchyManipulator.hpp:157
Data2D< int > computeDAGDown(MultiIndexSet const &mset)
Cache the indexes slot numbers of the children of the multi-indexes in mset.
MultiIndexSet generateFullTensorSet(std::vector< int > const &num_entries)
Create a full-tensor multi-index set with num_entries in each direction.
Definition tsgIndexManipulator.hpp:79
Encapsulates the Tasmanian Sparse Grid module.
Definition TasmanianSparseGrid.hpp:68
Algorithms for manipulating sets of multi-indexes.