Doxygen 1.15.0
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2
Loading...
Searching...
No Matches
tsgHierarchyManipulator.hpp
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"
35#include "tsgIndexManipulator.hpp"
36
48
66
67namespace TasGrid{
68
74namespace HierarchyManipulations{
75
87template<RuleLocal::erule effrule>
88Data2D<int> computeDAGup(MultiIndexSet const &mset);
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>
123Data2D<int> computeDAGDown(MultiIndexSet const &mset);
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>
212MultiIndexSet getLargestConnected(MultiIndexSet const &current, MultiIndexSet const &candidates){
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
323class SplitDirections{
324public:
326 SplitDirections(const MultiIndexSet &points);
328 ~SplitDirections(){}
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
Encapsulates the Tasmanian Sparse Grid module.
Definition TasmanianSparseGrid.hpp:68