Пример #1
0
def preserves_hermitian_form(SL2C_matrices):
    """
    >>> CC = ComplexField(100)
    >>> A = matrix(CC, [[1, 1], [1, 2]]);
    >>> B = matrix(CC, [[0, 1], [-1, 0]])
    >>> C = matrix(CC, [[CC('I'),0], [0, -CC('I')]])
    >>> ans, sig, form = preserves_hermitian_form([A, B])
    >>> ans
    True
    >>> sig
    'indefinite'
    >>> form.change_ring(ComplexField(10))
    [  0.00 -1.0*I]
    [ 1.0*I   0.00]
    >>> preserves_hermitian_form([A, B, C])
    (False, None, None)
    >>> ans, sig, form = preserves_hermitian_form([B, C])
    >>> sig
    'definite'
    """
    M = block_matrix(len(SL2C_matrices), 1, [
        left_mult_by_adjoint(A) - right_mult_by_inverse(A)
        for A in SL2C_matrices
    ])

    CC = M.base_ring()
    mp.prec = CC.prec()
    RR = RealField(CC.prec())
    epsilon = RR(2)**(-int(0.8 * mp.prec))
    U, S, V = mp.svd(sage_matrix_to_mpmath(M))
    S = list(mp.chop(S, epsilon))
    if mp.zero not in S:
        return False, None, None
    elif S.count(mp.zero) > 1:
        for i, A in enumerate(SL2C_matrices):
            for B in SL2C_matrices[i + 1:]:
                assert (A * B - B * A).norm() < epsilon

        sig = 'indefinite' if any(abs(A.trace()) > 2
                                  for A in SL2C_matrices) else 'both'
        return True, sig, None
    else:
        in_kernel = list(mp.chop(V.H.column(S.index(mp.zero))))
        J = mp.matrix([in_kernel[:2], in_kernel[2:]])
        iJ = mp.mpc(imag=1) * J
        J1, J2 = J + J.H, iJ + iJ.H
        J = J1 if mp.norm(J1) >= mp.norm(J2) else J2
        J = (1 / mp.sqrt(abs(mp.det(J)))) * J
        J = mpmath_matrix_to_sage(J)
        assert all((A.conjugate_transpose() * J * A - J).norm() < epsilon
                   for A in SL2C_matrices)
        sig = 'definite' if J.det() > 0 else 'indefinite'
        return True, sig, J
def plot_C_pi():
    C = []
    for m in [0, 1]:
        Cm = []
        for i in range(0, len(lmx)):
            Crow = []
            for j in range(0, len(lmy)):
                if m == 0:
                    Crow.append(1)
                if m == 1:
                    Crow.append(
                        float(
                            mp.norm(-mp.exp(1j * (mp.atan(
                                mp.im(eq5.fl(lmx[i][j], lmy[i][j], 0)) /
                                mp.re(eq5.fl(lmx[i][j], lmx[i][j], 0))))))))
            Cm.append(Crow)
        C.append(Cm)

    for m in range(0, len(C)):
        plt.figure()
        plt.title("C matrix for band pi, element number " + str(m))
        plt.contourf(lmx, lmy, C[m], cmap=plt.get_cmap("coolwarm"))
        plt.colorbar()
        plt.xlabel(r'$l_x$ $[m^{-1}]$')
        plt.ylabel(r'$l_y$ $[m^{-1}]$')
Пример #3
0
 def two_body_reference(self, t1, num_1 = 0, num_2 = 1):
     """ reference notations are same as Yoel's notes
     using a precision of 64 digits for max accuracy """
     mp.dps = 64
     self.load_data()
     t1 = mp.mpf(t1)
     m_1 = mp.mpf(self.planet_lst[num_1].mass)
     m_2 = mp.mpf(self.planet_lst[num_2].mass)
     x1_0 = mp.matrix(self.planet_lst[num_1].loc)
     x2_0 = mp.matrix(self.planet_lst[num_2].loc)
     v1_0 = mp.matrix(self.planet_lst[num_1].v)
     v2_0 = mp.matrix(self.planet_lst[num_2].v)
     M = m_1 + m_2
     x_cm = (1/M)*((m_1*x1_0)+(m_2*x2_0))
     v_cm = (1/M)*((m_1*v1_0)+(m_2*v2_0))
     u1_0 = v1_0 - v_cm
     w = x1_0 - x_cm
     r_0 = mp.norm(w)
     alpha = mp.acos((np.inner(u1_0,w))/(mp.norm(u1_0)*mp.norm(w)))
     K = mp.mpf(self.G) * (m_2**3)/(M**2)
     u1_0 = mp.norm(u1_0)
     L = r_0 * u1_0 * mp.sin(alpha)
     cosgamma = ((L**2)/(K*r_0)) - 1
     singamma = -((L*u1_0*mp.cos(alpha))/K)
     gamma = mp.atan2(singamma, cosgamma)
     e = mp.sqrt(((r_0*(u1_0**2)*(mp.sin(alpha)**2)/K)-1)**2 + \
              (((r_0**2)*(u1_0**4)*(mp.sin(alpha)**2)*(mp.cos(alpha)**2))/(K**2)) )        
     r_theta = lambda theta: (L**2)/(K*(1+(e*mp.cos(theta - gamma))))
     f = lambda x: r_theta(x)**2/L
     curr_theta = 0
     max_it = 30
     it = 1
     converged = 0
     while ((it < max_it) & (converged != 1)):
         t_val = mp.quad(f,[0,curr_theta]) - t1
         dt_val = f(curr_theta)
         delta = t_val/dt_val
         if (abs(delta)<1.0e-6):
             converged = 1
         curr_theta -= delta
         it += 1 
     x1_new = mp.matrix([r_theta(curr_theta)*mp.cos(curr_theta), r_theta(curr_theta)*mp.sin(curr_theta)]) 
     # x2_new = -(m_1/m_2)*(x1_new) +(x_cm + v_cm*t1)
     x1_new = x1_new + (x_cm + v_cm*t1)
     return x1_new
Пример #4
0
 def __init__(self, side, extended, distance):
     self.distance = mp.mpf(distance)
     rightPointX = mp.mpf('1.41949302') if extended else mp.sqrt(2)
     self.side = side  # side length of square
     self.d = side / mp.cos(mp.pi / 12)  # length of left edge
     sin60 = mp.sqrt(3) / 2
     self.top = matrix([self.d / 2, sin60 * self.d])
     self.right = matrix([side * rightPointX, 0])
     self.nleft = matrix([[-sin60, 0.5]])
     self.ndown = matrix([[0, -1]])
     v = self.right - self.top
     norm = mp.norm(v)
     self.nright = matrix([[-v[1] / norm, v[0] / norm]])
     self.offset = self.nright * self.right
Пример #5
0
 def verify(self, x0, x1, y0, y1, s, t, x, y):
     "Verify the transformation given by (s, t, x, y) on pentagon."
     pentagon = [(x0, 0), (x1, 0), (0, y0), (0, y1), (self.side, self.side)]
     # reference point in interior of pentagon
     ref = matrix([x0 + x1 + self.side, y0 + y1 + self.side]) / 5
     translation = matrix(
         [s * ref[0] + t * ref[1] + x, -t * ref[0] + s * ref[1] + y])
     # reconstruct rotation angle
     norm = mp.sqrt(s * s + t * t)
     if t < 0:
         angle = -mp.acos(s / norm)
     else:
         angle = mp.acos(s / norm)
     rotation = matrix([[mp.cos(angle), mp.sin(angle)],
                        [-mp.sin(angle), mp.cos(angle)]])
     pentagon = list(map(lambda pt: matrix(pt), pentagon))
     ipentagon = list(
         map(lambda pt: rotation * (pt - ref) + translation, pentagon))
     # Verify that ipentagon is a congruent image of pentagon
     eps = mp.mpf(10)**-(mp.dps - 2)  # accept error in last two digits
     for i in range(5):
         for j in range(i + 1, 5):
             d1 = mp.norm(pentagon[j] - pentagon[i])
             d2 = mp.norm(ipentagon[j] - ipentagon[i])
             dd = abs(d1 - d2)
             assert dd < eps, (pentagon, dd, eps)
     dists = []
     for p in ipentagon:
         dists.append(self.nleft * p)
         dists.append(self.ndown * p)
         dists.append(self.nright * p - self.offset)
     dist = max(map(lambda m: m[0], dists))
     if dist > -self.distance:
         sys.stderr.write("Pentagon failing slack test: %d %d %d %d\n" %
                          (x0, x1, y0, y1))
         return False
     return True
Пример #6
0
def solve_multiprecision(M, A, b, tolerance=1e-60):
    af = sparse_make_single_precision(M, A)
    so = sp.sparse.linalg.factorized(af)

    def solve(b):
        b = _TO_NUMPY(b).flatten()
        x = so(b)
        return FROM_NUMPY(x)

    """
    def solve(b):
        b = _TO_NUMPY(b)
        x, e = sp.sparse.linalg.gmres(af, b)
        if e != 0:
            print("error", e)
            raise Exception("gmres error")
        return FROM_NUMPY(x)
    """
    x = solve(b)
    current_prec = mp.prec
    try:
        guess = np.log2(M) - np.log2(tolerance) + 24
        mp.prec = guess
        while True:
            residual = b - mmul(A, x)
            scale = mp.norm(residual, p='inf')
            print("residual: %e" % scale)
            if scale < tolerance:
                return x
            compare = solve(residual / scale)
            x += scale * compare
            amplification = float(mp.norm(compare, p='inf'))
            mp.prec = max(mp.prec, guess + np.log2(amplification))
            print("precision:", mp.prec)
    finally:
        mp.prec = current_prec
Пример #7
0
def nearly_diagonal(A):
    assert A.rows == A.cols == 2
    a = A[0, 0]
    return mp.norm(A - mp.diag([a, a])) < 1000 * mp.eps
Пример #8
0
def w2s(kx, ky, kz):
    return ct.nrm_s * ct.a0**(3 / 2) * (
        ((ct.a0 * mp.norm([kx, ky, kz])) / ct.hbar)**2 -
        (ct.Zeff2s / 2)**2) / (((ct.a0 * mp.norm([kx, ky, kz])) / ct.hbar)**2 +
                               (ct.Zeff2s / 2)**2)**3
Пример #9
0
def w2py(kx, ky, kz):
    return ct.nrm_py * ct.a0**(5 / 2) * (ky / ct.hbar) / (
        (ct.a0 * mp.norm([kx, ky, kz]) / ct.hbar)**2 + (ct.Zeff2pxy / 2)**2)**3
Пример #10
0
def w2pz(kx, ky, kz):
    return ct.nrm_pz * ct.a0**(5 / 2) * (kz / ct.hbar) / (
        (ct.a0 * mp.norm([kx, ky, kz]) / ct.hbar)**2 + (ct.Zeff2pz / 2)**2)**3
Пример #11
0
def speedup_Green_Taylor_Arnoldi_RgNmn_Uconverge(n,
                                                 k,
                                                 R,
                                                 klim=10,
                                                 Taylor_tol=1e-8,
                                                 invchi=0.1,
                                                 Unormtol=1e-4,
                                                 veclim=3,
                                                 delveclim=2,
                                                 plotVectors=False):
    #sets up the Arnoldi matrix and associated unit vector lists for any given RgN
    #ti = time.time()

    kR = mp.mpf(k * R)
    pow_jndiv, coe_jndiv, pow_djn, coe_djn, pow_yndiv, coe_yndiv, pow_dyn, coe_dyn = get_Taylor_jndiv_djn_yndiv_dyn(
        n, kR, klim, tol=Taylor_tol)
    #print(time.time()-ti,'0')

    #print(len(pow_jndiv))
    pow_jndiv = np.array(pow_jndiv)
    pow_djn = np.array(pow_djn)
    nfac = mp.sqrt(n * (n + 1))
    rmRgN_Bpol = mp.one * np.zeros(pow_jndiv[-1] + 1 - (n - 1))
    rmRgN_Ppol = mp.one * np.zeros(pow_jndiv[-1] + 1 - (n - 1))
    rmRgN_Bpol[pow_jndiv - (n - 1)] += coe_jndiv
    rmRgN_Bpol[pow_djn - (n - 1)] += coe_djn
    rmRgN_Ppol[pow_jndiv - (n - 1)] += coe_jndiv
    rmRgN_Ppol *= nfac

    rmRgN_Bpol = po.Polynomial(rmRgN_Bpol)
    rmRgN_Ppol = po.Polynomial(rmRgN_Ppol)

    rnImN_Bpol = mp.one * np.zeros(pow_yndiv[-1] + 1 + (n + 2),
                                   dtype=np.complex)
    rnImN_Ppol = mp.one * np.zeros(pow_yndiv[-1] + 1 + (n + 2),
                                   dtype=np.complex)
    pow_yndiv = np.array(pow_yndiv)
    pow_dyn = np.array(pow_dyn)
    rnImN_Bpol[(n + 2) + pow_yndiv] += coe_yndiv
    rnImN_Bpol[(n + 2) + pow_dyn] += coe_dyn
    rnImN_Ppol[(n + 2) + pow_yndiv] += coe_yndiv
    rnImN_Ppol *= nfac

    rnImN_Bpol = po.Polynomial(rnImN_Bpol)
    rnImN_Ppol = po.Polynomial(rnImN_Ppol)

    if plotVectors:
        plot_rmnNpol(n, rmRgN_Bpol.coef, rmRgN_Ppol.coef, kR * 0.01, kR)

    unitrmnBpols = []
    unitrmnPpols = []
    #print(time.time()-ti,'1')
    RgNnorm = mp.sqrt(rmnNnormsqr_Taylor(n, k, R, rmRgN_Bpol, rmRgN_Ppol))
    rmnBpol = rmRgN_Bpol / RgNnorm
    rmnPpol = rmRgN_Ppol / RgNnorm
    unitrmnBpols.append(rmnBpol)
    unitrmnPpols.append(rmnPpol)
    #print(time.time()-ti,'2')
    rmnGBpol, rmnGPpol = rmnGreen_Taylor_Nmn_vec(n, k, R, rmRgN_Bpol,
                                                 rmRgN_Ppol, rnImN_Bpol,
                                                 rnImN_Ppol, rmnBpol, rmnPpol)
    rmnGBpol = rmnGBpol.cutdeg(rmRgN_Bpol.degree())
    rmnGPpol = rmnGPpol.cutdeg(rmRgN_Bpol.degree())
    #print(time.time()-ti,'3')
    prefactpow, Upol = rmnNpol_dot(2 * n - 2, rmnBpol, rmnPpol, rmnGBpol,
                                   rmnGPpol)
    Uinv = mp.matrix([[invchi - kR**prefactpow * po.polyval(kR, Upol) / k**3]])
    unitrmnBpols.append(rmnGBpol)
    unitrmnPpols.append(rmnGPpol)  #set up beginning of Arnoldi iteration
    #print(time.time()-ti,'4')
    b = mp.matrix([mp.one])
    prevUnorm = 1 / Uinv[0, 0]

    i = 1
    while i < veclim:
        speedup_Green_Taylor_Arnoldi_step_RgNmn(n,
                                                k,
                                                R,
                                                invchi,
                                                rmRgN_Bpol,
                                                rmRgN_Ppol,
                                                rnImN_Bpol,
                                                rnImN_Ppol,
                                                unitrmnBpols,
                                                unitrmnPpols,
                                                Uinv,
                                                plotVectors=plotVectors)
        i += 1
        if i == veclim:
            #solve for first column of U and see if its norm has converged
            b.rows = i
            x = mp.lu_solve(Uinv, b)
            Unorm = mp.norm(x)
            if np.abs(prevUnorm - Unorm) > np.abs(Unorm) * Unormtol:
                veclim += delveclim
                prevUnorm = Unorm
            #else: print(x)

    if veclim == 1:
        x = mp.one / Uinv[0, 0]
    """
    #print(x)
    print(mp.norm(x))
    plt.figure()
    plt.matshow(np.abs(np.array((Uinv**-1).tolist(),dtype=np.complex)))
    plt.show()
    #EUdUinv = mpmath.eigh(Uinv.transpose_conj()*Uinv, eigvals_only=True)
    #print(EUdUinv)
    #print(type(EUdUinv))
    """
    #print(time.time()-ti,'5')
    #returns everything necessary to potentially extend size of Uinv matrix later
    return rmRgN_Bpol, rmRgN_Ppol, rnImN_Bpol, rnImN_Ppol, unitrmnBpols, unitrmnPpols, Uinv
Пример #12
0
def speedup_Green_Taylor_Arnoldi_RgMmn_Uconverge(n,
                                                 k,
                                                 R,
                                                 klim=10,
                                                 Taylor_tol=1e-8,
                                                 invchi=0.1,
                                                 Unormtol=1e-4,
                                                 veclim=3,
                                                 delveclim=2,
                                                 plotVectors=False):
    #sets up the Arnoldi matrix and associated unit vector lists for any given RgM

    kR = mp.mpf(k * R)
    pow_jn, coe_jn, pow_yn, coe_yn = get_Taylor_jn_yn(n, kR, klim, Taylor_tol)
    #print(len(pow_jn))
    pow_jn = np.array(pow_jn)
    coe_jn = np.array(coe_jn)
    rmnRgM = mp.one * np.zeros(pow_jn[-1] + 1 - n)
    rmnRgM[pow_jn - n] += coe_jn
    rmnRgM = po.Polynomial(rmnRgM)

    pow_yn = np.array(pow_yn)
    coe_yn = np.array(coe_yn)
    rnImM = mp.one * np.zeros(pow_yn[-1] + 1 + n + 1)
    rnImM[pow_yn + n + 1] += coe_yn
    rnImM = po.Polynomial(rnImM)

    if plotVectors:
        plot_rmnMpol(n, rmnRgM.coef, 0.01 * kR, kR)

    unitrmnMpols = []
    RgMnorm = mp.sqrt(rmnMnormsqr_Taylor(n, k, R, rmnRgM))
    rmnMpol = rmnRgM / RgMnorm
    unitrmnMpols.append(rmnMpol)

    rmnGMpol = rmnGreen_Taylor_Mmn_vec(n, k, R, rmnRgM, rnImM, rmnMpol)
    rmnGMpol = rmnGMpol.cutdeg(rmnRgM.degree())
    prefactpow, Upol = rmnMpol_dot(2 * n, rmnMpol, rmnGMpol)
    Uinv = mp.matrix([[invchi - kR**prefactpow * po.polyval(kR, Upol) / k**3]])
    unitrmnMpols.append(rmnGMpol)  #set up beginning of Arnoldi iteration

    b = mp.matrix([mp.one])
    prevUnorm = 1 / Uinv[0, 0]

    i = 1
    while i < veclim:
        speedup_Green_Taylor_Arnoldi_step_RgMmn(n,
                                                k,
                                                R,
                                                invchi,
                                                rmnRgM,
                                                rnImM,
                                                unitrmnMpols,
                                                Uinv,
                                                plotVectors=plotVectors)
        i += 1
        if i == veclim:
            #solve for first column of U and see if its norm has converged
            b.rows = i
            x = mp.lu_solve(Uinv, b)
            Unorm = mp.norm(x)
            if np.abs(prevUnorm - Unorm) > np.abs(Unorm) * Unormtol:
                veclim += delveclim
                prevUnorm = Unorm
            #else: print(x)

    if veclim == 1:
        x = mp.one / Uinv[0, 0]
    """
    print(x)
    print(mp.norm(x))
    plt.figure()
    plt.matshow(np.abs(np.array((Uinv**-1).tolist(),dtype=np.complex)))
    plt.show()
    #EUdUinv = mpmath.eigh(Uinv.transpose_conj()*Uinv, eigvals_only=True)
    #print(EUdUinv)
    """
    #returns everything necessary to potentially extend size of Uinv matrix later
    return rmnRgM, rnImM, unitrmnMpols, Uinv
Пример #13
0
def zdipole_field_xy2D_periodic_array(k0,
                                      L,
                                      xd,
                                      yd,
                                      zd,
                                      xp,
                                      yp,
                                      zp,
                                      sumtol=1e-12):
    #field at coord (xp,yp,zp) of z-polarized dipoles in a square array in the z=czd plane
    #generated by summing over discrete k-vectors; in evanescent region the summand decreases exponentially with increasing kp and abskz
    #it seems that directly summing over individual dipole fields leads to convergence issues due to relatively slow (polynomial) decay of dipole fields
    #order of summation in k-space: concentric squares, 0th square the origin, 1st square infinity-norm radius 1, 2nd square infinity-norm radius 2...
    #since we are using the angular representation for consistency we insist that zp>zd
    """
    if not (xp<L/2 and xp>-L/2 and yp<L/2 and yp>-L/2):
        return 'target point out of Brillouin zone'
    """
    if zp <= zd:
        return 'need zp>zd'

    field = mp.zeros(3, 1)
    oldfield = mp.zeros(3, 1)
    deltak = 2 * mp.pi / L
    deltax = xp - xd
    deltay = yp - yd
    deltaz = zp - zd

    i = 1  #label of which square we are on

    prefac = -1j / (2 * L**2 * k0**2)
    while True:  #termination condition in loop
        #sum over the i-th square
        lkx = -i * deltak
        rkx = i * deltak
        for iy in range(-i, i + 1):
            ky = iy * deltak
            kpsqr = lkx**2 + ky**2
            kz = mp.sqrt(k0**2 - kpsqr)
            lphasefac = mp.expj(lkx * deltax + ky * deltay + kz * deltaz)
            rphasefac = mp.expj(rkx * deltax + ky * deltay + kz * deltaz)

            field[0] += prefac * (lkx * lphasefac + rkx * rphasefac)
            field[1] += prefac * (lphasefac + rphasefac) * ky
            field[2] += prefac * (lphasefac + rphasefac) * (-kpsqr / kz)

        bky = -i * deltak
        uky = i * deltak
        for ix in range(-i + 1, i):
            kx = ix * deltak
            kpsqr = kx**2 + bky**2
            kz = mp.sqrt(k0**2 - kpsqr)
            bphasefac = mp.expj(kx * deltax + bky * deltay + kz * deltaz)
            uphasefac = mp.expj(kx * deltax + uky * deltay + kz * deltaz)

            field[0] += prefac * (bphasefac + uphasefac) * kx
            field[1] += prefac * (bphasefac * bky + uphasefac * uky)
            field[2] += prefac * (bphasefac + uphasefac) * (-kpsqr / kz)

        if mp.norm(field - oldfield) < mp.norm(field) * sumtol:
            break

        print('i', i)
        #mp.nprint(field)
        oldfield = field.copy()
        i += 1

    return field
Пример #14
0
def shell_Green_grid_Arnoldi_RgandImMmn_Uconverge_mp(n,k,R1,R2, invchi, gridpts=1000, Unormtol=1e-10, veclim=3, delveclim=2, maxveclim=40, plotVectors=False):
    np.seterr(over='raise',under='raise',invalid='raise')
    #for high angular momentum number could have floating point issues; in this case, raise error. Outer method will catch the error and use the mpmath version instead
    rgrid = np.linspace(R1,R2,gridpts)
    rsqrgrid = rgrid**2
    rdiffgrid = np.diff(rgrid)
    """
    RgMgrid = sp.spherical_jn(n, k*rgrid) #the argument for radial part of spherical waves is kr
    ImMgrid = sp.spherical_yn(n, k*rgrid)
    RgMgrid = RgMgrid.astype(np.complex)
    ImMgrid = ImMgrid.astype(np.complex)
    
    RgMgrid = complex_to_mp(RgMgrid)
    ImMgrid = complex_to_mp(ImMgrid)
    """
    RgMgrid = mp_vec_spherical_jn(n, k*rgrid)
    ImMgrid = mp_vec_spherical_yn(n, k*rgrid)
    
    vecRgMgrid = RgMgrid / mp.sqrt(rgrid_Mmn_normsqr(RgMgrid, rsqrgrid,rdiffgrid))
    
    vecImMgrid = ImMgrid - rgrid_Mmn_vdot(vecRgMgrid, ImMgrid, rsqrgrid,rdiffgrid)*vecRgMgrid
    vecImMgrid /= mp.sqrt(rgrid_Mmn_normsqr(vecImMgrid,rsqrgrid,rdiffgrid))
    
    if plotVectors:
        rgrid_Mmn_plot(vecRgMgrid,rgrid)
        rgrid_Mmn_plot(vecImMgrid,rgrid)
    
    unitMvecs = [vecRgMgrid,vecImMgrid]
    
    GvecRgMgrid = shell_Green_grid_Mmn_vec_mp(n,k, rsqrgrid,rdiffgrid, RgMgrid,ImMgrid, vecRgMgrid)
    GvecImMgrid = shell_Green_grid_Mmn_vec_mp(n,k, rsqrgrid,rdiffgrid, RgMgrid,ImMgrid, vecImMgrid)
    Gmat = mp.zeros(2,2)
    Gmat[0,0] = rgrid_Mmn_vdot(vecRgMgrid, GvecRgMgrid, rsqrgrid,rdiffgrid)
    Gmat[0,1] = rgrid_Mmn_vdot(vecRgMgrid, GvecImMgrid, rsqrgrid,rdiffgrid)
    Gmat[1,0] = Gmat[0,1]
    Gmat[1,1] = rgrid_Mmn_vdot(vecImMgrid,GvecImMgrid, rsqrgrid,rdiffgrid)
    Uinv = mp.eye(2)*invchi-Gmat

    unitMvecs.append(GvecRgMgrid)
    unitMvecs.append(GvecImMgrid) #append unorthogonalized, unnormalized Arnoldi vector for further iterations
    
    b = mp.matrix([mp.one])
    prevUnorm = 1 / Uinv[0,0]
    
    i=2
    while i<veclim:
        Gmat = shell_Green_grid_Arnoldi_RgandImMmn_step_mp(n,k,invchi, rgrid,rsqrgrid,rdiffgrid, RgMgrid, ImMgrid, unitMvecs, Gmat, plotVectors=plotVectors)
        i += 1
        print(i)
        if i==maxveclim:
            break
        if i==veclim:
            #solve for first column of U and see if its norm has converged
            Uinv = mp.eye(Gmat.rows)*invchi-Gmat
            b.rows = i
            x = mp.lu_solve(Uinv, b)
            Unorm = mp.norm(x)
            print('Unorm', Unorm, flush=True)
            if np.abs(prevUnorm-Unorm) > np.abs(Unorm)*Unormtol:
                veclim += delveclim
                prevUnorm = Unorm
    
    return rgrid,rsqrgrid,rdiffgrid, RgMgrid, ImMgrid, unitMvecs, Uinv, Gmat