def insertTruncatedBorder(grid, gp): """ insert points on the border recursively for grids with border @param grid: Grid @param gp: HashGridIndex @return: list of HashGridIndex, contains all the newly added grid points """ gs = grid.getStorage() gps = [gp] ans = [] while len(gps) > 0: gp = gps.pop() for d in xrange(gs.dim()): # right border in d rgp = HashGridIndex(gp) gs.right_levelzero(rgp, d) # insert the point if not gs.has_key(rgp): ans += insertPoint(grid, rgp) gps.append(rgp) # left border in d lgp = HashGridIndex(gp) gs.left_levelzero(lgp, d) # insert the point if not gs.has_key(rgp): ans += insertPoint(grid, lgp) gps.append(lgp) return ans
def lookupFullGridPointsRec1d(self, grid, alpha, gp, d, p, opEval, maxLevel, acc): gs = grid.getStorage() level, index = gp.getLevel(d), gp.getIndex(d) # if the function value for the left child # is negtive, then add it with all its # hierarchical ancestors gs.left_child(gp, d) gp.getCoords(p) if opEval.eval(alpha, p) < 0: acc.append(HashGridIndex(gp)) if level + 1 < maxLevel: self.lookupFullGridPointsRec1d(grid, alpha, gp, d, p, opEval, maxLevel, acc) # if the function value for the right child # is negtive, then add it with all its # hierarchical ancestors gp.set(d, level, index) gs.right_child(gp, d) gp.getCoords(p) if opEval.eval(alpha, p) < 0: acc.append(HashGridIndex(gp)) # store them for next round if level + 1 < maxLevel: self.lookupFullGridPointsRec1d(grid, alpha, gp, d, p, opEval, maxLevel, acc) # reset the grid point gp.set(d, level, index)
def balance(grid): gs = grid.getStorage() newgps = [] gps = [gs.get(i) for i in xrange(gs.size())] while len(gps) > 0: gp = gps.pop() for dim in xrange(gs.dim()): # left child in dimension dim lgp = HashGridIndex(gp) gs.left_child(lgp, dim) # right child in dimension dim rgp = HashGridIndex(gp) gs.right_child(rgp, dim) if gs.has_key(lgp) and not gs.has_key(rgp): inserted = insertPoint(grid, rgp) elif gs.has_key(rgp) and not gs.has_key(lgp): inserted = insertPoint(grid, lgp) else: inserted = [] # update lists for gpi in inserted: gps.append(gpi) newgps.append(gpi) gs.recalcLeafProperty() return newgps
def naive_calc(self): result = {} for j in xrange(self.gridSize): HashGridIndex = self.storage.get(j) HashGridIndex.setLeaf(False) print "Point: ", j, " (", HashGridIndex.toString(), ")" for d in xrange(self.dim): print "Dimension: ", d # # Get left and right child # leftChild = HashGridIndex(HashGridIndex) rightChild = HashGridIndex(HashGridIndex) self.storage.left_child(leftChild, d) self.storage.right_child(rightChild, d) # # Check if point is refinable # if self.storage.has_key(leftChild) or self.storage.has_key( rightChild): continue # # Insert children temporarily # self.storage.insert(leftChild) self.storage.insert(rightChild) val1 = self.naive_calc_single(leftChild) print "Left Child: ", val1 val2 = self.naive_calc_single(rightChild) print "Right Child: ", val2 self.storage.deleteLast() self.storage.deleteLast() result[(j, d)] = val1 + val2 print "" return result
def findCandidates(self, grid, alpha): gs = grid.getStorage() candidates = {} # lookup dimension-wise for d in xrange(gs.dim()): # compute starting points by level sum anchors = [] for i in xrange(gs.size()): accLevel = gs.get(i).getLevel(d) if accLevel == 1: anchors.append(i) while len(anchors) > 0: # get next starting node ix = anchors.pop(0) gp = gs.get(ix) acc = [] self.findCandidatesSweep1d(d, gp, alpha, grid, acc, False) # store candidates for gp in acc: ix = gs.seq(gp) if ix not in candidates: candidates[ix] = HashGridIndex(gp) return candidates.values()
def insertPoint(grid, gp): """ insert a grid point to the storage if it is valid. Returns the sequence number of the new grid point in the storage """ gs = grid.getStorage() if gs.has_key(gp) or not isValid(grid, gp): return [] success = gs.insert(HashGridIndex(gp)) > -1 if success: return [HashGridIndex(gp)] else: raise AttributeError( 'can not insert this new grid point to the storage')
def extend_grid_1d(grid, *args, **kws): gs = grid.getStorage() accLevel = gs.getMaxLevel() dim = gs.dim() # create dim+1 dimensional grid of level 0 new_grid = createGrid(grid, dim + 1, *args, **kws) # create 1 dimensional reference grid of level accLevel ref_grid = createGrid(grid, 1) ref_grid.createGridGenerator().regular(accLevel) # == full grid in dim = 1 ref_gs = ref_grid.getStorage() # create cross product between the 1d and the dimd-grid for i in xrange(gs.size()): gp = gs.get(i) new_gp = HashGridIndex(dim + 1) # copy level index vectors from old grid to the new one for d in xrange(gs.dim()): new_gp.set(d, gp.getLevel(d), gp.getIndex(d)) # get the indices in the missing dimension for j in xrange(ref_gs.size()): ref_gp = ref_gs.get(j) new_gp.set(dim, ref_gp.getLevel(0), ref_gp.getIndex(0)) insertPoint(new_grid, new_gp) return new_grid
def addChildren(self, grid, gp): gs = grid.getStorage() for d in xrange(gs.dim()): # check left child in d gpl = HashGridIndex(gp) gs.left_child(gpl, d) if not gs.has_key(gpl) and isValid(grid, gpl) and \ self.checkRange(gpl, self.maxLevel): self.addCollocationNode(grid, gpl) # check right child in d gpr = HashGridIndex(gp) gs.right_child(gpr, d) if not gs.has_key(gpr) and isValid(grid, gpr) and \ self.checkRange(gpr, self.maxLevel): self.addCollocationNode(grid, gpr)
def project(grid, dims): """ Project all grid points to the given dimensions @param grid: Grid sparse grid @param dims: list dimensions to which the grid points are projected """ gs = grid.getStorage() # create a new empty grid dim = len(dims) gps = [None] * gs.size() # run over all grid points in grid and # project them to the dimensions dims for i in xrange(gs.size()): gp = gs.get(i) ngp = HashGridIndex(dim) # copy level index to new grid point for k, d in enumerate(dims): ngp.set(k, gp.getLevel(d), gp.getIndex(d)) # insert it to the new grid gps[i] = ngp # compute new basis ngrid = createGrid(grid, len(dims)) basis = getBasis(ngrid) return gps, basis
def isRefineable(grid, gp): gs = grid.getStorage() for d in xrange(gs.dim()): # left child in dimension dim gpl = HashGridIndex(gp) gs.left_child(gpl, d) if not gs.has_key(gpl) and isValid(grid, gpl): return True # right child in dimension dim gpr = HashGridIndex(gp) gs.right_child(gpr, d) if not gs.has_key(gpr) and isValid(grid, gpr): return True return False
def insert_children(grid, gp, d): cnt = [] gs = grid.getStorage() # left child in dimension dim gpl = HashGridIndex(gp) gs.left_child(gpl, d) if not gs.has_key(gpl) and isValid(grid, gpl): success = gs.insert(gpl) > -1 cnt += 1 if success else 0 # right child in dimension dim gpr = HashGridIndex(gp) gs.right_child(gpr, d) if not gs.has_key(gpr) and isValid(grid, gpr): success = gs.insert(gpr) > -1 cnt += 1 if success else 0 return cnt
def refine(self, grid, gp): ans = [] gs = grid.getStorage() for d in xrange(gs.dim()): gpl = HashGridIndex(gp) gs.left_child(gpl, d) ans += insertPoint(grid, gpl) ans += insertHierarchicalAncestors(grid, gpl) if hasBorder(grid): ans += insertTruncatedBorder(grid, gpl) gpr = HashGridIndex(gp) gs.right_child(gpr, d) ans += insertPoint(grid, gpr) ans += insertHierarchicalAncestors(grid, gpr) if hasBorder(grid): ans += insertTruncatedBorder(grid, gpr) gs.recalcLeafProperty() return ans
def parent(grid, gp, d): # get parent level = gp.getLevel(d) - 1 index = gp.getIndex(d) / 2 + ((gp.getIndex(d) + 1) / 2) % 2 if isValid1d(grid, level, index): # create parent ans = HashGridIndex(gp) ans.set(d, level, index) return ans return None
def insertHierarchicalAncestors(grid, gp): """ insert all hierarchical ancestors recursively to the grid @param grid: Grid @param gp: HashGridIndex @return: list of HashGridIndex, contains all the newly added grid points """ newGridPoints = [] gs = grid.getStorage() gps = [gp] while len(gps) > 0: gp = gps.pop() gpc = HashGridIndex(gp) for dim in xrange(gp.dim()): oldlevel, oldindex = gpc.getLevel(dim), gpc.getIndex(dim) # run up to the root node until you find one existing node level, index = oldlevel, oldindex while level > 1: level -= 1 index = index / 2 + ((index + 1) / 2) % 2 gpc.set(dim, level, index) if not gs.has_key(gpc): newGridPoints.append(HashGridIndex(gpc)) else: break # reset the point gpc.set(dim, oldlevel, oldindex) # insert the grid points in a list and add the hierarchical ancestors # of them for gp in newGridPoints: gps += insertPoint(grid, gp) return newGridPoints
def copyGrid(grid, level=0, deg=1): # create new grid gs = grid.getStorage() dim = gs.dim() newGrid = createGrid(grid, dim, deg) if level > 0: newGrid.createGridGenerator().regular(level) newGs = newGrid.getStorage() # insert grid points for i in xrange(gs.size()): gp = gs.get(i) # insert grid point if not newGs.has_key(gp): newGs.insert(HashGridIndex(gp)) newGs.recalcLeafProperty() return newGrid
def hasChildren(grid, gp): gs = grid.getStorage() d = 0 gpn = HashGridIndex(gp) while d < gs.dim(): # load level index level, index = gp.getLevel(d), gp.getIndex(d) # check left child in d gs.left_child(gp, d) if gs.has_key(gpn): return True # check right child in d gp.set(d, level, index) gs.right_child(gp, d) if gs.has_key(gpn): return True gpn.set(d, level, index) d += 1 return False
def test_1(self): storage = self.grid.getStorage() gridSize = self.grid.getSize() numDim = storage.dim() print "######" print "Expected result:" print "######" expected = {} for j in xrange(gridSize): HashGridIndex = storage.get(j) HashGridIndex.setLeaf(False) print "Point: ", j, " (", HashGridIndex.toString(), ")" for d in xrange(numDim): # # Get left and right child # leftChild = HashGridIndex(HashGridIndex) rightChild = HashGridIndex(HashGridIndex) storage.left_child(leftChild, d) storage.right_child(rightChild, d) # # Check if point is refinable # if storage.has_key(leftChild) or storage.has_key(rightChild): continue # # Insert children temporarily # storage.insert(leftChild) storage.insert(rightChild) val1 = self.calc_indicator_value(leftChild) val2 = self.calc_indicator_value(rightChild) storage.deleteLast() storage.deleteLast() print "Dimension: ", d print "Left Child: ", val1 print "Right Child: ", val2 print "" expected[(j, d)] = val1 + val2 print "" for k, v in expected.iteritems(): print(k, v) print "######" print "Actual result:" print "######" actual = refinement_map({}) self.strategy.collectRefinablePoints(storage, 10, actual) for k, v in actual.iteritems(): print(k, v) # # Assertions # for k, v in expected.iteritems(): self.assertEqual(actual[k], v)
def hierarchizeBruteForce(grid, nodalValues, ignore=None): if hasBorder(grid): print 'brute force hierarchization is not supported for boundary grids' return nodalValues alpha = DataVector(nodalValues) gs = grid.getStorage() basis = getBasis(grid) # hierarchize dimension-wise for d in xrange(gs.dim()): # compute starting points by level sum ixs = {} for i in xrange(gs.size()): accLevel = gs.get(i).getLevel(d) if accLevel in ixs: ixs[accLevel].append(i) else: ixs[accLevel] = [i] # collect all possible starting points starting_points = [] for key in sorted(ixs.keys()): starting_points += ixs[key] while len(starting_points) > 0: # get next starting node ix = starting_points.pop(0) gp = gs.get(ix) # append left and right child gpl = HashGridIndex(gp) gs.left_child(gpl, d) gpr = HashGridIndex(gp) gs.right_child(gpr, d) gps = [] if gs.has_key(gpr): gps.append(gpr) if gs.has_key(gpl): gps.append(gpl) while len(gps) > 0: gpc = gps.pop() ix = gs.seq(gpc) # removeSample point from possible starting points starting_points.remove(ix) diff = evalHierToTop(basis, grid, alpha, gpc, d) # print "%i: %.20f - %.20f = %.20f" % (ix, alpha[ix], diff, alpha[ix] - diff) alpha[ix] -= diff # append left and right child gpl = HashGridIndex(gpc) gs.left_child(gpl, d) gpr = HashGridIndex(gpc) gs.right_child(gpr, d) if gs.has_key(gpr): gps.append(gpr) if gs.has_key(gpl): gps.append(gpl) return alpha
def createGrid(self): """ Creates the specified grid """ grid = None if self.__file is not None and os.path.exists(self.__file): gridFormatter = GridFormatter() grid = gridFormatter.deserializeFromFile(self.__file) else: if self.__grid is not None: self.__dim = self.__grid.getStorage().dim() if (self.__dim is None or self.level is None) and self.__grid is None: raise AttributeError("Not all attributes assigned to create\ grid") if self.__border is not None: if self.__border == BorderTypes.TRAPEZOIDBOUNDARY: if self.__deg > 1: grid = Grid.createPolyBoundaryGrid( self.__dim, self.__deg) else: grid = Grid.createLinearBoundaryGrid(self.__dim) elif self.__border == BorderTypes.COMPLETEBOUNDARY: if self.__deg > 1: raise NotImplementedError() else: grid = Grid.createLinearBoundaryGrid(self.__dim, 0) else: if self.__deg > 1: grid = Grid.createModPolyGrid(self.__dim, self.__deg) else: grid = Grid.createModLinearGrid(self.__dim) else: # no border points if self.__deg > 1: grid = Grid.createPolyGrid(self.__dim, self.__deg) else: grid = Grid.createLinearGrid(self.__dim) # generate the grid if self.level is not None: generator = grid.createGridGenerator() if not self.__full: generator.regular(self.level) else: generator.full(self.level) # if there is a grid specified, add all the missing points if self.__grid is not None: gs = grid.getStorage() copygs = self.__grid.getStorage() # insert grid points for i in xrange(copygs.size()): gp = copygs.get(i) # insert grid point if not gs.has_key(gp): gs.insert(HashGridIndex(gp)) if self.__border == BorderTypes.TRAPEZOIDBOUNDARY: insertTruncatedBorder(grid, gp) gs.recalcLeafProperty() return grid
def __doMarginalize(grid, alpha, dd, measure=None): gs = grid.getStorage() dim = gs.dim() if dim < 2: raise AttributeError("The grid has to be at least of dimension 2") if dd >= dim: raise AttributeError("The grid has only %i dimensions, so I can't \ integrate over %i" % (dim, dd)) # create new grid n_dim = dim - 1 n_grid = createGrid(grid, n_dim) n_gs = n_grid.getStorage() # insert grid points n_gp = HashGridIndex(n_dim) for i in xrange(gs.size()): gp = gs.get(i) for d in range(dim): if d == dd: # omit marginalization direction continue elif d < dd: n_gp.set(d, gp.getLevel(d), gp.getIndex(d)) else: n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d)) # insert grid point if not n_gs.has_key(n_gp): n_gs.insert(n_gp) n_gs.recalcLeafProperty() # create coefficient vector n_alpha = DataVector(n_gs.size()) n_alpha.setAll(0.0) # set function values for n_alpha for i in xrange(gs.size()): gp = gs.get(i) for d in range(dim): if d == dd: dd_level = gp.getLevel(d) dd_index = gp.getIndex(d) elif d < dd: n_gp.set(d, gp.getLevel(d), gp.getIndex(d)) else: n_gp.set(d - 1, gp.getLevel(d), gp.getIndex(d)) if not n_gs.has_key(n_gp): raise Exception("This should not happen!") # compute the integral of the given basis if measure is None: q, err = getIntegral(grid, dd_level, dd_index), 0. else: dist, trans = measure[0][dd], measure[1][dd] lf = LinearGaussQuadratureStrategy([dist], [trans]) basis = getBasis(grid) gpdd = HashGridIndex(1) gpdd.set(0, dd_level, dd_index) q, err = lf.computeLinearFormByList([gpdd], basis) q = q[0] # search for the corresponding index j = n_gs.seq(n_gp) n_alpha[j] += alpha[i] * q return n_grid, n_alpha, err
def __refine(self, learner, B, simulate=False): # get sparse grid grid = learner.getGrid() if simulate: oldGrid = grid grid = copyGrid(grid) learner.grid = grid # find how many points should be refined pointsNum = learner.getNumOfPointsToRefine(len(B)) # refine now step by step newGridPoints = [] refinedPoints = [] gs = grid.getStorage() iteration = learner.iteration # size of grid before refinement n1 = gs.size() # as long as the end of learning has not been reached, continue... while pointsNum > 0 and len(B) > 0 and \ (not learner.stopPolicy or not learner.stopPolicy.hasLimitReached(learner)): # note: the highest rated grid point is at the end of B vi, gp = B.pop() # some printing if not simulate: print "refine %i/%i (%i, %i) = %g" % \ (pointsNum, len(B), len(newGridPoints), len(refinedPoints), vi) # refine the grid nps = self._localRefinementStrategy.refine(grid, gp) # ## set surplus vector such that just the desired point # ## is going to be refined and nothing else # oldgs = HashGridStorage(gs) # alpha = DataVector(gs.size()) # alpha.setAll(0.0) # alpha[gs.seq(gp)] = 2.0 # refFunc = SurplusRefinementFunctor(alpha, 1, 1) # ## TODO: try refineMaxLevel(refFunc, maxLevel) # grid.createGridGenerator().refine(refFunc) # nps = [] # for i in xrange(gs.size()): # if not oldgs.has_key(gs.get(i)): # nps.append(i) # check there have been added some new points if not learner.stopPolicy or \ learner.stopPolicy.hasGridSizeChanged(learner): # if something has been refined then reduce the number # of points which should still be refined pointsNum -= 1 # store which point has been refined refinedPoints.append(HashGridIndex(gp)) newGridPoints += nps # increase iteration of the learner learner.iteration += 1 # balance the grid if self._balancing: newGridPoints += balance(grid) # update admissible set if not simulate: self._admissibleSet.update(grid, newGridPoints) # make sure that I have collected all the new grid points assert len(newGridPoints) == gs.size() - n1 # reset the iteration variable @TODO: the iteration variable # is ambiguous. It represents in the TrainingStopPolicy the # number of refinement steps, in the context of ASGC it # represents the number of refinements. So here we neglect the # first part and use it just internally so that the # hasLimitReached works. learner.iteration = iteration # if not simulate: # gs = grid.getStorage() # p = DataVector(gs.dim()) # # for gp in refinedPoints: # gp.getCoords(p) # plt.plot(p[0], p[1], marker='o', markersize=20, # linestyle='', color='green') # # for i in xrange(gs.size()): # gs.get(i).getCoords(p) # plt.plot(p[0], p[1], marker='o', markersize=10, # linestyle='', color='blue') # # for gp in newGridPoints: # gp.getCoords(p) # plt.plot(p[0], p[1], marker='o', markersize=10, # linestyle='', color='red') # # plt.title("size = %i" % gs.size()) # plt.xlim(0, 1) # plt.ylim(0, 1) # plt.savefig('%i.png' % learner.iteration) # reset the learner if the refinement is just simulated if simulate: learner.grid = oldGrid return newGridPoints