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
Exemple #3
0
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)
Exemple #4
0
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)