def sparse_grid(func, order, dim, skew=None): X, W = [], [] bindex = ber.bindex(order - dim + 1, order, dim) if skew is None: skew = np.zeros(dim, dtype=int) else: skew = np.array(skew, dtype=int) assert len(skew) == dim for i in xrange(ber.terms(order, dim) - ber.terms(order - dim, dim)): I = bindex[i] x, w = func(skew + I) w *= (-1)**(order - sum(I)) * comb(dim - 1, order - sum(I)) X.append(x) W.append(w) X = np.concatenate(X, 1) W = np.concatenate(W, 0) order = np.lexsort(X) X = X.T[order].T W = W[order] # identify non-unique terms diff = np.diff(X.T, axis=0) ui = np.ones(len(X.T), bool) ui[1:] = (diff != 0).any(axis=1) # merge duplicate nodes N = len(W) i = 1 while i < N: while i < N and ui[i]: i += 1 j = i + 1 while j < N and not ui[j]: j += 1 if j - i > 1: W[i - 1] = np.sum(W[i - 1:j]) i = j + 1 X = X[:, ui] W = W[ui] return X, W
def sparse_grid(func, order, dim, skew=None): X, W = [], [] bindex = ber.bindex(order-dim+1, order, dim) if skew is None: skew = np.zeros(dim, dtype=int) else: skew = np.array(skew, dtype=int) assert len(skew)==dim for i in xrange(ber.terms(order, dim)-ber.terms(order-dim, dim)): I = bindex[i] x,w = func(skew+I) w *= (-1)**(order-sum(I))*comb(dim-1,order-sum(I)) X.append(x) W.append(w) X = np.concatenate(X, 1) W = np.concatenate(W, 0) X = np.around(X, 15) order = np.lexsort(tuple(X)) X = X.T[order].T W = W[order] # identify non-unique terms diff = np.diff(X.T, axis=0) ui = np.ones(len(X.T), bool) ui[1:] = (diff!=0).any(axis=1) # merge duplicate nodes N = len(W) i = 1 while i<N: while i<N and ui[i]: i+=1 j = i+1 while j<N and not ui[j]: j+=1 if j-i>1: W[i-1] = np.sum(W[i-1:j]) i = j+1 X = X[:,ui] W = W[ui] return X, W
def lagrange_polynomial(X, sort="GR"): """ Lagrange Polynomials X : array_like Sample points where the lagrange polynomials shall be """ X = np.asfarray(X) if len(X.shape) == 1: X = X.reshape(1, X.size) dim, size = X.shape order = 1 while ber.terms(order, dim) <= size: order += 1 indices = np.array(ber.bindex(1, order, dim, sort)[:size]) s, t = np.mgrid[:size, :size] M = np.prod(X.T[s]**indices[t], -1) det = np.linalg.det(M) if det == 0: raise np.linalg.LinAlgError, "invertable matrix" v = po.basis(1, order, dim, sort)[:size] coeffs = np.zeros((size, size)) if size == 2: coeffs = np.linalg.inv(M) else: for i in xrange(size): for j in xrange(size): coeffs[i, j] += np.linalg.det(M[1:, 1:]) M = np.roll(M, -1, axis=0) M = np.roll(M, -1, axis=1) coeffs /= det return po.sum(v * (coeffs.T), 1)
def lagrange_polynomial(X, sort="GR"): """ Lagrange Polynomials X : array_like Sample points where the lagrange polynomials shall be """ X = np.asfarray(X) if len(X.shape)==1: X = X.reshape(1,X.size) dim,size = X.shape order = 1 while ber.terms(order, dim)<=size: order += 1 indices = np.array(ber.bindex(1, order, dim, sort)[:size]) s,t = np.mgrid[:size, :size] M = np.prod(X.T[s]**indices[t], -1) det = np.linalg.det(M) if det==0: raise np.linalg.LinAlgError, "invertable matrix" v = po.basis(1, order, dim, sort)[:size] coeffs = np.zeros((size, size)) if size==2: coeffs = np.linalg.inv(M) else: for i in xrange(size): for j in xrange(size): coeffs[i,j] += np.linalg.det(M[1:,1:]) M = np.roll(M, -1, axis=0) M = np.roll(M, -1, axis=1) coeffs /= det return po.sum(v*(coeffs.T), 1)
def orth_bert(N, dist, normed=False, sort="GR"): """ # Stabilized process for generating orthogonal polynomials in a weighted function space. Add a comment to this line Parameters ---------- N : int The upper polynomial order. dist : Dist Weighting distribution(s) defining orthogonality. normed Returns ------- P : Poly The orthogonal polynomial expansion. Examples -------- >>> Z = cp.MvNormal([0,0], [[1,.5],[.5,1]]) >>> P = orth_bert(2, Z) >>> print P [1.0, q0, q1-0.5q0, q0^2-1.0, -0.5q0^2+q0q1, 0.25q0^2-0.75+q1^2-q0q1] """ dim = len(dist) sort = sort.upper() # Start orthogonalization x = po.basis(1,1,dim) if not ("R" in sort): x = x[::-1] foo = ber.Fourier_recursive(dist) # Create order=0 pool = [po.Poly(1, dim=dim, shape=())] # start loop M = ber.terms(N,dim) for i in xrange(1, M): par, ax0 = ber.parent(i, dim) gpar, ax1 = ber.parent(par, dim) oneup = ber.child(0, dim, ax0) # calculate rank to cut some terms rank = ber.multi_index(i, dim) while rank[-1]==0: rank = rank[:-1] rank = dim - len(rank) candi = x[ax0]*pool[par] for j in xrange(gpar, i): # cut irrelevant term if rank and np.any(ber.multi_index(j, dim)[-rank:]): continue A = foo(oneup, par, j) P = pool[j] candi = candi - P*A if normed: candi = candi/np.sqrt(foo(i, i, 0)) pool.append(candi) if "I" in sort: pool = pool[::-1] P = po.Poly([_.A for _ in pool], dim, (ber.terms(N, dim),)) return P
def orth_bert(N, dist, normed=False, sort="GR"): """ # Stabilized process for generating orthogonal polynomials in a weighted function space. Add a comment to this line Parameters ---------- N : int The upper polynomial order. dist : Dist Weighting distribution(s) defining orthogonality. normed Returns ------- P : Poly The orthogonal polynomial expansion. Examples -------- >>> Z = cp.MvNormal([0,0], [[1,.5],[.5,1]]) >>> P = orth_bert(2, Z) >>> print P [1.0, q0, q1-0.5q0, q0^2-1.0, -0.5q0^2+q0q1, 0.25q0^2-0.75+q1^2-q0q1] """ dim = len(dist) sort = sort.upper() # Start orthogonalization x = po.basis(1, 1, dim) if not ("R" in sort): x = x[::-1] foo = ber.Fourier_recursive(dist) # Create order=0 pool = [po.Poly(1, dim=dim, shape=())] # start loop M = ber.terms(N, dim) for i in xrange(1, M): par, ax0 = ber.parent(i, dim) gpar, ax1 = ber.parent(par, dim) oneup = ber.child(0, dim, ax0) # calculate rank to cut some terms rank = ber.multi_index(i, dim) while rank[-1] == 0: rank = rank[:-1] rank = dim - len(rank) candi = x[ax0] * pool[par] for j in xrange(gpar, i): # cut irrelevant term if rank and np.any(ber.multi_index(j, dim)[-rank:]): continue A = foo(oneup, par, j) P = pool[j] candi = candi - P * A if normed: candi = candi / np.sqrt(foo(i, i, 0)) pool.append(candi) if "I" in sort: pool = pool[::-1] P = po.Poly([_.A for _ in pool], dim, (ber.terms(N, dim), )) return P