/** * Descends on all dimensions beside dim_sweep. Class functor for dim_sweep * Boundaries are not regarded * * @param source a DataVector containing the source coefficients of the grid points * @param result a DataVector containing the result coefficients of the grid points * @param dim_sweep the dimension in which the functor is executed */ void sweep1D(DataVector& source, DataVector& result, size_t dim_sweep) { // generate a list of all dimension (-dim_sweep) // from dimension recursion unrolling std::vector<size_t> dim_list; for (size_t i = 0; i < storage->dim(); i++) { if (i != dim_sweep) { dim_list.push_back(i); } } grid_iterator index(storage); sweep_rec(source, result, index, dim_list, storage->dim() - 1, dim_sweep); }
/** * Recursive traversal of the "tree" of basis functions for evaluation, used in operator(). * For a given evaluation point \f$x\f$, it stores tuples (std::pair) of * \f$(i,\phi_i(x))\f$ in the result vector for all basis functions that are non-zero. * * @param basis a sparse grid basis * @param point evaluation point within the domain * @param current_dim the dimension currently looked at (recursion parameter) * @param value the value of the evaluation of the current basis function up to (excluding) dimension current_dim (product of the evaluations of the one-dimensional ones) * @param working iterator working on the GridStorage of the basis * @param source array of indices for each dimension (identifying the indices of the current grid point) * @param alpha the spars grid's ansatzfunctions coefficients * @param result reference to a float_t into which the result should be stored */ void rec(BASIS& basis, const DataVector& point, size_t current_dim, float_t value, GridStorage::grid_iterator& working, GridStorage::index_type::index_type* source, const DataVector& alpha, float_t& result) { typedef GridStorage::index_type::level_type level_type; typedef GridStorage::index_type::index_type index_type; const unsigned int BITS_IN_BYTE = 8; // maximum possible level for the index type const level_type max_level = static_cast<level_type> ( sizeof(index_type) * BITS_IN_BYTE - 1); index_type src_index = source[current_dim]; level_type work_level = 1; while (true) { size_t seq = working.seq(); if (storage->end(seq)) { break; } else { index_type work_index; level_type temp; working.get(current_dim, temp, work_index); float_t new_value = basis.eval(work_level, work_index, point[current_dim]); new_value *= value; if (current_dim == storage->dim() - 1) { result += (alpha[seq] * new_value); } else { rec(basis, point, current_dim + 1, new_value, working, source, alpha, result); } } if (working.hint()) { break; } // this decides in which direction we should descend by evaluating // the corresponding bit // the bits are coded from left to right starting with level 1 // being in position max_level bool right = (src_index & (1 << (max_level - work_level))) > 0; ++work_level; if (right) { working.rightChild(current_dim); } else { working.leftChild(current_dim); } } working.resetToLevelOne(current_dim); }
/** * Descends on all dimensions beside dim_sweep. Class functor for dim_sweep * Boundaries are regarded * * @param source a DataMatrix containing the source coefficients of the grid points * @param result a DataMatrix containing the result coefficients of the grid points * @param dim_sweep the dimension in which the functor is executed */ void sweep1D_Boundary(DataMatrix& source, DataMatrix& result, size_t dim_sweep) { // generate a list of all dimension (-dim_sweep) from // dimension recursion unrolling std::vector<size_t> dim_list; for (size_t i = 0; i < storage->dim(); i++) { if (i != dim_sweep) { dim_list.push_back(i); } } grid_iterator index(storage); index.resetToLevelZero(); sweep_Boundary_rec(source, result, index, dim_list, storage->dim() - 1, dim_sweep); }
int main() { // create a two-dimensional piecewise bilinear grid size_t dim = 2; Grid* grid = Grid::createLinearGrid(dim); GridStorage* gridStorage = grid->getStorage(); std::cout << "dimensionality: " << gridStorage->dim() << std::endl; // create regular grid, level 3 size_t level = 3; GridGenerator* gridGen = grid->createGridGenerator(); gridGen->regular(level); std::cout << "number of initial grid points: " << gridStorage->size() << std::endl; // create coefficient vector DataVector alpha(gridStorage->size()); alpha.setAll(0.0); std::cout << "length of alpha vector: " << alpha.getSize() << std::endl; GridIndex* gp; // refine adaptively 5 times for (int step = 0; step < 5; step++) { // set function values in alpha for (size_t i = 0; i < gridStorage->size(); i++) { gp = gridStorage->get(i); alpha[i] = f(gp->getCoord(0), gp->getCoord(1)); } // hierarchize SGPP::op_factory::createOperationHierarchisation(*grid)->doHierarchisation( alpha); // refine a single grid point each time gridGen->refine(new SurplusRefinementFunctor(&alpha, 1)); std::cout << "refinement step " << step + 1 << ", new grid size: " << alpha.getSize() << std::endl; // extend alpha vector (new entries uninitialized) alpha.resize(gridStorage->size()); } delete grid; }
void testHierarchisationDehierarchisation(SGPP::base::Grid* grid, size_t level, SGPP::float_t (*func)(DataVector&), SGPP::float_t tolerance = 0.0, bool naiveOp = false, bool doStretch = false) { GridGenerator* gridGen = grid->createGridGenerator(); gridGen->regular(level); GridStorage* gridStore = grid->getStorage(); size_t dim = gridStore->dim(); Stretching* stretch = NULL; if (doStretch) stretch = gridStore->getStretching(); DataVector node_values = DataVector(gridStore->size()); DataVector coords = DataVector(dim); for (size_t n = 0; n < gridStore->size(); n++) { if (doStretch) { gridStore->get(n)->getCoordsStretching(coords, *stretch); } else { gridStore->get(n)->getCoords(coords); } node_values[n] = func(coords); } DataVector alpha = DataVector(node_values); OperationHierarchisation* hierarchisation = SGPP::op_factory::createOperationHierarchisation(*grid); hierarchisation->doHierarchisation(alpha); if (naiveOp == true) { OperationNaiveEval* op = SGPP::op_factory::createOperationNaiveEval(*grid); for (size_t n = 0; n < gridStore->size(); n++) { if (doStretch) { gridStore->get(n)->getCoordsStretching(coords, *stretch); } else { gridStore->get(n)->getCoords(coords); } SGPP::float_t eval = op->eval(alpha, coords); BOOST_CHECK_CLOSE(eval, node_values[n], tolerance); } } else { OperationEval* op = SGPP::op_factory::createOperationEval(*grid); for (size_t n = 0; n < gridStore->size(); n++) { if (doStretch) { gridStore->get(n)->getCoordsStretching(coords, *stretch); } else { gridStore->get(n)->getCoords(coords); } SGPP::float_t eval = op->eval(alpha, coords); BOOST_CHECK_CLOSE(eval, node_values[n], tolerance); } } DataVector node_values_back = DataVector(alpha); hierarchisation->doDehierarchisation(node_values_back); for (size_t n = 0; n < gridStore->size(); n++) { BOOST_CHECK_CLOSE(node_values_back[n], node_values[n], tolerance); } }