plt.show(block=False) if 1 in TESTS: ########################################################## # TEST 1 import random maxvoleps = 1e-5 delta = 1e-5 xspan = [-1., 1.] d = 2 size1D = 31 maxord = 31 P = S1D.Poly1D(S1D.JACOBI, [0., 0.]) (x, w) = P.Quadrature(size1D) ords = [random.randrange(6, maxord) for i in range(d)] def f(X, params): return np.prod([ P.GradEvaluate(np.array([X[i]]), params['ords'][i], 0, norm=False) for i in range(len(X)) ]) X = [(S1D.JACOBI, S1D.GAUSS, (0., 0.), [-1., 1.]) for i in xrange(d)] orders = [size1D] * d params = {'ords': ords} surr_type = TT.PROJECTION STTapprox = TT.SQTT(f,
pN = 100 px = np.linspace(plot_span[0], plot_span[1], pN) pX, pY = np.meshgrid(px, px) pZ = np.zeros(pX.shape) for i in range(pN): for j in range(pN): pZ[i, j] = f(np.array([pX[i, j], pY[i, j]]), params) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(pX, pY, pZ) plt.title('Original') plt.show(block=False) # Quadrature rule construction (No need to change here a part from the comments) P = S1D.Poly1D(PolyType, PolyParams) X = [] W = [] for i in range(d): [x, w] = P.Quadrature(PolyOrd[i], QuadType, normed=False) x = (x + 1.) / 2. # The points are rescaled from [-1,1] to [0,1] X.append(x) w /= 2. # The weights are rescaled from |w|_1 = 2 to |w|_1 = 1 W.append(w) # The TensorWrapper is an object that wraps the user defined function and stores the computed values, # in case they need to be reused. This object has also some features allowing to see the indices of # the computed values and total number of function evaluations. TW = DT.TensorWrapper(f, X, params) # The TTapprox is the tensor-train approximation of the integrand. This is the part where the algorithm
def test(FNUM, GenzNormalized=False, SpectralType='Projection', GenzPatrick=False): # SpectralType = "Projection", "LinInterp", "PolyInterp" if SpectralType == "Projection": QuadType = S1D.GAUSS elif SpectralType == "PolyInterp": QuadType = S1D.GAUSSLOBATTO ######################################### # Genz functions ######################################### if not GenzPatrick: file_name_pat = "" if SpectralType == "Projection": sizes = range(2, 10) PolyType = S1D.JACOBI PolyParams = [0., 0.] elif SpectralType == "PolyInterp": sizes = range(2, 10) PolyType = S1D.JACOBI PolyParams = [0., 0.] elif SpectralType == "LinInterp": sizes = 2**np.arange(1, 8) if FNUM == 0: FUNC = 0 ds = [10, 50, 100, 200] elif FNUM == 1: FUNC = 1 ds = [10, 15, 20] elif FNUM == 2: FUNC = 2 ds = [10, 15, 20] elif FNUM == 3: FUNC = 3 ds = [10, 50, 100, 200] elif FNUM == 4: FUNC = 4 ds = [10, 50, 100] elif FNUM == 5: FUNC = 5 ds = [10, 15, 20] if GenzPatrick: file_name_pat = "Patrick" GenzNormalized = False if SpectralType == "Projection": sizes = range(2, 15) PolyType = S1D.JACOBI PolyParams = [0., 0.] elif SpectralType == "PolyInterp": sizes = range(2, 10) PolyType = S1D.JACOBI PolyParams = [0., 0.] elif SpectralType == "LinInterp": sizes = 2**np.arange(1, 8) if FNUM == 0: FUNC = 0 ds = [5] elif FNUM == 1: FUNC = 1 ds = [5] elif FNUM == 2: FUNC = 2 ds = [5] elif FNUM == 3: FUNC = 3 ds = [5] print "Function: " + str(FUNC) + " Norm: " + str( GenzNormalized) + " Dims: " + str(ds) + " Type: " + SpectralType colmap = plt.get_cmap('jet') cols = [colmap(i) for i in np.linspace(0, 1.0, len(ds))] N_EXP = 30 xspan = [0, 1] maxvoleps = 1e-10 delta = 1e-10 tt_maxit = 50 if not GenzNormalized: file_name_ext = "New" else: file_name_ext = "" MCestVarLimit = 1e-1 MCestMinIter = 100 MCestMaxIter = 1e6 MCstep = 10000 names = [ "Oscillatory", "Product Peak", "Corner Peak", "Gaussian", "Continuous", "Discontinuous" ] file_names = [ "Oscillatory", "ProductPeak", "CornerPeak", "Gaussian", "Continuous", "Discontinuous" ] # Iter size1D L2err = np.zeros((len(ds), N_EXP, len(sizes))) L2errVar = np.zeros((len(ds), N_EXP, len(sizes))) feval = np.zeros((len(ds), N_EXP, len(sizes)), dtype=int) for i_d, d in enumerate(ds): for n_exp in range(N_EXP): vol = (xspan[1] - xspan[0])**d expnts = np.array([1.5, 2.0, 2.0, 1.0, 2.0, 2.0]) dfclt = np.array([284.6, 725.0, 185.0, 70.3, 2040., 430.]) # dfclt = np.array([110., 600., 600., 100., 150., 100.]) if not GenzPatrick: csSum = dfclt / (float(d)**expnts) else: csSum = np.array([1.5, float(d), 1.85, 7.03, 20.4, 4.3]) # csSum = np.array([9., 7.25, 1.85, 7.03, 20.4, 4.3]) if FUNC != 5: ws = npr.random(d) elif FUNC == 5: # For function 5 let the discontinuity be cutting the space in two equiprobable regions beta = 1. alpha = np.exp(np.log(1. / 2.) / d) / (1 - np.exp(np.log(1. / 2.) / d)) * beta dd = stats.beta(alpha, beta) ws = dd.rvs(d) cs = npr.random(d) if GenzNormalized: cs *= csSum[FUNC] / np.sum(cs) params = {'ws': ws, 'cs': cs} if FUNC == 0: # Oscillatory def f(X, params): if X.ndim == 1: return np.cos(2. * np.pi * params['ws'][0] + np.sum(params['cs'] * X)) else: return np.cos(2. * np.pi * params['ws'][0] + np.sum( np.tile(params['cs'], (X.shape[0], 1)) * X, 1)) elif FUNC == 1: # Product peak def f(X, params): if X.ndim == 1: return np.prod( (params['cs']**-2. + (X - params['ws'])**2.)**-1.) else: return np.prod( (np.tile(params['cs'], (X.shape[0], 1))**-2. + (X - np.tile(params['ws'], (X.shape[0], 1)))**2.)**-1., 1) elif FUNC == 2: # Corner peak def f(X, params): if X.ndim == 1: return (1. + np.sum(params['cs'] * X))**(-(d + 1.)) else: return (1. + np.sum( np.tile(params['cs'], (X.shape[0], 1)) * X, 1))**(-(d + 1)) elif FUNC == 3: # Gaussian def f(X, params): if X.ndim == 1: return np.exp(-np.sum(params['cs']**2. * (X - params['ws'])**2.)) else: return np.exp(-np.sum( np.tile(params['cs'], (X.shape[0], 1))**2. * (X - np.tile(params['ws'], (X.shape[0], 1)))**2., 1)) elif FUNC == 4: # Continuous def f(X, params): if X.ndim == 1: return np.exp(-np.sum(params['cs'] * np.abs(X - params['ws']))) else: return np.exp(-np.sum( np.tile(params['cs'], (X.shape[0], 1)) * np.abs(X - np.tile(params['ws'], (X.shape[0], 1))), 1)) elif FUNC == 5: # Discontinuous (not C^0) def f(X, params): ws = params['ws'] / 2. + 0.25 # ws = params['ws'] if X.ndim == 1: if np.any(X > ws): return 0. else: return np.exp(np.sum(params['cs'] * X)) else: out = np.zeros(X.shape[0]) idxs = np.where( np.logical_not( np.any(X > np.tile(ws, (X.shape[0], 1)), axis=1)))[0] if len(idxs) == 1: out[idxs] = np.exp( np.sum(params['cs'] * X[idxs, :])) elif len(idxs) > 1: out[idxs] = np.exp( np.sum( np.tile(params['cs'], (len(idxs), 1)) * X[idxs, :], 1)) return out if d == 2: # Plot function pN = 40 px = np.linspace(0., 1., pN) pX, pY = np.meshgrid(px, px) pZ = np.zeros(pX.shape) for i in range(pN): for j in range(pN): pZ[i, j] = f(np.array([pX[i, j], pY[i, j]]), params) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(pX, pY, pZ) plt.title('Original') plt.show(block=False) for i_size, size in enumerate(sizes): size1D = size size = [size1D for i in range(d)] # Build up the 2d tensor wrapper if SpectralType == "Projection": P = S1D.Poly1D(PolyType, PolyParams) X = [] W = [] for i in range(d): [x, w] = P.Quadrature(size[i], QuadType, normed=False) x = (x + 1.) / 2. X.append(x) W.append(w) elif SpectralType == "LinInterp": X = [np.linspace(xspan[0], xspan[1], size[i])] * d elif SpectralType == "PolyInterp": P = S1D.Poly1D(PolyType, PolyParams) X = [] W = [] for i in range(d): [x, w] = P.Quadrature(size[i], QuadType, normed=False) x = (x + 1.) / 2. X.append(x) W.append(w) dims = [len(Xi) for Xi in X] TW = DT.TensorWrapper(f, X, params) # Construct TT approximation TTapprox = None TTapprox = DT.TTvec(TW) TTapprox.build(method='ttdmrgcross', delta=delta, mv_eps=maxvoleps, maxit=tt_maxit) print TTapprox.ranks() if d == 2 and IS_PLOTTING: # Plot TT approx ttX, ttY = np.meshgrid(X[0], X[1]) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(ttX, ttY, TTapprox.to_tensor()) plt.title('TT approx.') plt.show(block=False) if SpectralType == "Projection": # Construct spectral approximation Vs = [ P.GradVandermonde1D(X[i] * 2. - 1., size[i], 0, norm=True) for i in range(d) ] TTfour = TTapprox.project(Vs, W) # elif SpectralType == "PolyInterp": # # Construct spectral approximation # Vs = [P.GradVandermonde1D(X[i]*2.-1.,size[i],0,norm=True) for i in range(d)] # VsFlat = [ Vs[i].reshape((1,np.prod(Vs[i].shape))) for i in range(d)] # CCVs = DT.Candecomp(VsFlat) # TTVs = DT.TTmat(CCVs,nrows=[Vs[i].shape[0] for i in range(d)], ncols=[Vs[i].shape[1] for i in range(d)]) # (TTfour,conv,TT_info) = mla.gmres(TTVs, TTapprox,restart=20,eps=eps_gmres,ext_info=True) feval[i_d, n_exp, i_size] = TW.get_fill_level() if d == 2 and IS_PLOTTING: if SpectralType == "Projection": # Plot spectral approx VsI = [ P.GradVandermonde1D(px * 2. - 1., size[i], 0, norm=True) for i in range(d) ] TTval = TTfour.interpolate(VsI) elif SpectralType == "LinInterp": MsI = [ S1D.LinearInterpolationMatrix(X[i], px) for i in range(d) ] is_sparse = [True] * d TTval = TTapprox.interpolate(MsI, eps=1e-8, is_sparse=is_sparse) elif SpectralType == "PolyInterp": # VsI = [P.GradVandermonde1D(px*2.-1.,size[i],0,norm=True) for i in range(d)] bw = [S1D.BarycentricWeights(X[i]) for i in range(d)] MsI = [ S1D.LagrangeInterpolationMatrix(X[i], bw[i], px) for i in range(d) ] is_sparse = [False] * d TTval = TTapprox.interpolate(MsI, is_sparse=is_sparse) print 'L2 Grid err %e' % npla.norm(TTval.to_tensor() - pZ) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.plot_surface(pX, pY, TTval.to_tensor()) plt.title('Spectral approx.') plt.show(block=False) # Estimate L2error using Monte Carlo method VarI = 1. dist = stats.uniform() DIST = RS.MultiDimDistribution([dist] * d) intf = [] values = [] multi = 1 if SpectralType == "PolyInterp": bw = [S1D.BarycentricWeights(X[i]) for i in range(d)] while (len(values) < MCestMinIter or VarI > MCestVarLimit) and len(values) < MCestMaxIter: MCstep_loop = multi * MCstep - len(values) multi *= 2 # Monte Carlo xx = np.asarray(DIST.rvs(MCstep_loop)) if SpectralType == "Projection": VsI = None VsI = [ P.GradVandermonde1D(xx[:, i] * 2. - 1., size[i], 0, norm=True) for i in range(d) ] TTval = TTfour.interpolate(VsI) elif SpectralType == "LinInterp": MsI = None MsI = [ S1D.SparseLinearInterpolationMatrix( X[i], xx[:, i]).tocsr() for i in range(d) ] is_sparse = [True] * d TTval = TTapprox.interpolate(MsI, eps=1e-8, is_sparse=is_sparse) elif SpectralType == "PolyInterp": MsI = [ S1D.LagrangeInterpolationMatrix( X[i], bw[i], xx[:, i]) for i in range(d) ] is_sparse = [False] * d TTval = TTapprox.interpolate(MsI, is_sparse=is_sparse) # TTval = TTfour.interpolate(VsI) TTvals = [ TTval[tuple([i] * d)] for i in range(MCstep_loop) ] fval = f(xx, params) intf.extend(list(fval**2.)) values.extend( list((np.asarray(fval) - np.asarray(TTvals))**2.)) EstI = vol * np.mean(np.asarray(values)) VarI = (vol**2. * np.var(np.asarray(values)) / float(len(values))) # / EstI**2. # EstI = vol * np.mean( np.asarray(values) / np.asarray(intf) ) # VarI = (vol**2. * np.var( np.asarray(values) / np.asarray(intf) ) / float(len(values)) ) # mean = vol * np.mean(values) # var = vol**2. * np.var(values) / len(values) sys.stdout.write( "L2err estim. iter: %d Var: %e VarLim: %e L2err: %e \r" % (len(values), VarI, MCestVarLimit, np.sqrt(EstI) / np.sqrt(np.mean(intf)))) sys.stdout.flush() sys.stdout.write("\n") sys.stdout.flush() if GenzPatrick: L2err[i_d, n_exp, i_size] = np.sqrt(EstI) else: L2err[i_d, n_exp, i_size] = np.sqrt(EstI) / np.sqrt(np.mean(intf)) L2errVar[i_d, n_exp, i_size] = VarI if IS_PLOTTING: plt.figure(figsize=fsize) for i_d, d in enumerate(ds): for n_exp in range(N_EXP): plt.semilogy(sizes, L2err[i_d, n_exp, :], '.', color=cols[i_d]) plt.semilogy(sizes, np.mean(L2err[i_d, :, :], axis=0), 'o-', color=cols[i_d], label='d=%d' % d) plt.xlabel('Order') plt.ylabel('L2err') plt.subplots_adjust(bottom=0.15) plt.grid(True) plt.title(names[FUNC]) plt.legend(loc='best') if IS_STORING: path = FIG_FOLDER + "/" + SpectralType + "-" + file_names[ FUNC] + file_name_ext + "-" + "OrdVsL2err" plt.savefig(path + ".png", format="png") plt.savefig(path + ".pdf", format="pdf") plt.savefig(path + ".ps", format="ps") plt.figure(figsize=fsize) for i_d, d in enumerate(ds): for n_exp in range(N_EXP): plt.semilogy(feval[i_d, n_exp, :], L2err[i_d, n_exp, :], '.', color=cols[i_d]) plt.semilogy(np.mean(feval[i_d, :, :], axis=0), np.mean(L2err[i_d, :, :], axis=0), 'o-', color=cols[i_d], label='d=%d' % d) plt.xlabel('# func. eval') plt.ylabel('L2err') plt.subplots_adjust(bottom=0.15) plt.grid(True) plt.title(names[FUNC]) plt.legend(loc='best') plt.figure(figsize=fsize) for i_d, d in enumerate(ds): for n_exp in range(N_EXP): plt.loglog(feval[i_d, n_exp, :], L2err[i_d, n_exp, :], '.', color=cols[i_d]) plt.loglog(np.mean(feval[i_d, :, :], axis=0), np.mean(L2err[i_d, :, :], axis=0), 'o-', color=cols[i_d], label='d=%d' % d) plt.xlabel('# func. eval') plt.ylabel('L2err') plt.subplots_adjust(bottom=0.15) plt.grid(True) plt.title(names[FUNC]) plt.legend(loc='best') if IS_STORING: path = FIG_FOLDER + "/" + SpectralType + "-" + file_names[ FUNC] + file_name_ext + "-" + "convergence" plt.savefig(path + ".png", format="png") plt.savefig(path + ".pdf", format="pdf") plt.savefig(path + ".ps", format="ps") plt.figure(figsize=fsize) for i_d, d in enumerate(ds): for n_exp in range(N_EXP): plt.semilogy(sizes, feval[i_d, n_exp, :], '.', color=cols[i_d]) plt.semilogy(sizes, np.mean(feval[i_d, :, :], axis=0), 'o-', color=cols[i_d], label='d=%d' % d) plt.xlabel('Order') plt.ylabel('# func. eval') plt.subplots_adjust(bottom=0.15) plt.grid(True) plt.title(names[FUNC]) plt.legend(loc='best') if IS_STORING: path = FIG_FOLDER + "/" + SpectralType + "-" + file_names[ FUNC] + file_name_ext + "-" + "OrdVsFeval" plt.savefig(path + ".png", format="png") plt.savefig(path + ".pdf", format="pdf") plt.savefig(path + ".ps", format="ps") plt.show(block=False) if IS_STORING_DATA: d = {'feval': feval, 'L2err': L2err} if GenzPatrick: path = DAT_FOLDER + "/" + SpectralType + "-" + file_names[ FUNC] + file_name_ext + "-" + "data-Patrick.pkl" else: path = DAT_FOLDER + "/" + SpectralType + "-" + file_names[ FUNC] + file_name_ext + "-" + "data.pkl" ExtPython.storeVariables(d, path)
def run(maxprocs, PLOTTING=False, loglev=logging.WARNING): import numpy.linalg as npla logging.basicConfig(level=loglev) if PLOTTING: from matplotlib import pyplot as plt nsucc = 0 nfail = 0 ################ TEST 1 ########################### # Test folding/unfolding index function sys.stdout.write("Test folding/unfolding index function\r") sys.stdout.flush() dlist = (4, 2, 8) base = 2 dfold = [base for i in range(int(np.log(np.prod(dlist)) / np.log(base)))] A = np.arange(64).reshape(dlist) Aflat = A.flatten() Arsh = A.reshape(dfold) test = True err = [] for i in range(dlist[0]): for j in range(dlist[1]): for k in range(dlist[2]): idxs = (i, j, k) val = (A[idxs] == Aflat[DT.idxunfold(dlist, idxs)] and A[idxs] == Arsh[DT.idxfold( dfold, DT.idxunfold(dlist, idxs))]) if not val: err.append(idxs) test = False if test: print_ok("Test folding/unfolding index function") nsucc += 1 else: print_fail("Test folding/unfolding index function") nfail += 1 ################ TEST 2.1 ########################### # Test exponential N-dimensional vector (2^6 points) sys.stdout.write("Test exponential N-dimensional vector (2^6 points)\r") sys.stdout.flush() z = 2. q = 2 L = 6 N = q**L X = z**np.arange(N) TT = DT.QTTvec(X) TT.build() if TT.ranks() == [1 for i in range(L + 1)]: print_ok("Test exponential N-dimensional vector (2^6 points)") nsucc += 1 else: print_fail("Test exponential N-dimensional vector (2^6 points)") nfail += 1 ################ TEST 2.1b ########################### # Test exponential N-dimensional vector (28 points) sys.stdout.write("Test exponential N-dimensional vector (28 points)\r") sys.stdout.flush() z = 2. N = 28 X = z**np.arange(N) eps = 1e-6 TT = DT.QTTvec(X) TT.build(eps) L2err = npla.norm(TT.to_tensor() - X) if L2err <= eps: print_ok("Test exponential N-dimensional vector (28 points)") nsucc += 1 else: print_fail( "Test exponential N-dimensional vector (28 points): L2err=%e" % L2err) nfail += 1 ################ TEST 2.2 ########################### # Test sum of exponential N-dimensional vector sys.stdout.write("Test sum of exponential N-dimensional vector\r") sys.stdout.flush() import numpy.random as npr R = 3 z = npr.rand(R) c = npr.rand(R) q = 2 L = 8 N = q**L X = np.dot(c, np.tile(z, (N, 1)).T**np.tile(np.arange(N), (R, 1))) TT = DT.QTTvec(X) TT.build() if np.max(TT.ranks()) <= R: print_ok("Test sum of exponential N-dimensional vector") nsucc += 1 else: print_fail("Test sum of exponential N-dimensional vector") nfail += 1 ################ TEST 2.3 ########################### # Test sum of trigonometric N-dimensional vector sys.stdout.write("Test sum of trigonometric N-dimensional vector\r") sys.stdout.flush() import numpy.random as npr R = 3 a = npr.rand(R) c = npr.rand(R) q = 2 L = 8 N = q**L X = np.dot(c, np.sin(np.tile(z, (N, 1)).T * np.tile(np.arange(N), (R, 1)))) TT = DT.QTTvec(X) TT.build() if np.max(TT.ranks()) <= 2 * R: print_ok("Test sum of trigonometric N-dimensional vector") nsucc += 1 else: print_fail("Test sum of trigonometric N-dimensional vector") nfail += 1 ################ TEST 2.4 ########################### # Test sum of exponential-trigonometric N-dimensional vector sys.stdout.write( "Test sum of exponential-trigonometric N-dimensional vector\r") sys.stdout.flush() import numpy.random as npr R = 3 a = npr.rand(R) z = npr.rand(R) c = npr.rand(R) q = 2 L = 8 N = q**L X1 = np.tile(z, (N, 1)).T**np.tile(np.arange(N), (R, 1)) X2 = np.sin(np.tile(z, (N, 1)).T * np.tile(np.arange(N), (R, 1))) X = np.dot(c, X1 * X2) TT = DT.QTTvec(X) TT.build() if np.max(TT.ranks()) <= 2 * R: print_ok("Test sum of exponential-trigonometric N-dimensional vector") nsucc += 1 else: print_fail( "Test sum of exponential-trigonometric N-dimensional vector") nfail += 1 ################ TEST 2.4 ########################### # Test sum of exponential-trigonometric N-dimensional vector sys.stdout.write("Test Chebyshev polynomial vector\r") sys.stdout.flush() from SpectralToolbox import Spectral1D as S1D P = S1D.Poly1D(S1D.JACOBI, [-0.5, -0.5]) q = 2 L = 8 N = q**L (x, w) = P.GaussQuadrature(N - 1) X = P.GradEvaluate(x, N - 1, 0).flatten() TT = DT.QTTvec(X) TT.build() if np.max(TT.ranks()) <= 2: print_ok("Test Chebyshev polynomial vector") nsucc += 1 else: print_fail("Test Chebyshev polynomial vector") nfail += 1 ################ TEST 2.5 ########################### # Test N-dimensional vector sys.stdout.write("Test generic polynomial equidistant vector\r") sys.stdout.flush() from SpectralToolbox import Spectral1D as S1D import numpy.random as npr R = 100 c = npr.rand(R + 1) - 0.5 q = 2 L = 16 N = q**L x = np.linspace(-1, 1, N) X = np.dot(c, np.tile(x, (R + 1, 1))**np.tile(np.arange(R + 1), (N, 1)).T) TT = DT.QTTvec(X) TT.build(eps=1e-6) if np.max(TT.ranks()) <= R + 1: print_ok("Test generic polynomial (ord=%d) equidistant vector" % R) nsucc += 1 else: print_fail("Test generic polynomial (ord=%d) equidistant vector" % R) nfail += 1 ################ TEST 2.6 ########################### # Test N-dimensional vector sys.stdout.write("Test 1/(1+25x^2) Cheb vector\r") sys.stdout.flush() TT_eps = 1e-6 from SpectralToolbox import Spectral1D as S1D P = S1D.Poly1D(S1D.JACOBI, [-0.5, -0.5]) q = 2 L = 16 N = q**L (x, w) = P.GaussQuadrature(N - 1) X = 1. / (1. + 25. * x**2.) TT = DT.QTTvec(X) TT.build(eps=1e-6) import numpy.linalg as npla V = P.GradVandermonde1D(x, 60, 0) (xhat, res, rnk, s) = npla.lstsq(V, X) # Polynomial approximation is better print_ok( "Test 1/(1+25x^2) Cheb vector: Max-rank = %d, Size = %d, Poly-int res = %e" % (np.max(TT.ranks()), TT.size(), res)) nsucc += 1 # ################ TEST 2.7 ########################### # # Test discontinuos function N-dimensional vector # sys.stdout.write("Test discontinuous vector\r") # sys.stdout.flush() # TT_eps = 1e-6 # from SpectralToolbox import Spectral1D as S1D # P = S1D.Poly1D(S1D.JACOBI,[-0.5,-0.5]) # q = 2 # L = 16 # N = q**L # (x,w) = P.GaussQuadrature(N-1) # X = (x<-0.1).astype(float) - (x>0.1).astype(float) # TT = DT.QTTvec(X,q,eps=1e-6) # import numpy.linalg as npla # V = P.GradVandermonde1D(x,TT.size(),0) # (xhat,res,rnk,s) = npla.lstsq(V,X) # Polynomial approximation is better # print_ok("Test discontinuous vector: Max-rank = %d, Size = %d, Eps = %e, Poly-int res = %e" % (np.max(TT.ranks()),TT.size(),TT_eps,res)) ################# TEST 3.1 ########################## # Test d-dimensional Laplace operator # Scaling of storage for d-dimensional Laplace operator: # 1) Full tensor product: N^(2d) # 2) Sparse tensor product: ~ (3N)^d # 3) QTT format: 1D -> max-rank = 3: ~ 3*4*3*log2(N) # dD -> max-rank = 4: ~ d*4*4*4*log2(N) d = 4 span = np.array([0., 1.]) q = 2 L = 5 N = q**L h = 1 / float(N - 1) TT_round = 1e-13 D = -1. / h**2. * (np.diag(np.ones( (N - 1)), -1) + np.diag(np.ones( (N - 1)), 1) + np.diag(-2. * np.ones((N)), 0)) #D[0,0:2] = np.array([1.,0.]) #D[-1,-2:] = np.array([0.,1.]) D_tensor = DT.matkron_to_mattensor(D, nrows=N, ncols=N) TT_D = DT.QTTmat(D_tensor, base=q, nrows=N, ncols=N) TT_D.build(eps=TT_round) I = np.eye(N) I_tensor = DT.matkron_to_mattensor(I, nrows=N, ncols=N) TT_I = DT.QTTmat(I_tensor, base=q, nrows=N, ncols=N) TT_I.build(eps=TT_round) tt_list = [] for i in range(d): if i == 0: tmp = TT_D.copy() else: tmp = TT_I.copy() for j in range(1, d): if i == j: tmp.kron(TT_D) else: tmp.kron(TT_I) tt_list.append(tmp) TT_Dxy = np.sum(tt_list).rounding(TT_round) if d == 2 and N <= 8: sys.stdout.write("Test 2-dimensional laplace from kron of 1D QTTmat\r") sys.stdout.flush() Dd = np.zeros((N**d, N**d)) for i in range(d): tmp = np.array([1]) for j in range(d): if i != j: tmp = np.kron(tmp, I) else: tmp = np.kron(tmp, D) Dd += tmp # Check equality with Dd nrows = [N for i in range(d)] ncols = [N for i in range(d)] err = [] test = True for i in range(N**d): for j in range(N**d): sys.stdout.write("i = %d, j = %d \r" % (i, j)) sys.stdout.flush() if np.abs(Dd[i, j] - TT_Dxy[DT.idxfold(nrows, i), DT.idxfold(ncols, j)]) > TT_round: err.append((i, j)) test = False if test: print_ok("Test 2-dimensional laplace from kron of 1D QTTmat") nsucc += 1 else: print_fail("Test 2-dimensional laplace from kron of 1D QTTmat") nfail += 1 ################# TEST 3.2 ###################################### # Test 2-dimensional Laplace operator from full tensor product if d == 2 and N <= 8: sys.stdout.write("Test 2-dimensional laplace from full kron product\r") sys.stdout.flush() Dd = np.zeros((N**d, N**d)) for i in range(d): tmp = np.array([1]) for j in range(d): if i != j: tmp = np.kron(tmp, I) else: tmp = np.kron(tmp, D) Dd += tmp Dd_tensor = DT.matkron_to_mattensor(Dd, nrows=[N for i in range(d)], ncols=[N for i in range(d)]) TT_Dxykron = DT.QTTmat(Dd_tensor, base=q, nrows=[N for i in range(d)], ncols=[N for i in range(d)]) TT_Dxykron.build() # Check equality with Dd nrows = [N for i in range(d)] ncols = [N for i in range(d)] err = [] test = True for i in range(N**d): for j in range(N**d): sys.stdout.write("i = %d, j = %d \r" % (i, j)) sys.stdout.flush() if np.abs(Dd[i, j] - TT_Dxykron[DT.idxfold(nrows, i), DT.idxfold(ncols, j)]) > TT_round: err.append((i, j)) test = False if test: print_ok("Test 2-dimensional laplace from full kron product") nsucc += 1 else: print_fail("Test 2-dimensional laplace from full kron product") nfail += 1 ################# TEST 4.0 ######################################### # Solve the d-dimensional Dirichlet-Poisson equation using full matrices # Use Conjugate-Gradient method d = 3 span = np.array([0., 1.]) q = 2 L = 4 N = q**L h = 1 / float(N - 1) X = np.linspace(span[0], span[1], N) eps_cg = 1e-13 sys.stdout.write("%d-dim Dirichlet-Poisson problem FULL with CG\r" % d) sys.stdout.flush() try: # Construct d-D Laplace (with 2nd order finite diff) D = -1. / h**2. * (np.diag(np.ones( (N - 1)), -1) + np.diag(np.ones( (N - 1)), 1) + np.diag(-2. * np.ones((N)), 0)) D[0, 0:2] = np.array([1., 0.]) D[-1, -2:] = np.array([0., 1.]) D_sp = sp.coo_matrix(D) I_sp = sp.identity(N) I = np.eye(N) FULL_LAP = sp.coo_matrix((N**d, N**d)) for i in range(d): tmp = sp.identity((1)) for j in range(d): if i != j: tmp = sp.kron(tmp, I_sp) else: tmp = sp.kron(tmp, D_sp) FULL_LAP = FULL_LAP + tmp except MemoryError: print("FULL CG: Memory Error") dofull = False # Construct Right hand-side (b=1, Dirichlet BC = 0) b1D = np.ones(N) b1D[0] = 0. b1D[-1] = 0. tmp = np.array([1.]) for j in range(d): tmp = np.kron(tmp, b1D) FULL_b = tmp # Solve full system using npla.solve (FULL_RES, FULL_CONV) = spla.cg(FULL_LAP, FULL_b, tol=eps_cg) if PLOTTING and d == 2: from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm X = np.linspace(span[0], span[1], N) (XX, YY) = np.meshgrid(X, X) fig = plt.figure(figsize=(14, 10)) ################# TEST 4.1 ######################################### # Solve the 2-dimensional Dirichlet-Poisson equation using QTTmat and QTTvec # Use Conjugate-Gradient method sys.stdout.write( "%d-dim Dirichlet-Poisson problem QTTmat,QTTvec with CG\r" % d) sys.stdout.flush() TT_round = 1e-8 eps_cg = 1e-3 # Laplace operator D = -1. / h**2. * (np.diag(np.ones( (N - 1)), -1) + np.diag(np.ones( (N - 1)), 1) + np.diag(-2. * np.ones((N)), 0)) D[0, 0:2] = np.array([1., 0.]) D[-1, -2:] = np.array([0., 1.]) D_tensor = DT.matkron_to_mattensor(D, nrows=N, ncols=N) TT_D = DT.QTTmat(D_tensor, base=q, nrows=N, ncols=N) TT_D.build(eps=TT_round) I = np.eye(N) I_tensor = DT.matkron_to_mattensor(I, nrows=N, ncols=N) TT_I = DT.QTTmat(I_tensor, base=q, nrows=N, ncols=N) TT_I.build(eps=TT_round) tt_list = [] for i in range(d): if i == 0: tmp = TT_D.copy() else: tmp = TT_I.copy() for j in range(1, d): if i == j: tmp.kron(TT_D) else: tmp.kron(TT_I) tt_list.append(tmp) TT_Dxy = np.sum(tt_list).rounding(TT_round) # Right hand side b1D = np.ones(N) b1D[0] = 0. b1D[-1] = 0. B = np.array([1.]) for j in range(d): B = np.kron(B, b1D) B = np.reshape(B, [N for i in range(d)]) TT_B = DT.QTTvec(B) TT_B.build(TT_round) # Solve QTT cg x0 = DT.QTTzerosvec(d=d, N=N, base=q) cg_start = time.clock() (TT_RES, TT_conv, TT_info) = mla.cg(TT_Dxy, TT_B, x0=x0, eps=eps_cg, ext_info=True, eps_round=TT_round) cg_stop = time.clock() L2err = mla.norm( TT_RES.to_tensor().reshape([N for i in range(d)]) - FULL_RES.reshape([N for i in range(d)]), 'fro') if L2err < eps_cg: print_ok( "%d-dim Dirichlet-Poisson problem QTTmat,QTTvec with CG [PASSED] Time: %.10f\n" % (d, cg_stop - cg_start)) nsucc += 1 else: print_fail( "%d-dim Dirichlet-Poisson problem QTTmat,QTTvec with CG [FAILED] L2err: %.e\n" % (d, L2err)) nfail += 1 if PLOTTING and d == 2: # Plot function ax = fig.add_subplot(321, projection='3d') ax.plot_surface(XX, YY, TT_RES.to_tensor().reshape((N, N)), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax = fig.add_subplot(322, projection='3d') ax.plot_surface(XX, YY, np.abs(TT_RES.to_tensor().reshape((N, N)) - FULL_RES.reshape((N, N))), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) plt.show(block=False) ################# TEST 4.2 ######################################### # Solve the 2-dimensional Dirichlet-Poisson equation using QTTmat and np.ndarray # Use Conjugate-Gradient method sys.stdout.write( "%d-dim Dirichlet-Poisson problem QTTmat,ndarray with CG\r" % d) sys.stdout.flush() TT_round = 1e-8 eps_cg = 1e-3 # Laplace operator D = -1. / h**2. * (np.diag(np.ones( (N - 1)), -1) + np.diag(np.ones( (N - 1)), 1) + np.diag(-2. * np.ones((N)), 0)) D[0, 0:2] = np.array([1., 0.]) D[-1, -2:] = np.array([0., 1.]) D_tensor = DT.matkron_to_mattensor(D, nrows=N, ncols=N) TT_D = DT.QTTmat(D_tensor, base=q, nrows=N, ncols=N) TT_D.build(eps=TT_round) I = np.eye(N) I_tensor = DT.matkron_to_mattensor(I, nrows=N, ncols=N) TT_I = DT.QTTmat(I_tensor, base=q, nrows=N, ncols=N) TT_I.build(eps=TT_round) tt_list = [] for i in range(d): if i == 0: tmp = TT_D.copy() else: tmp = TT_I.copy() for j in range(1, d): if i == j: tmp.kron(TT_D) else: tmp.kron(TT_I) tt_list.append(tmp) TT_Dxy = np.sum(tt_list).rounding(TT_round) # Right hand side b1D = np.ones(N) b1D[0] = 0. b1D[-1] = 0. B = np.array([1.]) for j in range(d): B = np.kron(B, b1D) B = np.reshape(B, [N for i in range(d)]) B = np.reshape(B, [q for i in range(d * L)]) # Solve QTT cg x0 = np.zeros([q for i in range(d * L)]) cg_start = time.clock() (ARR_RES, TT_conv, TT_info1) = mla.cg(TT_Dxy, B, x0=x0, eps=eps_cg, ext_info=True, eps_round=TT_round) cg_stop = time.clock() L2err = mla.norm( ARR_RES.reshape([N for i in range(d)]) - FULL_RES.reshape([N for i in range(d)]), 'fro') if L2err < eps_cg: print_ok( "%d-dim Dirichlet-Poisson problem QTTmat,ndarray with CG [PASSED] Time: %.10f" % (d, cg_stop - cg_start)) nsucc += 1 else: print_fail( "%d-dim Dirichlet-Poisson problem QTTmat,ndarray with CG [FAILED] L2err: %.e" % (d, L2err)) nfail += 1 if PLOTTING and d == 2: # Plot function ax = fig.add_subplot(323, projection='3d') ax.plot_surface(XX, YY, ARR_RES.reshape((N, N)), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) ax = fig.add_subplot(324, projection='3d') ax.plot_surface( XX, YY, np.abs(ARR_RES.reshape((N, N)) - FULL_RES.reshape((N, N))), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False) plt.show(block=False) # ################# TEST 4.3 ######################################### # # Solve the 2-dimensional Dirichlet-Poisson equation using QTTmat and np.ndarray # # Use Preconditioned Conjugate-Gradient method # sys.stdout.write("%d-dim Dirichlet-Poisson problem QTTmat,ndarray with Prec-CG\r" % d) # sys.stdout.flush() # TT_round = 1e-8 # eps_cg = 1e-3 # # Laplace operator # D = -1./h**2. * ( np.diag(np.ones((N-1)),-1) + np.diag(np.ones((N-1)),1) + np.diag(-2.*np.ones((N)),0) ) # D[0,0:2] = np.array([1.,0.]) # D[-1,-2:] = np.array([0.,1.]) # D_tensor = DT.matkron_to_mattensor(D,nrows=N,ncols=N) # TT_D = DT.QTTmat(D_tensor, base=q,nrows=N,ncols=N,eps=TT_round) # I = np.eye(N) # I_tensor = DT.matkron_to_mattensor(I,nrows=N,ncols=N) # TT_I = DT.QTTmat(I_tensor,base=q,nrows=N,ncols=N,eps=TT_round) # tt_list = [] # for i in range(d): # if i == 0: tmp = TT_D.copy() # else: tmp = TT_I.copy() # for j in range(1,d): # if i == j: tmp.kron(TT_D) # else: tmp.kron(TT_I) # tt_list.append(tmp) # TT_Dxy = np.sum(tt_list).rounding(TT_round) # # Construct Preconditioner using Newton-iterations # TT_II = TT_I.copy() # for j in range(1,d): TT_II.kron(TT_I) # alpha = 1e-6 # TT_Pround = 1e-4 # TT_P = alpha*TT_II # eps = mla.norm(TT_II-mla.dot(TT_Dxy,TT_P),'fro')/mla.norm(TT_II,'fro') # i = 0 # while eps > 5.*1e-1: # i += 1 # TT_P = (2. * TT_P - mla.dot(TT_P,mla.dot(TT_Dxy,TT_P).rounding(TT_Pround)).rounding(TT_Pround)).rounding(TT_Pround) # eps = mla.norm(TT_II-mla.dot(TT_Dxy,TT_P),'fro')/mla.norm(TT_II,'fro') # sys.stdout.write("\033[K") # sys.stdout.write("Prec: err=%e, iter=%d\r" % (eps,i)) # sys.stdout.flush() # # Right hand side # b1D = np.ones(N) # b1D[0] = 0. # b1D[-1] = 0. # B = np.array([1.]) # for j in range(d): # B = np.kron(B,b1D) # B = np.reshape(B,[N for i in range(d)]) # B = np.reshape(B,[q for i in range(d*L)]) # # Solve QTT cg # x0 = np.zeros([q for i in range(d*L)]) # # Precondition # TT_DP = mla.dot(TT_P,TT_Dxy).rounding(TT_round) # BP = mla.dot(TT_P,B) # cg_start = time.clock() # (ARR_RES,TT_conv,TT_info) = mla.cg(TT_DP,BP,x0=x0,eps=eps_cg,ext_info=True,eps_round=TT_round) # cg_stop = time.clock() # L2err = mla.norm(ARR_RES.reshape([N for i in range(d)])-FULL_RES.reshape([N for i in range(d)]), 'fro') # if L2err < eps_cg: # print_ok("%d-dim Dirichlet-Poisson problem QTTmat,ndarray with Prec-CG [PASSED] Time: %.10f" % (d, cg_stop-cg_start)) # else: # print_fail("%d-dim Dirichlet-Poisson problem QTTmat,ndarray with Prec-CG [FAILED] L2err: %.e" % (d,L2err)) # if PLOTTING and d == 2: # # Plot function # ax = fig.add_subplot(325,projection='3d') # ax.plot_surface(XX,YY,ARR_RES.reshape((N,N)),rstride=1, cstride=1, cmap=cm.coolwarm, # linewidth=0, antialiased=False) # ax = fig.add_subplot(326,projection='3d') # ax.plot_surface(XX,YY,np.abs(ARR_RES.reshape((N,N))-FULL_RES.reshape((N,N))),rstride=1, cstride=1, cmap=cm.coolwarm, # linewidth=0, antialiased=False) # plt.show(block=False) print_summary("QTT", nsucc, nfail) return (nsucc, nfail)