def norm(order, dist, orth=None): dim = len(dist) try: if dim > 1: norms = np.array([norm(order + 1, D) for D in dist]) Is = ber.bindex(order, dim) out = np.ones(len(Is)) for i in xrange(len(Is)): I = Is[i] for j in xrange(dim): if I[j]: out[i] *= norms[j, I[j]] return out K = range(1, order + 1) ttr = [1.] + [dist.ttr(k)[1] for k in K] return np.cumprod(ttr) except NotImplementedError: if orth is None: orth = orth_chol(order, dist) return E(orth**2, dist)
def norm(order, dist, orth=None): dim = len(dist) try: if dim>1: norms = np.array([norm(order+1, D) for D in dist]) Is = ber.bindex(order, dim) out = np.ones(len(Is)) for i in xrange(len(Is)): I = Is[i] for j in xrange(dim): if I[j]: out[i] *= norms[j, I[j]] return out K = range(1,order+1) ttr = [1.] + [dist.ttr(k)[1] for k in K] return np.cumprod(ttr) except NotImplementedError: if orth is None: orth = orth_chol(order, dist) return E(orth**2, dist)
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_ttr(order, dist, normed=False, sort="GR", retall=False, **kws): """ Create orthogonal polynomial expansion from three terms recursion formula. Parameters ---------- order : int Order of polynomial expansion dist : Dist Distribution space where polynomials are orthogonal If dist.ttr exists, it will be used, othervice Clenshaw-Curtis integration will be used. Must be stochastically independent. normed : bool If True orthonormal polynomials will be used instead of monic. sort : str Polynomial sorting. Same as in basis retall : bool If true return norms as well. kws : optional Keyword argument passed to stieltjes method. Returns ------- orth[, norms] orth : Poly Orthogonal polynomial expansion norms : np.ndarray Norms of the orthogonal expansion on the form E(orth**2, dist) Calculated using recurrence coefficients for stability. Examples -------- >>> Z = cp.Normal() >>> print cp.orth_ttr(4, Z) [1.0, q0, q0^2-1.0, q0^3-3.0q0, -6.0q0^2+3.0+q0^4] """ P, norms, A, B = qu.stieltjes(dist, order, retall=True, **kws) if normed: for i in xrange(len(P)): P[i] = P[i]/np.sqrt(norms[:,i]) norms = norms**0 dim = len(dist) if dim>1: Q, G = [], [] indices = ber.bindex(0,order,dim,sort) for I in indices: q = [P[I[i]][i] for i in xrange(dim)] q = reduce(lambda x,y: x*y, q) Q.append(q) if retall: for I in indices: g = [norms[i,I[i]] for i in xrange(dim)] G.append(np.prod(g)) P = Q else: G = norms[0] P = po.flatten(po.Poly(P)) if retall: return P, np.array(G) return P
def orth_ttr(order, dist, normed=False, sort="GR", retall=False, **kws): """ Create orthogonal polynomial expansion from three terms recursion formula. Parameters ---------- order : int Order of polynomial expansion dist : Dist Distribution space where polynomials are orthogonal If dist.ttr exists, it will be used, othervice Clenshaw-Curtis integration will be used. Must be stochastically independent. normed : bool If True orthonormal polynomials will be used instead of monic. sort : str Polynomial sorting. Same as in basis retall : bool If true return norms as well. kws : optional Keyword argument passed to stieltjes method. Returns ------- orth[, norms] orth : Poly Orthogonal polynomial expansion norms : np.ndarray Norms of the orthogonal expansion on the form E(orth**2, dist) Calculated using recurrence coefficients for stability. Examples -------- >>> Z = cp.Normal() >>> print cp.orth_ttr(4, Z) [1.0, q0, q0^2-1.0, q0^3-3.0q0, -6.0q0^2+3.0+q0^4] """ P, norms, A, B = qu.stieltjes(dist, order, retall=True, **kws) if normed: for i in xrange(len(P)): P[i] = P[i] / np.sqrt(norms[:, i]) norms = norms**0 dim = len(dist) if dim > 1: Q, G = [], [] indices = ber.bindex(0, order, dim, sort) for I in indices: q = [P[I[i]][i] for i in xrange(dim)] q = reduce(lambda x, y: x * y, q) Q.append(q) if retall: for I in indices: g = [norms[i, I[i]] for i in xrange(dim)] G.append(np.prod(g)) P = Q else: G = norms[0] P = po.flatten(po.Poly(P)) if retall: return P, np.array(G) return P