## The aim of this notebook is to calculate a cost estimation of different methods to calculate the energy of a system with different Phase Estimation protocols

```python
import numpy as np
from itertools import combinations
import scipy
from scipy.optimize import minimize
from scipy.special import binom, gamma
from scipy.integrate import quad, dblquad
from scipy import integrate
import sympy
```

## IMPORTANT: to these cost, we have to add the QFT cost, which is minor, and has an associated error.

Question: what is the base of the logs that appear?

# qDrift and Trotterization

The first algorithm we would like to estimate its complexity is the q-Drift protocol from appendix A. The cost is
$$3n(10+12\log \epsilon^{-1})\log N  = 3\frac{27\pi^2}{2}\frac{\lambda^2}{\delta_E^2 P_f}(10+12\log \epsilon^{-1})\log N$$
where $\lambda = \sum a_\gamma $ for the Hamiltonian $H = a_\gamma H_\gamma$;
$\delta_E$ is the error in Phase Estimation (an arbitrary parameter chosen by the user);
and $P_f = \frac{3}{2}p_f$ the probability of failure (also chosen by the user). The $\epsilon$ parameter is given by the smallest of
$$\epsilon_j = \epsilon_{tot}\frac{2^j}{2(2^m-1)};$$
We also need that
$$ n = 4\frac{\pi^2(2^m-1)^2}{\epsilon_{tot}}$$ with

$$m = q +\log_2 \left(\frac{1}{2p_f} + \frac{1}{2}\right),$$
$\delta_E = 2\lambda\delta$,  $q = \log_2 \delta -1$; and $P_f = p_f +2\epsilon_{tot}$

We want to minimize the total cost
$$3n(10+12\log \epsilon^{-1})\log N  = 3\frac{27\pi^2}{2}\frac{\lambda^2}{\delta_E^2 P_f}(10+12\log \epsilon^{-1})\log N$$
where $\epsilon$ is the error of individual rotations $$\epsilon = \frac{\epsilon(j)}{n(j)} = \frac{\epsilon_{tot}^2}{4\pi^2(2^m-1)^2}$$

```python
def calc_qdrift_resources(lambd, N, deltaE = 1e-4, P_failure = .1):
    n = ((27*np.pi**2/2)*(lambd/deltaE)**2) / P_failure**3

    delta = deltaE/(2*lambd)
    q = np.log2(1/delta)-1

    pf = 2/3*P_failure
    eps_tot = P_failure/6
    #sanity check
    assert (pf +2*eps_tot)/P_failure == 1

    m = q + np.log2(1/(2*pf)+1/2)

    # Another sanity check. This should coincide
    eps_tot_2 = 4*(np.pi*2**m-1)**2/n
    print(eps_tot,eps_tot_2)

    # error in individual rotations
    eps = (eps_tot/(2*np.pi*(2**m-1)))**2

    rost_cost_factor = 3*(10+12*np.log(1/eps))*np.log(N)
    print('eps',eps)

    return rost_cost_factor*n

calc_qdrift_resources(lambd = 768, N = (467403)**(1/4))
```

    0.016666666666666666 0.01896296276647537
    eps 1.8639547394483464e-21

    4.484316495050195e+22

For the randomised Hamiltonian approach, the equations are similar. However, now $p_f = 3/4P_f$ and
$$n = 8\Gamma^2\left(\frac{ \pi^3 \Lambda^3}{8\delta_E^3}\right)^{1/2}\left(\frac{1+p_f}{p_f}\right)^{3/2}\frac{1}{\epsilon_{tot}^{1/2}} = 4.35\sqrt{8}\pi^{3/2}\Gamma^2 \frac{\Lambda^{3/2}}{\delta_E^{3/2}P_f^2}$$

```python
def calc_rand_ham_resources(Lambd, lambd, Gamma, N, deltaE = 1e-4, P_failure = .1):
    n = 4.35*np.sqrt(8)*(np.pi*Lambd/deltaE)**(3/2) *(Gamma/ P_failure)**2
    print('n',n)

    # error in individual rotations
    Lambda_A = Lambd/(2*lambd)
    delta = deltaE/(2*lambd)
    q = np.log2(1/delta)-1

    pf = 3/4*P_failure
    eps_tot = P_failure/8
    #sanity check
    assert (pf +2*eps_tot)/P_failure == 1

    m = q + np.log2(1/(2*pf)+1/2)

    n1 = 8*Gamma**2 * ( 2**(m+1)*np.pi**3*Lambda_A**3/eps_tot  )**(1/2) *2*(2**m-1)
    print('n1',n1)

    # Another sanity check. This should coincide
    eps_tot_2 = ( 8*Gamma**2* (np.pi*Lambd/(2*deltaE))**(3/2)* ((1+pf)/pf)**(3/2) /n1    )**2
    eps_tot_3 = 1/ ( 4.35* (1/P_failure)**2  *  (pf/(1+pf))**(3/2)  )**2
    print(eps_tot,eps_tot_2,eps_tot_3)

    n2 = 8*Gamma**2 * ( 2**(m+1)*np.pi**3*Lambda_A**3/eps_tot_2  )**(1/2) *2*(2**m-1)
    print('n2',n2)

    n3 = 8*Gamma**2 * ( 2**(m+1)*np.pi**3*Lambda_A**3/eps_tot_3  )**(1/2) *2*(2**m-1)
    print('n3',n3)

    # Esto probablemente esté mal:
    eps = 1/4*(eps_tot/(np.pi*2**m*Lambda_A))**(3/2)

    rost_cost_factor = 3*(10+12*np.log(1/eps))*np.log(N)
    print('eps',eps)

    return rost_cost_factor*n

calc_rand_ham_resources(Lambd = 4.07, lambd = 768, Gamma =467403,  N = (467403)**(1/4))
```

    n 1.2289484451445014e+22
    n1 1.3712296468152677e+22
    0.0125 0.012500000454215137 0.015561916785328065
    n2 1.3712296219019378e+22
    n3 1.2289484228162224e+22
    eps 1.1265689857382676e-12

    4.092893794257138e+25

# Taylorization (babbush2016exponential)

Let us know calcula the cost of performing Phase Estimation.
1.  We have already mentioned that in this case, controlling the direction of the time evolution adds negligible cost. We will also take the unitary $U$ in Phase estimation to be $U_r$. The number of segments we will have to Hamiltonian simulate in the phase estimation protocol is $r \approx \frac{4.7}{\epsilon_{\text{PEA}}}$.
2. Using oblivious amplitude amplification operator $G$ requires to use $\mathcal{W}$ three times.
3. Each operator $G$ requires to use Prepare$(\beta)$ twice and Select$(V)$ once.
4. The cost of Select$(V)$ is bounded in $8N\lceil \log_2\Gamma + 1\rceil\frac{K(K+1)(2K+1)}{3}+ 16N K(K+1)$.
5. The cost of Prepare$(\beta)$ is $(20+24\log\epsilon^{-1}_{SS})K$ T gates for the preparation of $\ket{k}$; and $(10+12\log\epsilon^{-1}_{SS})2^{\lceil \log \Gamma \rceil + 1}K$ T gates for the implementation of the $K$ Prepare$(W)$ circuits. Here notice that $2K$ and $2^{\lceil \log \Gamma \rceil + 1}K$ rotations up to error $\epsilon_{SS}$ will be implemented.
Remember that
$$ K =  O\left( \frac{\log(r/\epsilon_{HS})}{\log \log(r/\epsilon_{HS})} \right)$$
Notice that the $\Lambda$ parameters comes in the algorithm only implicitly, since we take the evolution time of a single segment to be $t_1 = \ln 2/\Lambda$ such that the first segment in Phase estimation has $r = \frac{\Lambda t_1}{\ln 2} = 1$ as it should be. In general, we will need to implement $r \approx \frac{4.7}{\epsilon_{PEA}}$. However, since $\epsilon_{PEA}$ makes reference to $H$ and we are instead simulating $H \ln 2/ \Lambda$, we will have to calculate the eigenvalue to precision $\epsilon \ln 2/ \Lambda$; so it is equivalently to fixing an initial time $t_1$ and running multiple segments in each of the $U$ operators in Phase Estimation.

```python
def Taylor_naive(Lambd, Gamma, N, epsilon_PEA = .4*eps_tot, epsilon_HS = .2*eps_tot, epsilon_S = .4*eps_tot):

    r = 4.7*Lambd / (epsilon_PEA*np.log(2)) # The simulated time

    K_list = []

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))
        K_list.append(K)

    result = 0

    epsilon_SS = epsilon_S /(np.sum([3*2*(K*2**(np.ceil(np.log2(Gamma)+1)) + 2*K) for K in K_list]))

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * t_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))
        Select_V = 8*N*np.ceil(np.log2(Gamma) +1)*K*(K+1)*(2*K+1)/3 + 16*N*K*(K+1)

        Prepare_beta_1 = (20+24*np.log2(1/epsilon_SS))*K
        Prepare_beta_2 = (10+12*np.log2(1/epsilon_SS))*K*2**(np.ceil(np.log2(Gamma)+1))
        Prepare_beta = Prepare_beta_1 + Prepare_beta_2

        result += 3*(2*Prepare_beta + Select_V)*t_j

    return result

Taylor_naive(Lambd = 4.07, Gamma =467403, N = (467403)**(1/4))
```

    95463557056106.14

```python
eps_tot = .0125
def Taylor_on_the_fly(Gamma, N, phi_max, dphi_max, zeta_max_i, epsilon_PEA = .4*eps_tot, epsilon_HS = .1*eps_tot, epsilon_S = .4*eps_tot, epsilon_H = .1*eps_tot, order = 10):
    '''
    Error terms
    eps_PEA: Phase estimation,
    eps_HS: the truncation of K,
    eps_S: gate synthesis,
    eps_H: discretization of integrals,
    eps_taylor: truncation of taylor series to order o
    '''

    t = 4.7/epsilon_PEA
    x_max = np.log(N * t/ epsilon_H)

    lambd = Gamma*phi_max**4 * x_max**5
    r = lambd* t / np.log(2)

    K_list = []

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))
        K_list.append(K)

    epsilon_SS = epsilon_S /np.sum([3*2*(2*K) for K in K_list])

    # We distribute the error between all C-U in phase estimation uniformly
    eps_tay_m_j = eps_tay/((6+2)*np.max(K_list)*r*3*2)

    x = sympy.Symbol('x')
    order = max(order_find(function = sqrt(x), x0 = 1, e = eps_tay_m_j, xeval = x_max),
                order_find(function = exp(max_zeta_i*(x)**2), x0 = 0, e = eps_tay_m_j, xeval = x_max))

    result = 0

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))

        mu = ( 3*K*2*r/epsilon_H *2*(4*dphi_max + phi_max/x_max)*phi_max**3 * x_max**6 )**6
        n = np.log(mu)/3

        Select_V = 8*N*np.ceil(np.log2(Gamma) +1)*K*(K+1)*(2*K+1)/3 + 16*N*K*(K+1)

        Prepare_beta_1 = (20+24*np.log2(1/epsilon_SS))*K

        Prepare_beta_2 = ( 6*35*n**2*(order-1)*4*N + (252+70*(order-1))*n**2 )*K

        Prepare_beta = Prepare_beta_1 + Prepare_beta_2

        result += 3*(2*Prepare_beta + Select_V)*t_j

    return result

Taylor_on_the_fly(Gamma = 467403, N = (467403)**(1/4), phi_max = .1, dphi_max = .1)
```

    4.81664159586087e+21

```python
# Taylor approximation at x0 of the function 'function'
def taylor(function,x0,n):
    i = 0
    p = 0
    while i <= n:
        p = p + (function.diff(x,i).subs(x,x0))/(factorial(i))*(x-x0)**i
        i += 1
    return p

#print(taylor(sympy.sqrt(x), 1, 5))#.subs(x,1).evalf())

def order_find(function, x0, e, xeval):

    x = sympy.Symbol('x')

    def factorial(n):
        if n <= 0:
            return 1
        else:
            return n*factorial(n-1)

    def taylor_err(function,x0,n, z = None):
        if z == None:
            z = x0
        #print('coefficient order',n, function.diff(x,n)/(factorial(n)))#.subs(x,z))
        a = (function.diff(x,n).subs(x,z))/(factorial(n))*(x-x0)**n
        #print('coefficient order',n, (function.diff(x,n).subs(x,z)/(factorial(n))*(x-x0)**n))
        #print('a',a)
        return a

    order = 0
    te = 1
    zeta = np.linspace(x0,xeval,20)

    while te > e:# or order < 10:
        order += 1
        #for z in zeta:
            #print(taylor_err(f, x0, order, z).subs(x,xeval).evalf())
        te = np.max([np.abs(taylor_err(function, x0, order, z).subs(x,xeval).evalf()) for z in zeta])
        #print('order',order, te,'\n')

    return order

x = sympy.Symbol('x')
order_find(sympy.sqrt(x), x0 = 1, e = 1e-3, xeval = 2)
```

    order 1 0.500000000000000

    order 2 0.125000000000000

    order 3 0.0625000000000000

    order 4 0.0390625000000000

    order 5 0.0273437500000000

    order 6 0.0205078125000000

    order 7 0.0161132812500000

    order 8 0.0130920410156250

    order 9 0.0109100341796875

    order 10 0.00927352905273438

    order 11 0.00800895690917969

    order 12 0.00700783729553223

    order 13 0.00619924068450928

    order 14 0.00553503632545471

    order 15 0.00498153269290924

    order 16 0.00451451400294900

    order 17 0.00411617453210056

    order 18 0.00377315998775885

    order 19 0.00347527893609367

    order 20 0.00321463301588665

    order 21 0.00298501637189474

    order 22 0.00278149252835647

    order 23 0.00260009084172452

    order 24 0.00243758516411674

    order 25 0.00229133005426974

    order 26 0.00215913793575417

    order 27 0.00203918582821228

    order 28 0.00192994373027233

    order 29 0.00183011905456859

    order 30 0.00173861310184016

    order 31 0.00165448666142854

    order 32 0.00157693259917408

    order 33 0.00150525384466617

    order 34 0.00143884558681325

    order 35 0.00137718077594982

    order 36 0.00131979824361858

    order 37 0.00126629290941783

    order 38 0.00121630766299344

    order 39 0.00116952659903215

    order 40 0.00112566935156845

    order 41 0.00108448632651106

    order 42 0.00104575467199281

    order 43 0.00100927485785353

    order 44 0.000974867760426703

    44

```python
33/2048
```

    0.01611328125

```python
eps_tot = .0125
def error_optimizer(eps_array):
    epsilon_PEA = eps_array[0]

    epsilon_S = eps_array[1]

    epsilon_HS = eps_tot - eps_array[0] - eps_array[1]

    return Taylor_naive(Lambd = 4.07, Gamma =467403, N = (467403)**(1/4),
                 epsilon_PEA = epsilon_PEA, epsilon_HS= epsilon_HS, epsilon_S = epsilon_S)

eps_array = [.005, .005]
#A = np.array([1,1])

constraint = scipy.optimize.LinearConstraint(A = np.array([[1,1],[1,0],[0,1]]), lb = [0,0,0], ub = [eps_tot,eps_tot,eps_tot], keep_feasible=True)
minimize(error_optimizer, x0 = eps_array, method='SLSQP', tol=1, constraints = (constraint))

```

         fun: 95463557056106.14
         jac: array([-1.96938319e+16, -6.01179179e+14])
     message: 'Inequality constraints incompatible'
        nfev: 3
         nit: 1
        njev: 1
      status: 4
     success: False
           x: array([0.005, 0.005])

# Configuration interaction (babbush2017exponentially)

\begin{equation}
    \begin{split}
        &\mu M \zeta = \mu \max_{\gamma,\rho}||\aleph_{\rho,\gamma}||_{\max} = \\
        &=\max \left[ \frac{672\pi^2}{\alpha^3}\varphi^4_{\max}x^5_{\max}\log^6 \left(\frac{K_2 \varphi^4_{\max}x^5_{\max}}{\delta}\right)\right.\\
        &, \left.\frac{256\pi^2}{\alpha^3}Z_q\varphi^2_{\max}x^2_{\max}\log^3 \left(\frac{K_1 Z_q\varphi^2_{\max}x^2_{\max}}{\delta}\right),\right.\\
        &\left. \frac{32\gamma_1^2}{\alpha^3}\varphi^2_{\max}x_{\max}\log^3 \left(\frac{K_0\varphi^2_{\max}x_{\max}}{\delta}\right)\right]
    \end{split}
    \end{equation}

```python
eps_tot = 0.125
def configuration_interaction(N, eta, alpha, gamma1, K0, K1, K2, epsilon_PEA = .4*eps_tot, epsilon_HS = .1*eps_tot, epsilon_S = .4*eps_tot, epsilon_H = .1*eps_tot):
    t = 4.7/epsilon_PEA
    x_max = np.log(N * t/ epsilon_HS)

    Gamma = binom(eta, 2)*binom(N-eta, 2) + binom(eta,1)*binom(N-eta,1) + 1 # = d
    Zq = eta

    '''
    Warning, we have a circular definition here of delta, mu_M_zeta and r.
    In practice we have to find the smallest value of mu_M_zeta compatible with delta:
    mu_M_zeta \leq f( epsilon_H / 3K*2 Gamma t mu_M_zeta), with f the np.max defining mu_M_zeta below
    Due to this complication we distribute the error uniformly accross all C-U which is not optimal
    '''

    delta = epsilon_H/(3*r*K) # delta is the error in calculating a single integral. There are 3K r of them in the simulation

    # This is an upper bound, not an equality!!!
    mu_M_zeta = np.max([
        672*np.pi**2/(alpha**3)*phi_max**4*x_max**5*(np.log(K2*phi_max**4*x_max**5/delta))**6,
        256*np.pi**2/(alpha**3)*Zq*phi_max**2*x_max**2*(np.log(K1*Zq*phi_max**2*x_max**2/delta))**3,
        32*gamma1**2**2/(alpha**3)*phi_max**2*x_max*(np.log(K0*phi_max**2*x_max/delta))**3
    ])

    r = 2*Gamma*t*mu_M_zeta
    K = np.log2(r/epsilon_HS)/np.log2(np.log2(r/epsilon_HS))
    epsilon_SS = epsilon_S / (2*K*2*3*r)
    Prepare_beta = (20+24*np.log2(1/epsilon_SS))*K

    mu = ( r/epsilon_H *2*(4*dphi_max + phi_max/x_max)*phi_max**3 * x_max**6 )**6
    n = np.log(mu)/3
    Sample_w = ( 6*35*n**2*(order-1)*4*N + (189+35*(order-1))*n**2 )*K

    Q_val = 2*Sample_w
    Q_col = 6*(32*eta*np.log2(N) + 24*eta**2 + 16*eta*(eta+1)*np.log2(N))

    Select_H = Q_val + 2*Q_col
    Select_V = K*Select_H

    return r*3*(2*Prepare_beta + Select_V)
```

# Low depth quantum simulation of materials (babbush2018low) Trotter

```python
def low_depth_trotter(N, Omega, eps_PEA, eps_HS, eps_S):
    def f(x, y):
        return 1/(x**2 + y**2)
    def I(N0):
        return integrate.nquad(f, [[1, N0],[1, N0]])[0]

    t = 4.7/eps_PEA
    sum_1_nu = 4*np.pi(np.sqrt(3)*N**(1/3)/2 - 1) + 3 - 3/N**(1/3) + 3*I(N**(1/3))
    max_V = eta**2/(2*np.pi*Omega**(1/3))*sum_1_nu
    max_U = eta**2/(np.pi*Omega**(1/3))*sum_1_nu
    nu_max = 3*(N**(1/3))**2
    max_T = 2*np.pi**2*eta/(Omega**(2/3))* nu_max

    r = np.sqrt(2*t**3/eps_HS *(max_T**2*(max_U + max_V) + max_T*(max_U + max_V)**2))

    eps_SS = eps_S/(2N +N*(N-1) + N*np.log(N/2) + 8*N)

    exp_UV_cost = (4*N**2 + 4*N)*np.log(1/eps_SS)
    FFFT_cost = (2 + 4*np.log(1/eps_SS))*n*np.log(N) + 4*N*np.log(1/eps_SS)
    exp_T_cost = 32*N*np.log(1/eps_SS)

    return r*(exp_UV_cost + FFFT_cost + exp_T_cost)
```

    (16.5877713181052, 2.1199305958404497e-06)

from sympy import *
x,y= symbols('x y')
a = symbols('a', positive=True)
expr=1/(x**2 + y**2)
integral = integrate(expr,(x,1,a),(y,1,a))
integral
integral.evalf(subs={a:10^6})

# Low depth quantum simulation of materials (babbush2018low) Taylor

```python
def low_depth_taylor(N, lambd, Lambd, eps_PEA, eps_HS, eps_S, Ham_norm):
    '''To be used in plane wave basis'''
    t = 4.7/eps_PEA
    r = t*Lambda/np.log(2)

    K_list = []

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))
        K_list.append(K)

    epsilon_SS = epsilon_S /np.sum([3*2*(2*K) for K in K_list]) # The extra two is because Uniform requires 2 Rz gates

    mu = np.ceil(np.log(2*np.sqrt(2)*Lambdd/eps_PEA) + np.log(1 + eps_PEA/(8*lambd)) + np.log(1 - (Ham_norm/lambd)**2))

    result = 0

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))

        prepare_beta = K*(6*N+40*np.log(N)+16*np.log(1/epsilon_SS) + 10*mu)
        select_V = K*(12*N+8*np.log(N))

        result += 3*(2*prepare_beta + select_V)*t_j

    return result
```

# Low depth quantum simulation of materials (babbush2018low) On-the fly

```python
def low_depth_on_the_fly(N, lambd, Omega, eps_PEA, eps_HS, eps_S, Ham_norm, J):
    '''To be used in plane wave basis
    J: Number of atoms
    '''
    Lambd = (2*eta+1)*N**3 / (2*Omega**(1/3)*np.pi)
    t = 4.7/eps_PEA
    r = t*Lambd/np.log(2)

    mu = np.ceil(np.log(2*np.sqrt(2)*Lambdd/eps_PEA) + np.log(1 + eps_PEA/(8*lambd)) + np.log(1 - (Ham_norm/lambd)**2))
    #K_list = []

    #epsilon_SS = epsilon_S /np.sum([3*2*(2*K) for K in K_list])

    x = sympy.Symbol('x')
    order = order_find(function = cos(x), x0 = 1, e = e, xeval = x_max)
    sample_w = 70*np.log(N)**2 + 29* np.log(N) + (21+14)*order/2*np.log(N)**2 + 2*order*np.log(N) + J*(35*order/2 + 63 + 2*order/np.log(N))*np.log(N)**2
    kickback = 32*np.log(mu)

    result = 0

    for m_j in range(0, int(np.ceil(np.log(r)))):

        t_j = 2**m_j
        epsilon_HS_mj = epsilon_HS / r * 2**m_j

        #K_list.append(K)

        K = np.ceil(np.log2(t_j/epsilon_HS_mj) / np.log2( np.log2 (t_j/epsilon_HS_mj)))

        prepare_W = 2*sample_w + kickback
        prepare_beta = K*prepare_W
        select_H = (12*N + 8*np.log(N))
        select_V = K*select_H

        result += 3*(2*prepare_beta + select_V)*t_j

    return result
```

## Linear T complexity (babbush2018encoding)

```python
def linear_T(N, lambd, eps_PEA, eps_SS):
    '''To be used in plane wave basis'''
    t = 4.7/eps_PEA
    r = lambd*t

    mu = np.ceil(np.log(2*np.sqrt(2)*lambd/eps_PEA) + np.log(1 + eps_PEA/(8*lambd)) + np.log(1 - (Ham_norm/lambd)**2))

    eps_SS = eps_S / (r*2*P)

    S = 12*N+8*np.log(N)
    P = 6*N + 40*np.log(N)+ 24*np.log(1/eps_SS) + 10*mu

    return r*(2*P + S)
```

## Sparsity and low rank factorization (berry2019qubitization)

```python
def sparsity_low_rank(N, lambd, eps_PEA, eps_SS, L):
    t = 4.7/eps_PEA
    r = lambd*t

    mu = np.ceil(np.log(2*np.sqrt(2)*lambd/eps_PEA) + np.log(1 + eps_PEA/(8*lambd)) + np.log(1 - (Ham_norm/lambd)**2))
    d = L(N**2/8 + N/4)
    M = np.log(N**2) + mu

    def closest_power(x):
        possible_results = np.floor(np.log2(x)), np.ceil(np.log2(x))
        return min(possible_results, key= lambda z: abs(x-2**z))

    kc = 2**closest_power(np.sqrt(d/M))
    ku = 2**closest_power(np.sqrt(d))

    QROAM = 4*(np.ceil(d/kc)+4*M*(kc-1)+2*np.ceil(d/ku) + 4*k_u)

    Select = (4*N + 4*np.log(N))*4 # The *4 because Toffoli -> T-gates

    # 7 times per prepare, we have to use Uniform
    eps_SS = eps_S/ (7*2*r)
    Uniform = 8*np.log(L) + 56*np.log(1/eps_SS) + 52*np.log(N/2) ### Warning, this is in T gates already!!!!

    Other_subprepare = mu + np.log(L) + 6*np.log(N/2)

    continuous_register = 2*(np.log(N/2))**2 + 3*np.log(N/2)

    Prepare = 4*(QROAM + Other_subprepare + continuous_register) + Uniform # The 4 is Toffoli -> T-gates

    return r*(2*Prepare + Select)
```

    4.442882938158366

## Interaction picture (low2019hamiltonian)

```python
def interaction_picture(N, Gamma, lambd_T, lambd_U_V, eps_S, eps_HS, eps_PEA):
    '''
    The number of rotations is very large here:
    Each of the r segments can be simulated as e^{-i(U+V)t} T(e^{-i \int H_I (s) ds})
    - The Time Ordered Dyson series segment is represented by TDS
    - TDS is made of oblivious Amplitude Amplification of TDS_beta: 2x Ref  + 3x TDS_beta
        < TDS_beta is made of COEF DYS_K COEF'
        < DYS_K is made of
            · 4K U operators
            · K Compare and K Swap
            · (3K + 1) ADD operators
            · K HAM-T operators, made of,
                > x2 e^{-i(U+V)t}
                > x2 FFFT
                > x2 Prepare
                > Select
    Also, the e^{-i(U+V)t} is
        > x2 FFFT
        > N log 1/eps_SS Phase operators
        > N Multiplications
    '''

    t = 4.7/eps_PEA
    r = lambd_T*t # lambd_T is necessary to take tau = 1

    # Notice that K is a bit different than in other articles because each segment is now its own Taylor series, which has the consequence of larger error
    K = np.ceil( -1  + 2* np.log(2*r/epsilon_HS)/np.log(np.log(2*r/epsilon_HS))  ) # We
    delta = eps_HS / t # Alternatively we can substitute t by r changing delta in the following line to 1/2. t represents L in the main text (see before eq 21 in the original article)
    tau = 1/np.ceil(2*lambd_T) # tau = t/ np.ceil(2 * lambd_T * t)
    M = np.max(16*tau/delta * (2*lambd_U_V + lambd_T), K**2)

    rot_FFFT = 2*N/2*np.log2(N)
    rot_U = 4*K
    rot_COEF = 2**(np.ceil(np.log2(K) + 1))
    rot_prep = 16*N

    epsilon_SS = 1e-2
    consistent = False
    while not consistent:
        rot_exp_U_V = rot_FFFT + N*np.log2(1/epsilon_SS) + N
        num_rotations = ((((2*rot_prep + 2* rot_FFFT + 2*np.log(M)*rot_exp_U_V)*K * rot_U) + 2*rot_COEF)*3 + rot_exp_U_V)*r
        proposed_eps_SS = eps_S / num_rotations
        if proposed_eps_SS < epsilon_SS:
            consistent = True
        else:
            epsilon_SS /= 10

    # Cost

    exp_U_V= 46*N*(np.log(1/eps_SS))**2+8*N + 8*N*np.log2(1/eps_SS)*np.log2(N) + 4*N*np.log(N)
    COEF = rot_COEF * (10 + 12*np.log2(K))
    U = 8*(np.log2(M) + np.log2(1/eps_SS))
    ADD = 4*np.log2(K)
    Comp = 8*np.log2(M)
    FFFT = (2 + 4*np.log(1/eps_SS))*N*np.log2(N) - 4*np.log2(1/eps_SS)*N
    Prep = 2**9*(1 + np.log2(N))+2**6*3*N*np.log2(1/eps_SS)
    Select = 8*N
    REF = 16*(np.log2(Gamma) + 2*np.log(K+1)+ 2*np.log(M))

    cost = ((((2*Prep + Select + 2*FFFT + 2*np.log(M)*exp_U_V)*K + (3*K+1)*ADD + K*Comp + 4*K*U +2*COEF)*3 + 2*REF) + exp_U_V)*r

    return cost
```

## Sublinear scaling and interaction picture babbush2019quantum

```python
def sublinear_scaling_interaction(N, eta, Gamma, lambd_T, lambd_U_V, eps_S, eps_HS, eps_PEA, eps_mu, eps_M_0):
    '''
    See the interaction_picture function for more background
    J represents the number of atoms
    In this article there are three additional sources of error,
        - the precision on preparing the amplitudes sqrt(zeta_l), eps_mu
        - the precision on the position of the atomic nuclei, 1/delta_R. In the article we take log(1/delta_R) < 1/3 log(N)
        - The precision due to the finite value of M_0 = eta N t / eps_M_0

    The algorithm follows a very similar structure to that of the interaction_picture one.
    '''

    t = 4.7/eps_PEA
    r = lambd_U_V*t # lambd_T is necessary to take tau = 1

    # Notice that K is a bit different than in other articles because each segment is now its own Taylor series, which has the consequence of larger error
    K = np.ceil( -1  + 2* np.log(2*r/epsilon_HS)/np.log(np.log(2*r/epsilon_HS))  ) # We
    delta = eps_HS / t # Alternatively we can substitute t by r changing delta in the following line to 1/2. t represents L in the main text (see before eq 21 in the original article)
    tau = 1/np.ceil(2*lambd_U_V) # tau = t/ np.ceil(2 * lambd_T * t)
    M = np.max(16*tau/delta * (lambd_U_V + 2*lambd_T), K**2)
    M0 = eta * N * tau / (eps_M_0/r)

    rot_exp_T = np.log2(eta) + 2*np.log2(N)
    rot_select_1 = 1/3*np.log2(N) + 2
    rot_Subprepare  = 2 # Only the two rotations from Uniform in Subprepare
    rot_COEF = 2**(np.ceil(np.log2(K) + 1))

    num_rotations = (((2*np.log(M)*rot_exp_T + rot_select_1)*K + 2*rot_COEF)*3 + rot_exp_T )*r
    eps_SS = eps_S / num_rotations

    num_Subprepare = 2*3*K*3*r
    eps_mus = eps_mu / num_Subp

    Subprep = 4*J + 4*np.log(1/eps_mus) +8*np.log2(1/eps_SS)+  12*np.log2(J)
    n = 1/3*np.log2(N) + 1
    Prep  = 3*(79*n**2 +43*n*np.log2(M0) + 44*n)
    exp_T = rot_exp_T * 4*np.log(1/eps_SS)
    select_0 = 16*eta*np.log2(N)
    select_1 = 8*eta*np.log2(N) + 14*(np.log2(N))**2 + 4*np.log2(N)*np.log(1/eps_SS)

    HAM_T = 2*np.log(M)*exp_T + 2*(3*(Subprep + Prep)) + select_0 + select_1 #The 3 multiplying Subprep and Prep comes from oblivious AA
    U = 8*(np.log2(M) + np.log2(1/eps_SS))
    ADD = 4*np.log2(K)
    Comp = 8*np.log2(M)

    COEF = rot_COEF * (10 + 12*np.log2(K))
    REF = 16*(np.log2(Gamma) + 2*np.log(K+1)+ 2*np.log(M))

    cost = (((4*K*U + K*Comp + (3*K + 1)*ADD + K*HAM_T) + 2*COEF)*3  + 2*REF)*r

    # Initial state antisymmetrization
    antisymmetrization = 3*eta*np.log2(eta)*(np.log2(eta)-1)*(2* np.ceil(np.log2(eta**2)) + np.log(N))

    return cost + antisymmetrization
```

# Finding the molecule parameters

```python
# Docs https://quantumai.google/reference/python/openfermion/

from openfermion.chem import geometry_from_pubchem, MolecularData
from openfermionpsi4 import run_psi4
from  openfermion.transforms  import  get_fermion_operator,  jordan_wigner
import openfermion
from openfermion.utils import Grid
from openfermion.hamiltonians import plane_wave_external_potential, plane_wave_potential, plane_wave_kinetic
from openfermion.hamiltonians import plane_wave_hamiltonian
from openfermion.hamiltonians import dual_basis_external_potential, dual_basis_potential, dual_basis_kinetic

from pyscf.mcscf import avas

methane_geometry = geometry_from_pubchem('methane')
print(methane_geometry)

basis = 'sto-3g'

molecule = MolecularData(methane_geometry, basis, multiplicity = 1)
print(molecule)

molecule = run_psi4(molecule,run_scf=True,
                        run_mp2=True,
                        #run_cisd=False,
                        #run_ccsd=True,
                        run_fci=False
                   )
```

    [('C', (0, 0, 0)), ('H', (0.5541, 0.7996, 0.4965)), ('H', (0.6833, -0.8134, -0.2536)), ('H', (-0.7782, -0.3735, 0.6692)), ('H', (-0.4593, 0.3874, -0.9121))]
    <openfermion.chem.molecular_data.MolecularData object at 0x7fe5c9b3b0b8>

```python
from pyscf import gto, scf, mcscf, fci,ao2mo
mol = gto.Mole()
mol = gto.M(
        atom = methane_geometry,
        basis = basis)
myhf = scf.RHF(mol) #.x2c() The x2c is relativistic. We are not so desperate :P
myhf.kernel()
mol.atom
```

    converged SCF energy = -39.7265817118519

    [('C', (0, 0, 0)),
     ('H', (0.5541, 0.7996, 0.4965)),
     ('H', (0.6833, -0.8134, -0.2536)),
     ('H', (-0.7782, -0.3735, 0.6692)),
     ('H', (-0.4593, 0.3874, -0.9121))]

```python
ao_labels = ['C 2pz']
norb, ne_act, orbs = avas.avas(myhf, ao_labels, canonicalize=False)
mo_ints_myhf = ao2mo.kernel(mol, myhf.mo_coeff) #orbs)
print(mo_ints_myhf.shape)
mo_ints_orbs = ao2mo.kernel(mol, orbs)
print(mo_ints_orbs.shape)
print(mo_ints_myhf - mo_ints_orbs)
```

    (45, 45)
    (45, 45)
    [[ 2.92982983e+00 -2.85459192e-01  5.91465974e-02 ... -1.11860112e-02
       2.66471566e-02  2.05217574e-01]
     [-2.85459192e-01  2.35658170e-02 -1.43562384e-01 ...  3.49209290e-07
       2.42649131e-04 -1.62842063e-02]
     [ 5.91465974e-02 -1.43562384e-01 -2.99766787e+00 ...  1.84095139e-06
      -7.74859929e-06 -2.61148750e-01]
     ...
     [-1.11860112e-02  3.49209289e-07  1.84095139e-06 ... -1.31244080e-05
       5.53431412e-03  1.39180374e-02]
     [ 2.66471566e-02  2.42649131e-04 -7.74859929e-06 ...  5.53431412e-03
       5.74825787e-02  6.73904843e-03]
     [ 2.05217574e-01 -1.62842063e-02 -2.61148750e-01 ...  1.39180374e-02
       6.73904843e-03 -7.40561615e-02]]

```python
'''
To obtain these Hamiltonians one must choose to study the system without a spin degree of freedom (spinless),
one must the specify dimension in which the calculation is performed (n_dimensions, usually 3),
one must specify how many plane waves are in each dimension (grid_length)
and one must specify the length scale of the plane wave harmonics in each dimension (length_scale)
and also the locations and charges of the nuclei.

Taken from https://quantumai.google/openfermion/tutorials/intro_to_openfermion
'''

grid = Grid(dimensions = 3, length = 8, scale = 1.) # La complejidad crece bastante con length
grid.volume_scale()

plane_wave_H = plane_wave_hamiltonian(grid, methane_geometry, True)
plane_wave_H
```

```python
## Selection of active orbitals

ao_labels = ['Fe 3d', 'C 2pz']
norb, ne_act, orbs = avas.avas(mf, ao_labels, canonicalize=False)
```

```python
## Low rank approximation. See
'''
https://quantumai.google/openfermion/tutorials/circuits_3_arbitrary_basis_trotter

Low rank approximation: https://github.com/quantumlib/OpenFermion/blob/4781602e094699f0fe0844bcded8ef0d45653e81/src/openfermion/circuits/low_rank.py#L76

Ground state: https://quantumai.google/reference/python/openfermion/linalg/get_ground_state

On the integration of low rank calculations: https://github.com/quantumlib/OpenFermion/issues/708#issuecomment-777640581
'''
```

```python
molecule = run_psi4(molecule,run_scf=True,
                        run_mp2=True,
                        run_cisd=False,
                        run_ccsd=True,
                        run_fci=False
                   )
```

```python
dir(molecule)
```

    ['__class__',
     '__delattr__',
     '__dict__',
     '__dir__',
     '__doc__',
     '__eq__',
     '__format__',
     '__ge__',
     '__getattribute__',
     '__gt__',
     '__hash__',
     '__init__',
     '__init_subclass__',
     '__le__',
     '__lt__',
     '__module__',
     '__ne__',
     '__new__',
     '__reduce__',
     '__reduce_ex__',
     '__repr__',
     '__setattr__',
     '__sizeof__',
     '__str__',
     '__subclasshook__',
     '__weakref__',
     '_canonical_orbitals',
     '_ccsd_double_amps',
     '_ccsd_single_amps',
     '_cisd_one_rdm',
     '_cisd_two_rdm',
     '_fci_one_rdm',
     '_fci_two_rdm',
     '_one_body_integrals',
     '_overlap_integrals',
     '_two_body_integrals',
     'atoms',
     'basis',
     'canonical_orbitals',
     'ccsd_double_amps',
     'ccsd_energy',
     'ccsd_single_amps',
     'charge',
     'cisd_energy',
     'cisd_one_rdm',
     'cisd_two_rdm',
     'description',
     'fci_energy',
     'fci_one_rdm',
     'fci_two_rdm',
     'filename',
     'general_calculations',
     'geometry',
     'get_active_space_integrals',
     'get_antisym',
     'get_from_file',
     'get_integrals',
     'get_j',
     'get_k',
     'get_molecular_hamiltonian',
     'get_molecular_rdm',
     'get_n_alpha_electrons',
     'get_n_beta_electrons',
     'hf_energy',
     'init_lazy_properties',
     'load',
     'mp2_energy',
     'multiplicity',
     'n_atoms',
     'n_electrons',
     'n_orbitals',
     'n_qubits',
     'name',
     'nuclear_repulsion',
     'one_body_integrals',
     'orbital_energies',
     'overlap_integrals',
     'protons',
     'save',
     'two_body_integrals']

```python
molecule.two_body_integrals
```

    array([[[[ 3.50111808e+00,  2.93359989e-01,  1.10767442e-06, ...,
              -3.28313798e-05, -6.91012233e-05,  3.26772351e-01],
             [ 2.93359989e-01,  3.86008907e-02,  2.06425379e-07, ...,
              -4.34506685e-06, -9.16302869e-06,  4.38093713e-02],
             [ 1.10767442e-06,  2.06425379e-07,  8.77763273e-03, ...,
              -8.81953045e-05,  1.34410199e-02,  2.86638503e-06],
             ...,
             [-3.28313798e-05, -4.34506685e-06, -8.81953045e-05, ...,
               2.07111511e-02, -2.63509490e-08, -2.89584668e-06],
             [-6.91012233e-05, -9.16302869e-06,  1.34410199e-02, ...,
              -2.63509490e-08,  2.07122620e-02, -6.31082236e-06],
             [ 3.26772351e-01,  4.38093713e-02,  2.86638503e-06, ...,
              -2.89584668e-06, -6.31082236e-06,  4.97918460e-02]],

            [[ 2.93359989e-01,  3.86008907e-02,  2.06425379e-07, ...,
              -4.34506685e-06, -9.16302869e-06,  4.38093713e-02],
             [ 7.08049932e-01,  9.18605309e-03, -1.41229460e-07, ...,
              -1.13582449e-06, -2.32160079e-06,  9.68165213e-03],
             [ 3.55133593e-06, -3.53156643e-08, -1.37788849e-02, ...,
               1.25125629e-04, -1.90679933e-02, -3.72634072e-06],
             ...,
             [-2.83415206e-05, -1.06179581e-06,  6.44065334e-05, ...,
              -1.42569709e-02,  1.97199747e-08, -2.52223399e-06],
             [-6.09306795e-05, -2.23060513e-06, -9.81482842e-03, ...,
               1.97259665e-08, -1.42571143e-02, -5.17749579e-06],
             [ 2.87620277e-01,  1.03823976e-02, -1.87134836e-06, ...,
              -2.54526708e-06, -5.16579481e-06,  1.09153886e-02]],

            [[ 1.10767442e-06,  2.06425379e-07,  8.77763273e-03, ...,
              -8.81953045e-05,  1.34410199e-02,  2.86638503e-06],
             [ 3.55133593e-06, -3.53156643e-08, -1.37788849e-02, ...,
               1.25125629e-04, -1.90679933e-02, -3.72634072e-06],
             [ 6.33204173e-01,  3.91902849e-03, -3.67742779e-03, ...,
              -1.58186659e-03, -4.46298057e-03,  3.73327229e-03],
             ...,
             [-1.64474956e-03, -3.57628621e-05,  1.18656398e-03, ...,
              -2.88043313e-03,  1.75897619e-03, -3.46276503e-05],
             [ 2.50609227e-01,  5.44929645e-03,  3.34711879e-03, ...,
               1.75726711e-03,  5.04403945e-03,  5.25585657e-03],
             [ 4.76341024e-05,  1.07477119e-06, -6.77256482e-03, ...,
               6.46649796e-05, -9.87178726e-03, -9.03711095e-07]],

            ...,

            [[-3.28313798e-05, -4.34506685e-06, -8.81953045e-05, ...,
               2.07111511e-02, -2.63509490e-08, -2.89584668e-06],
             [-2.83415206e-05, -1.06179581e-06,  6.44065334e-05, ...,
              -1.42569709e-02,  1.97199747e-08, -2.52223399e-06],
             [-1.64474956e-03, -3.57628621e-05,  1.18656398e-03, ...,
              -2.88043313e-03,  1.75897619e-03, -3.46276503e-05],
             ...,
             [ 7.30916095e-01,  8.45416653e-03, -2.08784404e-04, ...,
              -1.03692031e-03, -6.67196375e-04,  8.07457223e-03],
             [-2.01565298e-07, -1.14455491e-08,  1.28860659e-04, ...,
              -6.61335954e-04,  4.00337188e-04, -4.08711279e-08],
             [ 4.35423201e-06, -4.26310508e-07,  9.23093626e-05, ...,
              -2.01905932e-02, -2.31220933e-08, -2.49459591e-06]],

            [[-6.91012233e-05, -9.16302869e-06,  1.34410199e-02, ...,
              -2.63509490e-08,  2.07122620e-02, -6.31082236e-06],
             [-6.09306795e-05, -2.23060513e-06, -9.81482842e-03, ...,
               1.97259665e-08, -1.42571143e-02, -5.17749579e-06],
             [ 2.50609227e-01,  5.44929645e-03,  3.34711879e-03, ...,
               1.75726711e-03,  5.04403945e-03,  5.25585657e-03],
             ...,
             [-2.01565298e-07, -1.14455491e-08,  1.28860659e-04, ...,
              -6.61335954e-04,  4.00337188e-04, -4.08711280e-08],
             [ 7.30929458e-01,  8.45459050e-03,  3.71731601e-04, ...,
               3.97564082e-04,  1.16894374e-03,  8.07564932e-03],
             [ 7.47527832e-06, -9.59599899e-07, -1.40713753e-02, ...,
              -2.31100940e-08, -2.01906880e-02, -5.10946321e-06]],

            [[ 3.26772351e-01,  4.38093713e-02,  2.86638503e-06, ...,
              -2.89584668e-06, -6.31082236e-06,  4.97918460e-02],
             [ 2.87620277e-01,  1.03823976e-02, -1.87134836e-06, ...,
              -2.54526708e-06, -5.16579481e-06,  1.09153886e-02],
             [ 4.76341024e-05,  1.07477119e-06, -6.77256482e-03, ...,
               6.46649796e-05, -9.87178726e-03, -9.03711095e-07],
             ...,
             [ 4.35423201e-06, -4.26310507e-07,  9.23093626e-05, ...,
              -2.01905932e-02, -2.31220933e-08, -2.49459591e-06],
             [ 7.47527832e-06, -9.59599899e-07, -1.40713753e-02, ...,
              -2.31100940e-08, -2.01906880e-02, -5.10946321e-06],
             [ 6.93626813e-01,  1.22216132e-02, -5.63226815e-06, ...,
              -5.35882864e-06, -1.09470989e-05,  1.26981969e-02]]],

           [[[ 2.93359989e-01,  7.08049932e-01,  3.55133593e-06, ...,
              -2.83415206e-05, -6.09306795e-05,  2.87620277e-01],
             [ 3.86008907e-02,  9.18605309e-03, -3.53156643e-08, ...,
              -1.06179581e-06, -2.23060513e-06,  1.03823976e-02],
             [ 2.06425379e-07, -1.41229460e-07, -1.37788849e-02, ...,
               6.44065334e-05, -9.81482842e-03, -1.87134836e-06],
             ...,
             [-4.34506685e-06, -1.13582449e-06,  1.25125629e-04, ...,
              -1.42569709e-02,  1.97259665e-08, -2.54526708e-06],
             [-9.16302869e-06, -2.32160079e-06, -1.90679933e-02, ...,
               1.97199747e-08, -1.42571143e-02, -5.16579481e-06],
             [ 4.38093713e-02,  9.68165213e-03, -3.72634072e-06, ...,
              -2.52223399e-06, -5.17749580e-06,  1.09153886e-02]],

            [[ 3.86008907e-02,  9.18605309e-03, -3.53156643e-08, ...,
              -1.06179581e-06, -2.23060513e-06,  1.03823976e-02],
             [ 9.18605309e-03,  5.03450166e-01,  3.21671631e-06, ...,
              -8.66094513e-06, -1.94808815e-05,  8.77183115e-02],
             [-3.53156643e-08,  3.21671631e-06,  1.08115986e-01, ...,
              -1.22116196e-04,  1.85996575e-02,  3.06744488e-06],
             ...,
             [-1.06179581e-06, -8.66094513e-06, -1.22116196e-04, ...,
               4.76647154e-02,  8.42450793e-08, -2.20323013e-06],
             [-2.23060513e-06, -1.94808815e-05,  1.85996575e-02, ...,
               8.42450793e-08,  4.76646025e-02, -4.57068000e-06],
             [ 1.03823976e-02,  8.77183115e-02,  3.06744488e-06, ...,
              -2.20323013e-06, -4.57068000e-06,  7.34767459e-02]],

            [[ 2.06425379e-07, -1.41229460e-07, -1.37788849e-02, ...,
               6.44065334e-05, -9.81482842e-03, -1.87134836e-06],
             [-3.53156643e-08,  3.21671631e-06,  1.08115986e-01, ...,
              -1.22116196e-04,  1.85996575e-02,  3.06744488e-06],
             [ 3.91902849e-03,  4.85078209e-01,  5.45464260e-02, ...,
              -6.82034659e-03, -1.92377543e-02,  6.88314722e-02],
             ...,
             [-3.57628621e-05, -5.31163517e-04, -1.76729677e-02, ...,
              -3.36298146e-03,  2.04861041e-03, -4.70514494e-04],
             [ 5.44929645e-03,  8.09269071e-02, -4.98598966e-02, ...,
               2.04559813e-03,  5.86512604e-03,  7.17006501e-02],
             [ 1.07477119e-06,  1.36872951e-05, -1.05354363e-02, ...,
              -2.71611902e-04,  4.13909802e-02,  2.33650853e-05]],

            ...,

            [[-4.34506685e-06, -1.13582449e-06,  1.25125629e-04, ...,
              -1.42569709e-02,  1.97259665e-08, -2.54526708e-06],
             [-1.06179581e-06, -8.66094513e-06, -1.22116196e-04, ...,
               4.76647154e-02,  8.42450792e-08, -2.20323013e-06],
             [-3.57628621e-05, -5.31163517e-04, -1.76729677e-02, ...,
              -3.36298146e-03,  2.04861041e-03, -4.70514494e-04],
             ...,
             [ 8.45416653e-03,  4.93027410e-01, -1.79579657e-02, ...,
               2.65922313e-02,  1.70006790e-02,  8.17318129e-02],
             [-1.14455491e-08,  4.82654193e-08,  1.09508288e-02, ...,
               1.70169833e-02, -1.01859830e-02,  6.16828042e-07],
             [-4.26310508e-07,  3.47471534e-06, -6.33691367e-04, ...,
               8.92744321e-03,  6.58138124e-07,  2.31223997e-06]],

            [[-9.16302869e-06, -2.32160079e-06, -1.90679933e-02, ...,
               1.97199747e-08, -1.42571143e-02, -5.16579481e-06],
             [-2.23060513e-06, -1.94808815e-05,  1.85996575e-02, ...,
               8.42450792e-08,  4.76646025e-02, -4.57068000e-06],
             [ 5.44929645e-03,  8.09269071e-02, -4.98598966e-02, ...,
               2.04559813e-03,  5.86512604e-03,  7.17006501e-02],
             ...,
             [-1.14455491e-08,  4.82654193e-08,  1.09508288e-02, ...,
               1.70169833e-02, -1.01859830e-02,  6.16828042e-07],
             [ 8.45459050e-03,  4.93033242e-01,  3.14033557e-02, ...,
              -1.01934701e-02, -2.97359262e-02,  8.17170195e-02],
             [-9.59599899e-07,  7.41517256e-06,  9.64840370e-02, ...,
               6.58198841e-07,  8.91069925e-03,  3.42974564e-06]],

            [[ 4.38093713e-02,  9.68165213e-03, -3.72634072e-06, ...,
              -2.52223399e-06, -5.17749580e-06,  1.09153886e-02],
             [ 1.03823976e-02,  8.77183115e-02,  3.06744488e-06, ...,
              -2.20323013e-06, -4.57068000e-06,  7.34767459e-02],
             [ 1.07477119e-06,  1.36872951e-05, -1.05354363e-02, ...,
              -2.71611902e-04,  4.13909802e-02,  2.33650853e-05],
             ...,
             [-4.26310508e-07,  3.47471534e-06, -6.33691367e-04, ...,
               8.92744321e-03,  6.58138124e-07,  2.31223997e-06],
             [-9.59599899e-07,  7.41517256e-06,  9.64840370e-02, ...,
               6.58198841e-07,  8.91069925e-03,  3.42974564e-06],
             [ 1.22216132e-02,  4.69767734e-01,  4.18023449e-05, ...,
              -4.89659525e-06, -1.21614618e-05,  6.56355674e-02]]],

           [[[ 1.10767442e-06,  3.55133593e-06,  6.33204173e-01, ...,
              -1.64474956e-03,  2.50609227e-01,  4.76341024e-05],
             [ 2.06425379e-07, -3.53156643e-08,  3.91902849e-03, ...,
              -3.57628621e-05,  5.44929645e-03,  1.07477119e-06],
             [ 8.77763273e-03, -1.37788849e-02, -3.67742779e-03, ...,
               1.18656398e-03,  3.34711879e-03, -6.77256482e-03],
             ...,
             [-8.81953045e-05,  1.25125629e-04, -1.58186659e-03, ...,
              -2.88043313e-03,  1.75726711e-03,  6.46649796e-05],
             [ 1.34410199e-02, -1.90679933e-02, -4.46298057e-03, ...,
               1.75897619e-03,  5.04403945e-03, -9.87178726e-03],
             [ 2.86638503e-06, -3.72634072e-06,  3.73327229e-03, ...,
              -3.46276503e-05,  5.25585657e-03, -9.03711095e-07]],

            [[ 2.06425379e-07, -3.53156643e-08,  3.91902849e-03, ...,
              -3.57628621e-05,  5.44929645e-03,  1.07477119e-06],
             [-1.41229460e-07,  3.21671631e-06,  4.85078209e-01, ...,
              -5.31163517e-04,  8.09269071e-02,  1.36872951e-05],
             [-1.37788849e-02,  1.08115986e-01,  5.45464260e-02, ...,
              -1.76729677e-02, -4.98598966e-02, -1.05354363e-02],
             ...,
             [ 6.44065334e-05, -1.22116196e-04, -6.82034659e-03, ...,
              -3.36298146e-03,  2.04559813e-03, -2.71611902e-04],
             [-9.81482842e-03,  1.85996575e-02, -1.92377543e-02, ...,
               2.04861041e-03,  5.86512604e-03,  4.13909802e-02],
             [-1.87134836e-06,  3.06744488e-06,  6.88314722e-02, ...,
              -4.70514494e-04,  7.17006501e-02,  2.33650853e-05]],

            [[ 8.77763273e-03, -1.37788849e-02, -3.67742779e-03, ...,
               1.18656398e-03,  3.34711879e-03, -6.77256482e-03],
             [-1.37788849e-02,  1.08115986e-01,  5.45464260e-02, ...,
              -1.76729677e-02, -4.98598966e-02, -1.05354363e-02],
             [-3.67742779e-03,  5.45464260e-02,  5.46182984e-01, ...,
              -3.53212839e-03,  2.60690805e-02, -2.88691240e-02],
             ...,
             [ 1.18656398e-03, -1.76729677e-02, -3.53212839e-03, ...,
               2.65790147e-02,  2.08745115e-03,  8.54093957e-03],
             [ 3.34711879e-03, -4.98598966e-02,  2.60690805e-02, ...,
               2.08745115e-03,  1.27781451e-01,  2.41109016e-02],
             [-6.77256482e-03, -1.05354363e-02, -2.88691240e-02, ...,
               8.54093957e-03,  2.41109016e-02,  4.70702988e-02]],

            ...,

            [[-8.81953045e-05,  1.25125629e-04, -1.58186659e-03, ...,
              -2.88043313e-03,  1.75726711e-03,  6.46649796e-05],
             [ 6.44065334e-05, -1.22116196e-04, -6.82034659e-03, ...,
              -3.36298146e-03,  2.04559813e-03, -2.71611902e-04],
             [ 1.18656398e-03, -1.76729677e-02, -3.53212839e-03, ...,
               2.65790147e-02,  2.08745115e-03,  8.54093957e-03],
             ...,
             [-2.08784404e-04, -1.79579657e-02,  4.50045695e-01, ...,
              -8.49638631e-03,  8.82422963e-02,  2.11341434e-02],
             [ 1.28860659e-04,  1.09508288e-02,  2.50289706e-03, ...,
              -4.04799749e-03, -2.55352239e-03, -1.28886098e-02],
             [ 9.23093626e-05, -6.33691367e-04,  1.86134377e-02, ...,
               3.11226522e-02, -1.89925526e-02,  1.25310980e-04]],

            [[ 1.34410199e-02, -1.90679933e-02, -4.46298057e-03, ...,
               1.75897619e-03,  5.04403945e-03, -9.87178726e-03],
             [-9.81482842e-03,  1.85996575e-02, -1.92377543e-02, ...,
               2.04861041e-03,  5.86512604e-03,  4.13909802e-02],
             [ 3.34711879e-03, -4.98598966e-02,  2.60690805e-02, ...,
               2.08745115e-03,  1.27781451e-01,  2.41109016e-02],
             ...,
             [ 1.28860659e-04,  1.09508288e-02,  2.50289706e-03, ...,
              -4.04799749e-03, -2.55352239e-03, -1.28886098e-02],
             [ 3.71731601e-04,  3.14033557e-02,  5.37769937e-01, ...,
              -3.15977911e-03,  4.58716473e-02, -3.69569922e-02],
             [-1.40713753e-02,  9.64840370e-02,  5.25253416e-02, ...,
              -1.89951557e-02, -5.44872612e-02, -1.87973186e-02]],

            [[ 2.86638503e-06, -3.72634072e-06,  3.73327229e-03, ...,
              -3.46276503e-05,  5.25585657e-03, -9.03711095e-07],
             [-1.87134836e-06,  3.06744488e-06,  6.88314722e-02, ...,
              -4.70514494e-04,  7.17006501e-02,  2.33650853e-05],
             [-6.77256482e-03, -1.05354363e-02, -2.88691240e-02, ...,
               8.54093957e-03,  2.41109016e-02,  4.70702988e-02],
             ...,
             [ 9.23093626e-05, -6.33691367e-04,  1.86134377e-02, ...,
               3.11226522e-02, -1.89925526e-02,  1.25310980e-04],
             [-1.40713753e-02,  9.64840370e-02,  5.25253416e-02, ...,
              -1.89951557e-02, -5.44872612e-02, -1.87973186e-02],
             [-5.63226815e-06,  4.18023449e-05,  4.59426468e-01, ...,
              -3.70220438e-04,  5.67780971e-02,  4.96886151e-07]]],

           ...,

           [[[-3.28313798e-05, -2.83415206e-05, -1.64474956e-03, ...,
               7.30916095e-01, -2.01565298e-07,  4.35423201e-06],
             [-4.34506685e-06, -1.06179581e-06, -3.57628621e-05, ...,
               8.45416653e-03, -1.14455491e-08, -4.26310508e-07],
             [-8.81953045e-05,  6.44065334e-05,  1.18656398e-03, ...,
              -2.08784404e-04,  1.28860659e-04,  9.23093626e-05],
             ...,
             [ 2.07111511e-02, -1.42569709e-02, -2.88043313e-03, ...,
              -1.03692031e-03, -6.61335954e-04, -2.01905932e-02],
             [-2.63509490e-08,  1.97199747e-08,  1.75897619e-03, ...,
              -6.67196375e-04,  4.00337188e-04, -2.31220933e-08],
             [-2.89584668e-06, -2.52223399e-06, -3.46276503e-05, ...,
               8.07457223e-03, -4.08711279e-08, -2.49459591e-06]],

            [[-4.34506685e-06, -1.06179581e-06, -3.57628621e-05, ...,
               8.45416653e-03, -1.14455491e-08, -4.26310508e-07],
             [-1.13582449e-06, -8.66094513e-06, -5.31163517e-04, ...,
               4.93027410e-01,  4.82654193e-08,  3.47471534e-06],
             [ 1.25125629e-04, -1.22116196e-04, -1.76729677e-02, ...,
              -1.79579657e-02,  1.09508288e-02, -6.33691367e-04],
             ...,
             [-1.42569709e-02,  4.76647154e-02, -3.36298146e-03, ...,
               2.65922313e-02,  1.70169833e-02,  8.92744321e-03],
             [ 1.97259665e-08,  8.42450792e-08,  2.04861041e-03, ...,
               1.70006790e-02, -1.01859830e-02,  6.58138124e-07],
             [-2.54526708e-06, -2.20323013e-06, -4.70514494e-04, ...,
               8.17318129e-02,  6.16828042e-07,  2.31223997e-06]],

            [[-8.81953045e-05,  6.44065334e-05,  1.18656398e-03, ...,
              -2.08784404e-04,  1.28860659e-04,  9.23093626e-05],
             [ 1.25125629e-04, -1.22116196e-04, -1.76729677e-02, ...,
              -1.79579657e-02,  1.09508288e-02, -6.33691367e-04],
             [-1.58186659e-03, -6.82034659e-03, -3.53212839e-03, ...,
               4.50045695e-01,  2.50289706e-03,  1.86134377e-02],
             ...,
             [-2.88043313e-03, -3.36298146e-03,  2.65790147e-02, ...,
              -8.49638631e-03, -4.04799749e-03,  3.11226522e-02],
             [ 1.75726711e-03,  2.04559813e-03,  2.08745115e-03, ...,
               8.82422963e-02, -2.55352239e-03, -1.89925526e-02],
             [ 6.46649796e-05, -2.71611902e-04,  8.54093957e-03, ...,
               2.11341434e-02, -1.28886098e-02,  1.25310980e-04]],

            ...,

            [[ 2.07111511e-02, -1.42569709e-02, -2.88043313e-03, ...,
              -1.03692031e-03, -6.61335954e-04, -2.01905932e-02],
             [-1.42569709e-02,  4.76647154e-02, -3.36298146e-03, ...,
               2.65922313e-02,  1.70169833e-02,  8.92744321e-03],
             [-2.88043313e-03, -3.36298146e-03,  2.65790147e-02, ...,
              -8.49638631e-03, -4.04799749e-03,  3.11226522e-02],
             ...,
             [-1.03692031e-03,  2.65922313e-02, -8.49638631e-03, ...,
               5.61190785e-01,  9.40789903e-03, -3.31969562e-02],
             [-6.61335954e-04,  1.70169833e-02, -4.04799749e-03, ...,
               9.40789903e-03,  2.79620622e-02, -2.12487548e-02],
             [-2.01905932e-02,  8.92744321e-03,  3.11226522e-02, ...,
              -3.31969562e-02, -2.12487548e-02,  1.01806000e-01]],

            [[-2.63509490e-08,  1.97199747e-08,  1.75897619e-03, ...,
              -6.67196375e-04,  4.00337188e-04, -2.31220933e-08],
             [ 1.97259665e-08,  8.42450792e-08,  2.04861041e-03, ...,
               1.70006790e-02, -1.01859830e-02,  6.58138124e-07],
             [ 1.75726711e-03,  2.04559813e-03,  2.08745115e-03, ...,
               8.82422963e-02, -2.55352239e-03, -1.89925526e-02],
             ...,
             [-6.61335954e-04,  1.70169833e-02, -4.04799749e-03, ...,
               9.40789903e-03,  2.79620622e-02, -2.12487548e-02],
             [ 3.97564082e-04, -1.01934701e-02, -3.15977911e-03, ...,
               4.67730306e-01,  3.01499502e-03,  1.27084640e-02],
             [-2.31100940e-08,  6.58198841e-07, -1.89951557e-02, ...,
              -2.12351669e-02,  1.27020238e-02, -1.60013524e-06]],

            [[-2.89584668e-06, -2.52223399e-06, -3.46276503e-05, ...,
               8.07457223e-03, -4.08711280e-08, -2.49459591e-06],
             [-2.54526708e-06, -2.20323013e-06, -4.70514494e-04, ...,
               8.17318129e-02,  6.16828042e-07,  2.31223997e-06],
             [ 6.46649796e-05, -2.71611902e-04,  8.54093957e-03, ...,
               2.11341434e-02, -1.28886098e-02,  1.25310980e-04],
             ...,
             [-2.01905932e-02,  8.92744321e-03,  3.11226522e-02, ...,
              -3.31969562e-02, -2.12487548e-02,  1.01806000e-01],
             [-2.31100940e-08,  6.58198841e-07, -1.89951557e-02, ...,
              -2.12351669e-02,  1.27020238e-02, -1.60013524e-06],
             [-5.35882864e-06, -4.89659525e-06, -3.70220438e-04, ...,
               4.77271777e-01, -1.69108655e-06,  2.26242104e-05]]],

           [[[-6.91012233e-05, -6.09306795e-05,  2.50609227e-01, ...,
              -2.01565298e-07,  7.30929458e-01,  7.47527832e-06],
             [-9.16302869e-06, -2.23060513e-06,  5.44929645e-03, ...,
              -1.14455491e-08,  8.45459050e-03, -9.59599899e-07],
             [ 1.34410199e-02, -9.81482842e-03,  3.34711879e-03, ...,
               1.28860659e-04,  3.71731601e-04, -1.40713753e-02],
             ...,
             [-2.63509490e-08,  1.97259665e-08,  1.75726711e-03, ...,
              -6.61335954e-04,  3.97564082e-04, -2.31100940e-08],
             [ 2.07122620e-02, -1.42571143e-02,  5.04403945e-03, ...,
               4.00337188e-04,  1.16894374e-03, -2.01906880e-02],
             [-6.31082236e-06, -5.17749579e-06,  5.25585657e-03, ...,
              -4.08711280e-08,  8.07564932e-03, -5.10946321e-06]],

            [[-9.16302869e-06, -2.23060513e-06,  5.44929645e-03, ...,
              -1.14455491e-08,  8.45459050e-03, -9.59599899e-07],
             [-2.32160079e-06, -1.94808815e-05,  8.09269071e-02, ...,
               4.82654193e-08,  4.93033242e-01,  7.41517256e-06],
             [-1.90679933e-02,  1.85996575e-02, -4.98598966e-02, ...,
               1.09508288e-02,  3.14033557e-02,  9.64840370e-02],
             ...,
             [ 1.97199747e-08,  8.42450792e-08,  2.04559813e-03, ...,
               1.70169833e-02, -1.01934701e-02,  6.58198841e-07],
             [-1.42571143e-02,  4.76646025e-02,  5.86512604e-03, ...,
              -1.01859830e-02, -2.97359262e-02,  8.91069925e-03],
             [-5.16579481e-06, -4.57068000e-06,  7.17006501e-02, ...,
               6.16828042e-07,  8.17170195e-02,  3.42974564e-06]],

            [[ 1.34410199e-02, -9.81482842e-03,  3.34711879e-03, ...,
               1.28860659e-04,  3.71731601e-04, -1.40713753e-02],
             [-1.90679933e-02,  1.85996575e-02, -4.98598966e-02, ...,
               1.09508288e-02,  3.14033557e-02,  9.64840370e-02],
             [-4.46298057e-03, -1.92377543e-02,  2.60690805e-02, ...,
               2.50289706e-03,  5.37769937e-01,  5.25253416e-02],
             ...,
             [ 1.75897619e-03,  2.04861041e-03,  2.08745115e-03, ...,
              -4.04799749e-03, -3.15977911e-03, -1.89951557e-02],
             [ 5.04403945e-03,  5.86512604e-03,  1.27781451e-01, ...,
              -2.55352239e-03,  4.58716473e-02, -5.44872612e-02],
             [-9.87178726e-03,  4.13909802e-02,  2.41109016e-02, ...,
              -1.28886098e-02, -3.69569922e-02, -1.87973186e-02]],

            ...,

            [[-2.63509490e-08,  1.97259665e-08,  1.75726711e-03, ...,
              -6.61335954e-04,  3.97564082e-04, -2.31100940e-08],
             [ 1.97199747e-08,  8.42450792e-08,  2.04559813e-03, ...,
               1.70169833e-02, -1.01934701e-02,  6.58198841e-07],
             [ 1.75897619e-03,  2.04861041e-03,  2.08745115e-03, ...,
              -4.04799749e-03, -3.15977911e-03, -1.89951557e-02],
             ...,
             [-6.67196375e-04,  1.70006790e-02,  8.82422963e-02, ...,
               9.40789903e-03,  4.67730306e-01, -2.12351669e-02],
             [ 4.00337188e-04, -1.01859830e-02, -2.55352239e-03, ...,
               2.79620622e-02,  3.01499502e-03,  1.27020238e-02],
             [-2.31220933e-08,  6.58138124e-07, -1.89925526e-02, ...,
              -2.12487548e-02,  1.27084640e-02, -1.60013524e-06]],

            [[ 2.07122620e-02, -1.42571143e-02,  5.04403945e-03, ...,
               4.00337188e-04,  1.16894374e-03, -2.01906880e-02],
             [-1.42571143e-02,  4.76646025e-02,  5.86512604e-03, ...,
              -1.01859830e-02, -2.97359262e-02,  8.91069925e-03],
             [ 5.04403945e-03,  5.86512604e-03,  1.27781451e-01, ...,
              -2.55352239e-03,  4.58716473e-02, -5.44872612e-02],
             ...,
             [ 4.00337188e-04, -1.01859830e-02, -2.55352239e-03, ...,
               2.79620622e-02,  3.01499502e-03,  1.27020238e-02],
             [ 1.16894374e-03, -2.97359262e-02,  4.58716473e-02, ...,
               3.01499502e-03,  5.63117985e-01,  3.70448140e-02],
             [-2.01906880e-02,  8.91069925e-03, -5.44872612e-02, ...,
               1.27020238e-02,  3.70448140e-02,  1.01845168e-01]],

            [[-6.31082236e-06, -5.17749579e-06,  5.25585657e-03, ...,
              -4.08711280e-08,  8.07564932e-03, -5.10946321e-06],
             [-5.16579481e-06, -4.57068000e-06,  7.17006501e-02, ...,
               6.16828042e-07,  8.17170195e-02,  3.42974564e-06],
             [-9.87178726e-03,  4.13909802e-02,  2.41109016e-02, ...,
              -1.28886098e-02, -3.69569922e-02, -1.87973186e-02],
             ...,
             [-2.31220933e-08,  6.58138124e-07, -1.89925526e-02, ...,
              -2.12487548e-02,  1.27084640e-02, -1.60013524e-06],
             [-2.01906880e-02,  8.91069925e-03, -5.44872612e-02, ...,
               1.27020238e-02,  3.70448140e-02,  1.01845168e-01],
             [-1.09470989e-05, -1.21614618e-05,  5.67780971e-02, ...,
              -1.69108655e-06,  4.77312715e-01,  4.77368077e-05]]],

           [[[ 3.26772351e-01,  2.87620277e-01,  4.76341024e-05, ...,
               4.35423201e-06,  7.47527832e-06,  6.93626813e-01],
             [ 4.38093713e-02,  1.03823976e-02,  1.07477119e-06, ...,
              -4.26310508e-07, -9.59599899e-07,  1.22216132e-02],
             [ 2.86638503e-06, -1.87134836e-06, -6.77256482e-03, ...,
               9.23093626e-05, -1.40713753e-02, -5.63226815e-06],
             ...,
             [-2.89584668e-06, -2.54526708e-06,  6.46649796e-05, ...,
              -2.01905932e-02, -2.31100940e-08, -5.35882864e-06],
             [-6.31082236e-06, -5.16579481e-06, -9.87178726e-03, ...,
              -2.31220933e-08, -2.01906880e-02, -1.09470989e-05],
             [ 4.97918460e-02,  1.09153886e-02, -9.03711095e-07, ...,
              -2.49459592e-06, -5.10946321e-06,  1.26981969e-02]],

            [[ 4.38093713e-02,  1.03823976e-02,  1.07477119e-06, ...,
              -4.26310508e-07, -9.59599899e-07,  1.22216132e-02],
             [ 9.68165213e-03,  8.77183115e-02,  1.36872951e-05, ...,
               3.47471534e-06,  7.41517256e-06,  4.69767734e-01],
             [-3.72634072e-06,  3.06744488e-06, -1.05354363e-02, ...,
              -6.33691367e-04,  9.64840370e-02,  4.18023449e-05],
             ...,
             [-2.52223399e-06, -2.20323013e-06, -2.71611902e-04, ...,
               8.92744321e-03,  6.58198841e-07, -4.89659525e-06],
             [-5.17749579e-06, -4.57068000e-06,  4.13909802e-02, ...,
               6.58138124e-07,  8.91069925e-03, -1.21614618e-05],
             [ 1.09153886e-02,  7.34767459e-02,  2.33650853e-05, ...,
               2.31223997e-06,  3.42974564e-06,  6.56355674e-02]],

            [[ 2.86638503e-06, -1.87134836e-06, -6.77256482e-03, ...,
               9.23093626e-05, -1.40713753e-02, -5.63226815e-06],
             [-3.72634072e-06,  3.06744488e-06, -1.05354363e-02, ...,
              -6.33691367e-04,  9.64840370e-02,  4.18023449e-05],
             [ 3.73327229e-03,  6.88314722e-02, -2.88691240e-02, ...,
               1.86134377e-02,  5.25253416e-02,  4.59426468e-01],
             ...,
             [-3.46276503e-05, -4.70514494e-04,  8.54093957e-03, ...,
               3.11226522e-02, -1.89951557e-02, -3.70220438e-04],
             [ 5.25585657e-03,  7.17006501e-02,  2.41109016e-02, ...,
              -1.89925526e-02, -5.44872612e-02,  5.67780971e-02],
             [-9.03711095e-07,  2.33650853e-05,  4.70702988e-02, ...,
               1.25310980e-04, -1.87973186e-02,  4.96886152e-07]],

            ...,

            [[-2.89584668e-06, -2.54526708e-06,  6.46649796e-05, ...,
              -2.01905932e-02, -2.31100940e-08, -5.35882864e-06],
             [-2.52223399e-06, -2.20323013e-06, -2.71611902e-04, ...,
               8.92744321e-03,  6.58198841e-07, -4.89659525e-06],
             [-3.46276503e-05, -4.70514494e-04,  8.54093957e-03, ...,
               3.11226522e-02, -1.89951557e-02, -3.70220438e-04],
             ...,
             [ 8.07457223e-03,  8.17318129e-02,  2.11341434e-02, ...,
              -3.31969562e-02, -2.12351669e-02,  4.77271777e-01],
             [-4.08711280e-08,  6.16828042e-07, -1.28886098e-02, ...,
              -2.12487548e-02,  1.27020238e-02, -1.69108655e-06],
             [-2.49459591e-06,  2.31223997e-06,  1.25310980e-04, ...,
               1.01806000e-01, -1.60013524e-06,  2.26242104e-05]],

            [[-6.31082236e-06, -5.16579481e-06, -9.87178726e-03, ...,
              -2.31220933e-08, -2.01906880e-02, -1.09470989e-05],
             [-5.17749579e-06, -4.57068000e-06,  4.13909802e-02, ...,
               6.58138124e-07,  8.91069925e-03, -1.21614618e-05],
             [ 5.25585657e-03,  7.17006501e-02,  2.41109016e-02, ...,
              -1.89925526e-02, -5.44872612e-02,  5.67780971e-02],
             ...,
             [-4.08711280e-08,  6.16828042e-07, -1.28886098e-02, ...,
              -2.12487548e-02,  1.27020238e-02, -1.69108655e-06],
             [ 8.07564932e-03,  8.17170195e-02, -3.69569922e-02, ...,
               1.27084640e-02,  3.70448140e-02,  4.77312715e-01],
             [-5.10946321e-06,  3.42974564e-06, -1.87973186e-02, ...,
              -1.60013524e-06,  1.01845168e-01,  4.77368077e-05]],

            [[ 4.97918460e-02,  1.09153886e-02, -9.03711095e-07, ...,
              -2.49459591e-06, -5.10946321e-06,  1.26981969e-02],
             [ 1.09153886e-02,  7.34767459e-02,  2.33650853e-05, ...,
               2.31223997e-06,  3.42974564e-06,  6.56355674e-02],
             [-9.03711095e-07,  2.33650853e-05,  4.70702988e-02, ...,
               1.25310980e-04, -1.87973186e-02,  4.96886151e-07],
             ...,
             [-2.49459591e-06,  2.31223997e-06,  1.25310980e-04, ...,
               1.01806000e-01, -1.60013524e-06,  2.26242104e-05],
             [-5.10946321e-06,  3.42974564e-06, -1.87973186e-02, ...,
              -1.60013524e-06,  1.01845168e-01,  4.77368077e-05],
             [ 1.26981969e-02,  6.56355674e-02,  4.96886151e-07, ...,
               2.26242104e-05,  4.77368077e-05,  4.61373762e-01]]]])

```python
fermionic_hamiltonian = get_fermion_operator(molecule.get_molecular_hamiltonian())
plane_waves_hamiltonian = openfermion.get_diagonal_coulomb_hamiltonian(fermionic_hamiltonian)
plane_waves_hamiltonian
```

```python
from functools import reduce
import numpy
from pyscf import gto
from pyscf import scf
from pyscf import mcscf
from pyscf import fci

```

```python
mol = gto.Mole()
mol.atom = '''
Fe     0.000000    0.000000    0.000000
C     -0.713500   -0.982049   -1.648000
C      0.713500   -0.982049   -1.648000
C      1.154467    0.375109   -1.648000
C      0.000000    1.213879   -1.648000
C     -1.154467    0.375109   -1.648000
H     -1.347694   -1.854942   -1.638208
H      1.347694   -1.854942   -1.638208
H      2.180615    0.708525   -1.638208
H      0.000000    2.292835   -1.638208
H     -2.180615    0.708525   -1.638208
C     -0.713500   -0.982049    1.648000
C     -1.154467    0.375109    1.648000
C     -0.000000    1.213879    1.648000
C      1.154467    0.375109    1.648000
C      0.713500   -0.982049    1.648000
H     -1.347694   -1.854942    1.638208
H     -2.180615    0.708525    1.638208
H      0.000000    2.292835    1.638208
H      2.180615    0.708525    1.638208
H      1.347694   -1.854942    1.638208
'''
mol.basis = 'cc-pvtz-dk'
mol.spin = 0
mol.build()
```

    <pyscf.gto.mole.Mole at 0x7fc0ff3e5438>

```python
mol.__dict__
```

    {'output': None,
     'max_memory': 4000,
     'charge': 0,
     'spin': 0,
     'symmetry': False,
     'symmetry_subgroup': None,
     'cart': False,
     'atom': '\nFe     0.000000    0.000000    0.000000 \nC     -0.713500   -0.982049   -1.648000 \nC      0.713500   -0.982049   -1.648000 \nC      1.154467    0.375109   -1.648000 \nC      0.000000    1.213879   -1.648000 \nC     -1.154467    0.375109   -1.648000 \nH     -1.347694   -1.854942   -1.638208 \nH      1.347694   -1.854942   -1.638208 \nH      2.180615    0.708525   -1.638208 \nH      0.000000    2.292835   -1.638208 \nH     -2.180615    0.708525   -1.638208 \nC     -0.713500   -0.982049    1.648000 \nC     -1.154467    0.375109    1.648000 \nC     -0.000000    1.213879    1.648000 \nC      1.154467    0.375109    1.648000 \nC      0.713500   -0.982049    1.648000 \nH     -1.347694   -1.854942    1.638208 \nH     -2.180615    0.708525    1.638208 \nH      0.000000    2.292835    1.638208 \nH      2.180615    0.708525    1.638208 \nH      1.347694   -1.854942    1.638208  \n',
     'basis': 'cc-pvtz-dk',
     'nucmod': {},
     'ecp': {},
     'nucprop': {},
     '_atm': array([[ 26,  20,   1,  23,   0,   0],
            [  6,  24,   1,  27,   0,   0],
            [  6,  28,   1,  31,   0,   0],
            [  6,  32,   1,  35,   0,   0],
            [  6,  36,   1,  39,   0,   0],
            [  6,  40,   1,  43,   0,   0],
            [  1,  44,   1,  47,   0,   0],
            [  1,  48,   1,  51,   0,   0],
            [  1,  52,   1,  55,   0,   0],
            [  1,  56,   1,  59,   0,   0],
            [  1,  60,   1,  63,   0,   0],
            [  6,  64,   1,  67,   0,   0],
            [  6,  68,   1,  71,   0,   0],
            [  6,  72,   1,  75,   0,   0],
            [  6,  76,   1,  79,   0,   0],
            [  6,  80,   1,  83,   0,   0],
            [  1,  84,   1,  87,   0,   0],
            [  1,  88,   1,  91,   0,   0],
            [  1,  92,   1,  95,   0,   0],
            [  1,  96,   1,  99,   0,   0],
            [  1, 100,   1, 103,   0,   0]], dtype=int32),
     '_bas': array([[  0,   0,  19, ..., 148, 167,   0],
            [  0,   0,   1, ..., 281, 282,   0],
            [  0,   1,  15, ..., 283, 298,   0],
            ...,
            [ 20,   1,   1, ..., 421, 422,   0],
            [ 20,   1,   1, ..., 423, 424,   0],
            [ 20,   2,   1, ..., 425, 426,   0]], dtype=int32),
     '_env': array([ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
             0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,
            -1.34831959e+00, -1.85580365e+00, -3.11426865e+00,  0.00000000e+00,
             1.34831959e+00, -1.85580365e+00, -3.11426865e+00,  0.00000000e+00,
             2.18162645e+00,  7.08853277e-01, -3.11426865e+00,  0.00000000e+00,
             0.00000000e+00,  2.29389886e+00, -3.11426865e+00,  0.00000000e+00,
            -2.18162645e+00,  7.08853277e-01, -3.11426865e+00,  0.00000000e+00,
            -2.54677256e+00, -3.50533236e+00, -3.09576446e+00,  0.00000000e+00,
             2.54677256e+00, -3.50533236e+00, -3.09576446e+00,  0.00000000e+00,
             4.12076513e+00,  1.33891820e+00, -3.09576446e+00,  0.00000000e+00,
             0.00000000e+00,  4.33283020e+00, -3.09576446e+00,  0.00000000e+00,
            -4.12076513e+00,  1.33891820e+00, -3.09576446e+00,  0.00000000e+00,
            -1.34831959e+00, -1.85580365e+00,  3.11426865e+00,  0.00000000e+00,
            -2.18162645e+00,  7.08853277e-01,  3.11426865e+00,  0.00000000e+00,
             0.00000000e+00,  2.29389886e+00,  3.11426865e+00,  0.00000000e+00,
             2.18162645e+00,  7.08853277e-01,  3.11426865e+00,  0.00000000e+00,
             1.34831959e+00, -1.85580365e+00,  3.11426865e+00,  0.00000000e+00,
            -2.54677256e+00, -3.50533236e+00,  3.09576446e+00,  0.00000000e+00,
            -4.12076513e+00,  1.33891820e+00,  3.09576446e+00,  0.00000000e+00,
             0.00000000e+00,  4.33283020e+00,  3.09576446e+00,  0.00000000e+00,
             4.12076513e+00,  1.33891820e+00,  3.09576446e+00,  0.00000000e+00,
             2.54677256e+00, -3.50533236e+00,  3.09576446e+00,  0.00000000e+00,
             8.23600000e+03,  1.23500000e+03,  2.80800000e+02,  7.92700000e+01,
             2.55900000e+01,  8.99700000e+00,  3.31900000e+00,  3.64300000e-01,
             1.51092978e+00,  2.30028597e+00,  3.78085788e+00,  5.63467028e+00,
             6.90228313e+00,  5.82189670e+00,  2.19400053e+00, -1.08364117e-02,
            -5.48474761e-01, -8.37447421e-01, -1.38627626e+00, -2.12609047e+00,
            -2.79077716e+00, -2.89628036e+00, -1.83642868e+00,  1.23250240e+00,
             9.05900000e-01,  2.34598494e+00,  1.28500000e-01,  5.42241022e-01,
             1.87100000e+01,  4.13300000e+00,  1.20000000e+00,  4.48904647e+00,
             4.19768669e+00,  2.98763027e+00,  3.82700000e-01,  8.78127282e-01,
             1.20900000e-01,  2.07977938e-01,  1.09700000e+00,  3.06825171e+00,
             3.18000000e-01,  3.51379844e-01,  7.61000000e-01,  1.06690522e+00,
             4.31626500e+06,  6.46342400e+05,  1.47089700e+05,  4.16615200e+04,
             1.35907700e+04,  4.90575000e+03,  1.91274600e+03,  7.92604300e+02,
             3.44806500e+02,  1.55899900e+02,  7.22309100e+01,  3.27250600e+01,
             1.56676200e+01,  7.50348300e+00,  3.31222300e+00,  1.55847100e+00,
             6.83914000e-01,  1.46757000e-01,  7.05830000e-02,  3.34945134e+01,
             2.33247270e+01,  2.12339771e+01,  2.14171129e+01,  2.40769159e+01,
             2.93496851e+01,  3.70729071e+01,  4.48088389e+01,  4.67322128e+01,
             3.55940807e+01,  1.46257769e+01,  2.55879631e+00,  1.80958542e+00,
             1.01824838e+00,  8.87158080e-02, -1.36379650e-03,  1.52004229e-05,
            -1.49762710e-05,  1.10710707e-05, -1.72257137e+01, -1.20366858e+01,
            -1.09869947e+01, -1.10953232e+01, -1.25265848e+01, -1.53960383e+01,
            -1.97837700e+01, -2.48244728e+01, -2.81168176e+01, -2.56542315e+01,
            -1.43762959e+01,  1.59327273e+00,  1.02474583e+01,  5.58014937e+00,
             5.23411006e-01, -2.08304502e-02, -8.36021508e-05, -2.91737148e-04,
             1.51188993e-04,  4.06974987e+00,  2.82377954e+00,  2.56335164e+00,
             2.59496628e+00,  2.93712527e+00,  3.63360109e+00,  4.71691163e+00,
             6.08229856e+00,  7.23016411e+00,  7.30884938e+00,  4.66206211e+00,
            -8.89338367e-01, -6.14467956e+00, -5.11798675e+00,  9.24740638e-01,
             2.54028507e+00,  7.40912666e-01,  1.14994219e-02, -2.43128278e-03,
            -1.27064278e+00, -8.41147338e-01, -7.30662972e-01, -7.53224544e-01,
            -8.48714279e-01, -1.05199880e+00, -1.36608599e+00, -1.76287110e+00,
            -2.09742961e+00, -2.12708082e+00, -1.36165834e+00,  2.59001807e-01,
             1.88145027e+00,  1.63945063e+00, -3.64546653e-01, -1.05745761e+00,
            -5.99488889e-01,  2.36851996e-01,  2.59769283e-01, -1.73934259e+00,
            -1.25609444e+00, -1.14306442e+00, -1.18601190e+00, -1.29802068e+00,
            -1.69345006e+00, -2.04378565e+00, -2.90211584e+00, -3.04106788e+00,
            -3.68757391e+00, -1.64820245e+00, -2.83157581e-01,  3.95648045e+00,
             1.76349591e+00,  3.27021164e-01, -3.70481160e+00,  6.75559356e-01,
             1.15552472e+00, -3.82200882e-01, -1.73717388e+00, -1.25452828e+00,
            -1.13671832e+00, -1.17243305e+00, -1.27770942e+00, -1.67482460e+00,
            -2.00826526e+00, -2.87758591e+00, -2.98752509e+00, -3.68613644e+00,
            -1.61131696e+00, -3.34435684e-01,  4.16499181e+00,  2.22227193e+00,
            -7.58648631e-01, -4.60727418e+00,  3.02080367e+00, -1.72340269e-01,
            -3.27957661e-01,  3.14490000e-02,  1.88677518e-01,  1.77456900e+04,
             4.20072100e+03,  1.36442900e+03,  5.22080600e+02,  2.21459500e+02,
             1.00909600e+02,  4.84011500e+01,  2.39853600e+01,  1.21825000e+01,
             6.24229800e+00,  3.11094400e+00,  1.50995800e+00,  7.10845000e-01,
             2.72598000e-01,  1.03972000e-01,  7.34946211e+01,  5.58413050e+01,
             6.30929152e+01,  7.49518965e+01,  8.66102976e+01,  9.02155699e+01,
             7.82231433e+01,  5.14816685e+01,  2.19625257e+01,  4.45397627e+00,
             2.52681661e-01, -1.14556154e-02, -3.53030885e-03, -1.82157444e-04,
             5.16715017e-06, -2.56960383e+01, -1.97340578e+01, -2.23317100e+01,
            -2.67074777e+01, -3.12544887e+01, -3.34512337e+01, -3.01044569e+01,
            -2.08603854e+01, -9.09166955e+00,  9.70531476e-01,  4.04631205e+00,
             2.22444798e+00,  5.36573947e-01,  2.59473308e-02, -5.45193682e-04,
             7.52207684e+00,  6.07206786e+00,  6.80164369e+00,  8.14687540e+00,
             9.54509995e+00,  1.02424474e+01,  9.24118953e+00,  6.44368521e+00,
             2.82238384e+00, -4.33434821e-01, -1.47839165e+00, -8.77479444e-01,
            -1.97086115e-01,  1.73176537e-01,  1.37808011e-01,  8.67657705e+00,
             6.75387489e+00,  7.60301039e+00,  9.20513005e+00,  1.06504851e+01,
             1.15676943e+01,  1.02832864e+01,  7.33996142e+00,  3.10138501e+00,
            -3.88459349e-01, -1.76742966e+00, -9.83316404e-01, -2.00998444e-01,
             2.78854232e-01,  1.11515713e-01,  1.88667072e+01,  1.39145234e+01,
             1.67796475e+01,  1.87505778e+01,  2.36452652e+01,  2.33948787e+01,
             2.32702741e+01,  1.42740260e+01,  8.54586456e+00, -2.06354050e+00,
            -4.46428476e+00, -3.20549237e+00,  1.68637698e+00,  4.79044256e-01,
            -1.66327877e-01,  3.81660000e-02,  4.92130408e-02,  1.14884000e+02,
             3.38878000e+01,  1.23730000e+01,  4.99925000e+00,  2.07043000e+00,
             8.28183000e-01,  3.07547000e-01,  3.77639570e+01,  3.22529469e+01,
             2.12931119e+01,  1.05466665e+01,  3.37921324e+00,  6.91908027e-01,
             8.04428567e-02, -5.29878506e+01, -4.52935072e+01, -3.07251158e+01,
            -1.53848438e+01, -3.82363621e+00,  1.26283043e-01,  2.40502346e-01,
             7.11058250e+01,  6.13713699e+01,  4.34326050e+01,  2.11220904e+01,
             1.32102889e+00, -1.70340908e+00, -1.69230443e-02,  9.94550000e-02,
             4.59595718e-02,  3.22430000e+00,  2.74783157e+01,  7.75800000e-01,
             1.11415947e+00,  2.05150000e+00,  9.48671353e+00,  3.38700000e+01,
             5.09500000e+00,  1.15900000e+00,  9.05626514e-01,  1.63118079e+00,
             2.40483635e+00,  3.25800000e-01,  1.08950276e+00,  1.02700000e-01,
             4.58345379e-01,  1.40700000e+00,  4.47045795e+00,  3.88000000e-01,
             8.93354953e-01,  1.05700000e+00,  2.87515071e+00]),
     '_ecpbas': array([], shape=(0, 8), dtype=float64),
     'stdout': <ipykernel.iostream.OutStream at 0x7fb409de9908>,
     'groupname': 'C1',
     'topgroup': 'C1',
     'symm_orb': None,
     'irrep_id': None,
     'irrep_name': None,
     '_symm_orig': None,
     '_symm_axes': None,
     '_nelectron': None,
     '_nao': None,
     '_enuc': None,
     '_atom': [('Fe', [0.0, 0.0, 0.0]),
      ('C', [-1.3483195898771716, -1.8558036509029943, -3.1142686532832218]),
      ('C', [1.3483195898771716, -1.8558036509029943, -3.1142686532832218]),
      ('C', [2.181626449848253, 0.7088532768594759, -3.1142686532832218]),
      ('C', [0.0, 2.2938988583609126, -3.1142686532832218]),
      ('C', [-2.181626449848253, 0.7088532768594759, -3.1142686532832218]),
      ('H', [-2.5467725597195865, -3.505332356952965, -3.095764455071481]),
      ('H', [2.5467725597195865, -3.505332356952965, -3.095764455071481]),
      ('H', [4.120765133118442, 1.3389182024074604, -3.095764455071481]),
      ('H', [0.0, 4.332830198817134, -3.095764455071481]),
      ('H', [-4.120765133118442, 1.3389182024074604, -3.095764455071481]),
      ('C', [-1.3483195898771716, -1.8558036509029943, 3.1142686532832218]),
      ('C', [-2.181626449848253, 0.7088532768594759, 3.1142686532832218]),
      ('C', [0.0, 2.2938988583609126, 3.1142686532832218]),
      ('C', [2.181626449848253, 0.7088532768594759, 3.1142686532832218]),
      ('C', [1.3483195898771716, -1.8558036509029943, 3.1142686532832218]),
      ('H', [-2.5467725597195865, -3.505332356952965, 3.095764455071481]),
      ('H', [-4.120765133118442, 1.3389182024074604, 3.095764455071481]),
      ('H', [0.0, 4.332830198817134, 3.095764455071481]),
      ('H', [4.120765133118442, 1.3389182024074604, 3.095764455071481]),
      ('H', [2.5467725597195865, -3.505332356952965, 3.095764455071481])],
     '_basis': {'C': [[0,
        [8236.0, 0.0006772, -0.0001445],
        [1235.0, 0.0042785, -0.0009156],
        [280.8, 0.0213576, -0.0046031],
        [79.27, 0.0821858, -0.0182284],
        [25.59, 0.2350715, -0.055869],
        [8.997, 0.4342613, -0.1269889],
        [3.319, 0.3457333, -0.170105],
        [0.3643, -0.0089547, 0.598676]],
       [0, [0.9059, 1.0]],
       [0, [0.1285, 1.0]],
       [1, [18.71, 0.0140738], [4.133, 0.0869016], [1.2, 0.2902016]],
       [1, [0.3827, 1.0]],
       [1, [0.1209, 1.0]],
       [2, [1.097, 1.0]],
       [2, [0.318, 1.0]],
       [3, [0.761, 1.0]]],
      'Fe': [[0,
        [4316265.0, 0.00014, -7.2e-05, 1.7e-05, -4e-06, -7e-06, -1.2e-05],
        [646342.4, 0.000405, -0.000209, 4.9e-05, -1.1e-05, -2.1e-05, -3.6e-05],
        [147089.7, 0.001119, -0.000579, 0.000135, -2.9e-05, -5.8e-05, -9.9e-05],
        [41661.52, 0.002907, -0.001506, 0.000352, -7.7e-05, -0.000155, -0.000263],
        [13590.77, 0.007571, -0.003939, 0.000923, -0.000201, -0.000393, -0.000664],
        [4905.75, 0.019818, -0.010396, 0.002452, -0.000535, -0.001101, -0.001869],
        [1912.746, 0.050734, -0.027074, 0.006451, -0.001408, -0.002693, -0.004542],
        [792.6043, 0.118729, -0.065777, 0.016106, -0.003518, -0.007404, -0.012601],
        [344.8065, 0.231164, -0.139082, 0.035742, -0.007814, -0.014484, -0.024423],
        [155.8999, 0.319322, -0.23015, 0.065528, -0.014372, -0.031853, -0.054652],
        [72.23091, 0.233648, -0.229663, 0.07443, -0.016383, -0.025352, -0.042541],
        [32.72506, 0.074022, 0.046091, -0.025711, 0.005643, -0.007887, -0.015989],
        [15.66762, 0.090952, 0.515051, -0.308645, 0.071221, 0.19147, 0.345964],
        [7.503483, 0.088898, 0.487175, -0.446544, 0.1078, 0.148242, 0.320641],
        [3.312223, 0.014302, 0.08438, 0.148985, -0.044262, 0.050761, -0.202125],
        [1.558471,
         -0.000387,
         -0.005911,
         0.720395,
         -0.225999,
         -1.012246,
         -2.160673],
        [0.683914, 8e-06, -4.4e-05, 0.389698, -0.237628, 0.342339, 2.627486],
        [0.146757, -2.5e-05, -0.000487, 0.019184, 0.29778, 1.857266, -0.475452],
        [0.070583, 3.2e-05, 0.000437, -0.007023, 0.565497, -1.063679, -1.566613]],
       [0, [0.031449, 1.0]],
       [1,
        [17745.69, 0.000123, -4.3e-05, 9e-06, 1.4e-05, 3e-05],
        [4200.721, 0.000566, -0.0002, 4.4e-05, 6.6e-05, 0.000134],
        [1364.429, 0.002608, -0.000923, 0.000201, 0.000303, 0.000659],
        [522.0806, 0.010295, -0.003668, 0.0008, 0.001219, 0.002447],
        [221.4595, 0.034751, -0.012539, 0.002738, 0.00412, 0.009014],
        [100.9096, 0.09669, -0.035848, 0.007848, 0.011953, 0.023823],
        [48.40115, 0.21003, -0.080822, 0.017739, 0.02662, 0.059364],
        [23.98536, 0.332457, -0.134697, 0.029749, 0.045699, 0.08758],
        [12.1825, 0.330771, -0.136912, 0.030389, 0.045033, 0.122286],
        [6.242298, 0.154733, 0.033713, -0.010765, -0.013011, -0.068112],
        [3.110944, 0.020964, 0.33567, -0.087689, -0.141375, -0.351907],
        [1.509958, -0.002346, 0.455496, -0.12847, -0.194148, -0.623706],
        [0.710845, -0.001854, 0.28176, -0.073996, -0.10177, 0.841448],
        [0.272598, -0.000317, 0.04515, 0.215455, 0.467864, 0.79207],
        [0.103972, 3e-05, -0.003165, 0.572005, 0.624218, -0.91751]],
       [1, [0.038166, 1.0]],
       [2,
        [114.884, 0.003532, -0.003896, 0.005703],
        [33.8878, 0.02555, -0.028207, 0.041691],
        [12.373, 0.098357, -0.111573, 0.172043],
        [4.99925, 0.237919, -0.272839, 0.408607],
        [2.07043, 0.356539, -0.317152, 0.119525],
        [0.828183, 0.362848, 0.052062, -0.766038],
        [0.307547, 0.238803, 0.561269, -0.043081]],
       [2, [0.099455, 1.0]],
       [3, [3.2243, 1.0]],
       [3, [0.7758, 1.0]],
       [4, [2.0515, 1.0]]],
      'H': [[0, [33.87, 0.0060773], [5.095, 0.0453176], [1.159, 0.2028364]],
       [0, [0.3258, 1.0]],
       [0, [0.1027, 1.0]],
       [1, [1.407, 1.0]],
       [1, [0.388, 1.0]],
       [2, [1.057, 1.0]]]},
     '_ecp': {},
     '_built': True,
     '_pseudo': {},
     '_keys': {'_atm',
      '_atom',
      '_bas',
      '_basis',
      '_built',
      '_ecp',
      '_ecpbas',
      '_enuc',
      '_env',
      '_nao',
      '_nelectron',
      '_pseudo',
      '_symm_axes',
      '_symm_orig',
      'atom',
      'basis',
      'cart',
      'charge',
      'ecp',
      'groupname',
      'incore_anyway',
      'irrep_id',
      'irrep_name',
      'max_memory',
      'nucmod',
      'nucprop',
      'output',
      'spin',
      'stdout',
      'symm_orb',
      'symmetry',
      'symmetry_subgroup',
      'topgroup',
      'unit',
      'verbose'}}

```python
mf = scf.ROHF(mol)

```

```python
mf.kernel()
```

```python
from pyscf.mcscf import avas
# See also 43-dmet_cas.py and function gto.mole.search_ao_label for the rules
# of "ao_labels" in the following
ao_labels = ['Fe 3d', 'C 2pz']
norb, ne_act, orbs = avas.avas(mf, ao_labels, canonicalize=False)
```


## MTH 9842
## HW2

### Group L:  Tiangang Zhang, Yang Li, Zhirong Zhang, Jimmy Jusuf

### Problem 1###
\begin{eqnarray*}
L(x,y,\lambda)=(x-a)^2+(y-b)^2-\lambda_1 x+\lambda_2 (x-1)-\lambda_3 y +\lambda_4 (y-1)
\end{eqnarray*}
Then local minimizer should subject to

\begin{equation}
\left\{
             \begin{array}{ll}
             2(x^*-a)-\lambda_1^*+\lambda_2^*=0\\
             2(y^*-a)-\lambda_3^*+\lambda_4^*=0\\
             \lambda_1^* x^*=0\\
             \lambda_2^*(x^*-1)=0\\
             \lambda_3^* y^*=0\\
             \lambda_4^*(y^*-1)=0\\
             \lambda_i^* \geq 0 & \text{for } i=1,2,3,4
             \end{array}
\right.
\end{equation}

Solve the equations above, the solution is
\begin{equation}
x^*=
\left\{
             \begin{array}{ll}
             0 & a\leq 0\\
             a & a \in (0,1) \\
             1 & a \geq 1
             \end{array}
\right.
\end{equation}
\begin{equation}
y^*=
\left\{
             \begin{array}{ll}
             0 & b\leq 0\\
             b & b \in (0,1) \\
             1 & b \geq 1
             \end{array}
\right.
\end{equation}

### Problem 2###
We present two solutions below, with slightly different approach.

#### Solution 1
We replace constraints of the form
\begin{equation} |x_i| \leq b_i \end{equation}
with
\begin{equation}
\begin{split}
	x_i \leq b_i \\
	-x_i \leq b_i
\end{split}
\end{equation}

To deal with the absolute value in the objective function, we introduce a new variable U, s.t
\begin{equation}
\begin{split}
	x_2-10 \leq U \\
	10-x_2 \leq U
\end{split}
\end{equation}

Note that $U \geq |x_2-10|$ always holds. As $U$ has no other constrains, when we minimize $U$, $U=|x_2-10|$ always holds.

Thus, by change of variables and substitutions above, the nonlinear problem can be rewritten as LP problem
\begin{equation}
\min \, 2x_1+3U, \text{ subject to  }
\left\{
    \begin{array}{l}
    x_1 + 2 +x_2-10 \leq 5 \\
    -x_1 - 2 +x_2-10 \leq 5 \\
    x_1 + 2 +10-x_2  \leq 5 \\
    -x_1 - 2 +10-x_2  \leq 5 \\
    x_2-10 \leq U \\
	10-x_2 \leq U \\
    \end{array}
\right.
\end{equation}

### Problem 2###
#### Solution 2
Let $x_2-10=x^+-x^-,\, x^+,x^-\geq 0$, use the property of absolute value inequalities, the problem become
\begin{equation}
\min \, 2x_1+3|x^+-x^-|, \text{ subject to}
\left\{
             \begin{array}{ll}
             x_1+2+10+x^+-x^-\leq 5\\
             -x_1-2+10+x^+-x^-\leq 5\\
             x_1+2-10-x^++x^-\leq 5\\
             -x_1-2-10-x^++x^-\leq 5\\
             x^+,x^-\geq 0
             \end{array}
\right.
\end{equation}

Notice that
\begin{equation}
2x_1+3(x^++x^-) \geq 2x_1+3|x^+-x^-|
\end{equation}
now we consider
\begin{equation}
\min \,2x_1+3(x^++x^-) , \text{ subject to}
\left\{
             \begin{array}{ll}
             x_1+2+10+x^+-x^-\leq 5\\
             -x_1-2+10+x^+-x^-\leq 5\\
             x_1+2-10-x^++x^-\leq 5\\
             -x_1-2-10-x^++x^-\leq 5\\
             x^+,x^-\geq 0
             \end{array}
\right.
\end{equation}
Let $x_1^*,x^{+*},x^{-*}$ be the minimizer of the problem above, the next step is to prove that  $x_1^*,x^{+*},x^{-*}$ is the minimizer of the original problem, we prove by contradiction.
If there is $x_1',x_2'$ subject to the conditions and
\begin{equation}
2x_1'^*+3|x_2'-10| < 2x_1^*+3(x^{+*}+x^{-*})
\end{equation}
Let
\begin{eqnarray*}
x_{1\star}=x_1'\\
x^{+}_\star=\{x_2'-10\}^+\\
x^{^-}_\star=\{-x_2'+10\}^+
\end{eqnarray*}
Then
\begin{equation}
2x_{1\star}+3(x^{+}_\star+x^{^-}_\star) < 2x_1^*+3(x^{+*}+x^{-*})
\end{equation}
Contradiction!

Recall equation (5) we know that
\begin{equation}
2x_1'^*+3|x_2'-10| = 2x_1^*+3(x^{+*}+x^{-*})
\end{equation}
So we can always use the minimizer of problem (6) to get the minimizer and minimum value of the original problem. Then problem has been transferred into a LP
\begin{equation}
\min \,2x_1+3(x^++x^-) , \text{ subject to}
\left\{
             \begin{array}{ll}
             x_1+2+10+x^+-x^-\leq 5\\
             -x_1-2+10+x^+-x^-\leq 5\\
             x_1+2-10-x^++x^-\leq 5\\
             -x_1-2-10-x^++x^-\leq 5\\
             x^+,x^-\geq 0
             \end{array}
\right.
\end{equation}

### Problem 3###

There are $N$ currencies, index $i=1,\dots,N$.

We start with $B$ units of currency $1$ and we want to maximize the number
of units of currency $N$ through a sequence of trades. One unit of
currency $i$ can be exchanged for $f_{ij}$ units of currency $j$.

Decision variables: let $x_{ij} =$ amount of currency $i$ to be converted
%into currency $j$. According to no-arbitrage condition, there is no need to trade a currency back to
%the currency it traded from. The trade from one currency to another currency happens at most for one time. So we only need to know how much a currency is traded for another for one time.
into currency $j$.

The no-arbitrage condition
$f_{i_1 i_2}\,f_{i_2 i_3}\dots f_{i_{k-1} i_k}\,f_{i_k i_1}\leq 1 $ means
that if we start with any currency, continually exchange one currency into another
currency, and eventually back into the original currency, we can never end up
with more units of the original currency, i.e. if we start with 1 unit, at
most we get back 1 unit, or could be less than 1, after exchanging into a series of
other currencies. It also implies there can be no trading 'loops' or trading
sequences in which one can increase currency count beyond its initial allocation
in this economy.
The trade from one currency to another currency happens at most for one time.

Clearly $\sum_{j\not= 1}x_{1j}\leq B$. We also have
constraint $\sum_{j\not= 1}x_{1j}\leq u_1$, since we exchange out of
currency 1 exactly once into currency $j$ ($j \not= 1,N$) and never trade it back to currency 1,
where $u_i$ is the limit on the total amount of currency $i$ that can be
traded. If we exchange out of currency 1 into currency $N$ through
intermediate currency $i$, considering currency  the tradings from other currency to currency $i$, the trading limit is
%$(\sum_{j \not= 1}x_{ij} + \sum_{k \not= N}x_{ki}f_{ki}) \leq u_i$, for $i \not= 1,N$. The amount of buying currency $i$ should no less than sell it, so we have $\sum_{j\not= 1, i}x_{ij}\leq \sum_{k\not=i,N}f_{ki} x_{ki}$.
%
%Objective function: maximize $\sum_{i \not= N} f_{iN} * x_{iN}$, essential
%maximizing the total inflow into currency $N$ from all other currencies.
%There is no term $x_{i1}$ nor $x_{Ni}$ for $i=1,\dots,N$ in our solution because they are definitely 0 and we have no need to include them.(Any such positive value will definitely waste trading limit as well as reduce total value of our asset).
%
%Note that, let $x_{ij}^* $ and $x_{ji}^*$ be the solution(minimizer), then
%$x_{ij}^**x_{ji}^*= 0$ for $i,j \not=1,\dots,N$ because other wise we will trade currency $i$ to $j$ and then $j$ back to $i$. That will just waste trading limit as well as reduce total value because of no arbitrage condition. A solutio $x_{ij}^**x_{ji}^*= 0$ can definitely lead to a greater object value. So we do not need any constraint to prevent 'loops'.
%
$(\sum_{j \not= 1}x_{ij} + \sum_{k \not= N}x_{ki}f_{ki}) \leq u_i$, for $i \not= 1,N$. The amount of buying currency $i$ should no less than selling it, so we have $\sum_{j\not= 1, i}x_{ij}\leq \sum_{k\not=i,N}f_{ki} x_{ki}$.

Objective function: maximize $\sum_{i \not= N} f_{iN} * x_{iN}$, essential
maximizing the total inflow into currency $N$ from all other currencies.
There is no term $x_{i1}$ nor $x_{Ni}$ for $i=1,\dots,N$ in our solution because they are definitely 0 and we have no need to include them. Any such positive value will definitely waste trading limit as well as reduce total value of our asset.

In summary, the LP formulation of this problem is

\begin{equation}
\max \,\sum_{i \not= N} f_{iN} * x_{iN}, \text{ subject to}
\left\{
             \begin{array}{ll}
             \sum_{j\not= 1}x_{1j}\leq B,\\
             \sum_{j\not= 1}x_{1j}\leq u_1,\\
             \sum_{j\not= 1, i}x_{ij}\leq \sum_{k\not=i,N}f_{ki} x_{ki},& \text{for } i\not= 1,N\\
%%             \sum_{j \not= 1}x_{ij} + \sum_{k \not= N}x_{ki}f_{ki} \leq u_i &for i \not= 1,N\\
             \sum_{j \not= 1}x_{ij} + \sum_{k \not= N}x_{ki}f_{ki} \leq u_i, &\text{for } i \not= 1,N\\
             x_{ij}\geq 0, & \text{for } i\not= j,i\not=N
             \end{array}
\right.
\end{equation}

```python

```


```python
import numpy as np
import scipy as sp
import scipy.linalg
import sympy as sy
sy.init_printing()
```

```python
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
```

#  LU Factorization

LU factorization arises due its computational efficiency, it mainly facilitates solving the system of linear equations, though the flops (number of floating operations) of LU is still higher than Guassian-Jordon. Nonetheless LU factorization is particularly handy if you are computing multiple solutions of $A x =b$.

For instance, if you have a set of $\{b_i,\ i \in \mathbb Z\}$ to substitute in the system, such that
$$
Ax=b_1,\quad Ax=b_2,\quad Ax=b_3,\quad Ax=b_4, \quad...
$$
we only decompose $A$ once, but Guassian-Jordon algorithm will have to re-do operations with every $b_i$.

##  LU Algorithm

We aim to decompose a matrix $A$ into $L$ and $U$, which represent _lower_ and _upper triangular matrix_ respectively. And $L$ must have $1$'s on its principal diagonal.
$$
A = LU
$$
For instance,
$$
A=\underbrace{\left[\begin{array}{cccc}
1 & 0 & 0 & 0 \\
* & 1 & 0 & 0 \\
* & * & 1 & 0 \\
* & * & * & 1
\end{array}\right]}_{L}\underbrace{\left[\begin{array}{ccccc}
\blacksquare & * & * & * & * \\
0 & \blacksquare & * & * & * \\
0 & 0 & 0 & \blacksquare & * \\
0 & 0 & 0 & 0 & 0
\end{array}\right]}_{U}
$$

The plausibility of decomposition hinges on if $A$ can be converted into a upper triangular matrix after a series of row operations, i.e.

$$E_p...E_2E_1  A = U$$

Then

$$A = (E_p...E_2E_1)^{-1}U = LU$$

where

$$L = (E_p...E_2E_1)^{-1}$$

We will hand calculate an example here:

$$
A =
\begin{bmatrix}
9 & 3 & 6\\3 & 4 & 6\\0 & 8 & 8\\
\end{bmatrix}
$$

$$
\underbrace{
\begin{bmatrix}
1 & 0 & 0\\-\frac{1}{3} & 1 & 0\\0 & 0 & 1\\
\end{bmatrix}}_{E_1}
\underbrace{
\begin{bmatrix}
9 & 3 & 6\\3 & 4 & 6\\0 & 8 & 8\\
\end{bmatrix}}_{A}
=
\underbrace{
\begin{bmatrix}
9 & 3 & 6\\0 & 3 & 4\\0 & 8 & 8\\
\end{bmatrix}}_{E_1A}
$$

$$
\underbrace{
\begin{bmatrix}
1 & 0 & 0\\0 &1  & 0\\0 & -\frac{8}{3} & 1\\
\end{bmatrix}}_{E_2}
\underbrace{
\begin{bmatrix}
9 & 3 & 6\\0 & 3 & 4\\0 & 8 & 8\\
\end{bmatrix}}_{E_1A}
=
\underbrace{
\begin{bmatrix}
9 & 3 & 6\\0 & 3 & 4\\0 & 0 & -\frac{8}{3}\\
\end{bmatrix}}_{E_2E_1A=U}
$$

$$
L^{-1} = E_2E_1 =
\underbrace{
\begin{bmatrix}
1 & 0 & 0\\0 &1  & 0\\0 & -\frac{8}{3} & 1\\
\end{bmatrix}}_{E_2}
\underbrace{
\begin{bmatrix}
1 & 0 & 0\\-\frac{1}{3} & 1 & 0\\0 & 0 & 1\\
\end{bmatrix}}_{E_1}
=
\begin{bmatrix}
1 & 0 & 0\\-\frac{1}{3} & 1 & 0\\\frac{8}{9} & -\frac{8}{3} & 1\\
\end{bmatrix}
$$

Or we can compute $E_1^{-1}$ and $E_2^{-1}$ directly, because
$$
L = E_1^{-1}E_2^{-1}
$$

Construct augmented matrices for $E_2$ and $E_1$
$$
[E_1| I]=\left[\begin{array}{ccc|ccc}
1 & 0 & 0 & 1 & 0 & 0\\
-\frac{1}{3} & 1 & 0 & 0  & 1 & 0\\
0 & 0 & 1 & 0 & 0 & 1
\end{array}\right]
\sim
\left[\begin{array}{ccc|ccc}
1 &0 &0 &1 & 0 & 0\\
0& 1& 0& \frac{1}{3} & 1 & 0\\
0 & 0 & 1 &0 & 0 & 1
\end{array}\right]
=[I|E_1^{-1}]
$$

$$
[E_2| I]=
\left[\begin{array}{ccc|ccc}
1 & 0 & 0 & 1 & 0 & 0\\
0 & 1 & 0 & 0  & 1 & 0\\
0 & -\frac{8}{3} & 1 & 0 & 0 & 1\\
\end{array}
\right]
\sim
\left[\begin{array}{ccc|ccc}
1 & 0 & 0 & 1 & 0 & 0\\
0 & 1 & 0 & 0  & 1 & 0\\
0 & 0 & 1 & 0 &\frac{8}{3}& 1\\
\end{array}
\right]
=[I|E_2^{-1}]
$$

And we get the inverse of $E_1$ and $E_2$:
$$
E_1^{-1} = \left[\begin{array}{ccc|ccc} 1& 0& 0 \\ \frac{1}{3}& 1& 0\\ 0& 0 &1  \end{array}\right]\\
E_2^{-1} = \left[\begin{array}{ccc|ccc} 1& 0& 0 \\ 1& 1& 0\\ 0& \frac{8}{3} &1  \end{array}\right]
$$

$$
L = E_1^{-1}E_2^{-1}=
\left[\begin{array}{ccc|ccc} 1& 0& 0 \\ \frac{1}{3}& 1& 0\\ 0& 0 &1  \end{array}\right]
\left[\begin{array}{ccc|ccc} 1& 0& 0 \\ 1& 1& 0\\ 0& \frac{8}{3} &1 \end{array}\right]
=
\left[\begin{array}{ccc|ccc} 1& 0& 0 \\ \frac{4}{3}&1& 0\\ 0& \frac{8}{3} &1 \end{array}\right]
$$

The final result of LU decomposition:
$$
A = LU =
\underbrace{
\left[\begin{array}{ccc|ccc} 1& 0& 0 \\ \frac{4}{3}&1& 0\\ 0& \frac{8}{3} &1 \end{array}\right]}_{L}
\underbrace{
\begin{bmatrix}
9 & 3 & 6\\0 & 3 & 4\\0 & 0 & -\frac{8}{3}\\
\end{bmatrix}}_{E_2E_1A=U}
$$

We can take a look at SciPy results.

```python
A = np.array([[9, 3, 6], [3, 4, 6], [0, 8, 8]]); A
```

    array([[9, 3, 6],
           [3, 4, 6],
           [0, 8, 8]])

```python
P, L, U = sp.linalg.lu(A)
P
L
U
```

    array([[1., 0., 0.],
           [0., 0., 1.],
           [0., 1., 0.]])

    array([[1.        , 0.        , 0.        ],
           [0.        , 1.        , 0.        ],
           [0.33333333, 0.375     , 1.        ]])

    array([[9., 3., 6.],
           [0., 8., 8.],
           [0., 0., 1.]])

```python
P@L@U # this is A
```

    array([[9., 3., 6.],
           [3., 4., 6.],
           [0., 8., 8.]])

It is easy to notice the SciPy ```lu``` function give us more than $L$ and $U$, but also $P$ which is a **permutation matrix**. Theoretically, we don't need row switches to convert $A$ into $U$, but in some situations we must make row switches beforehand, otherwise decomposition will fail to materialize.

Thus Scipy uses $PLU$ decomposition to make the procedure always possible
$$
A  = PLU
$$

Actually $P = P^{-1}$, why? It's easier to analyze in augmented matrix expression, the inverse of row-switched elementary matrices are themselves.

$$
[P| I]=\left[\begin{array}{ccc|ccc}
1 & 0 & 0 & 1 & 0 & 0\\
0 & 0 & 1 & 0 & 1 & 0\\
0 & 1 & 0 & 0 & 0 & 1
\end{array}\right]
\sim
\left[\begin{array}{ccc|ccc}
1 & 0 & 0 & 1 & 0 & 0\\
0 & 1 & 0 & 0 & 0 & 1\\
0 & 0 & 1 & 0 & 1 & 0
\end{array}\right]=[I| P^{-1}]  =[P^{-1}|I]
$$

With these knowledge, what we are decomposing is actucally

$$
PA = LU
$$

$$
\begin{align}
E_2E_1E_0A &=
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 1 & 0\\0 & -\frac{3}{8} & 1\\
\end{bmatrix}}_{E_2}
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 1 & 0\\-\frac{1}{3} & 0 & 1\\
\end{bmatrix}}_{E_1}
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 0 & 1\\0 & 1 & 0\\
\end{bmatrix}}_{E_0}
\begin{bmatrix}
9 & 3 & 6\\3 & 4 & 6\\0 & 8 & 8\\
\end{bmatrix}\\
E_2E_1E_0A &=
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 1 & 0\\0 & -\frac{3}{8} & 1\\
\end{bmatrix}}_{E_2}
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 1 & 0\\-\frac{1}{3} & 0 & 1\\
\end{bmatrix}}_{E_1}
\underbrace{
\begin{bmatrix}
9& 3& 6\\0&8 &8\\ 3& 4& 6
\end{bmatrix}}_{E_0A}\\
E_2E_1E_0A &=
\underbrace{
\begin{bmatrix}
1 & 0& 0\\0 & 1 & 0\\0 & -\frac{3}{8} & 1\\
\end{bmatrix}}_{E_2}
\underbrace{
\begin{bmatrix}
9 &3 &6\\0 &8& 8 \\0& 3& 4
\end{bmatrix}}_{E_1E_0A}\\
E_2E_1E_0A &=
\underbrace{
\begin{bmatrix}
9 &3 &6\\0 &8& 8 \\0& 0& -1
\end{bmatrix}}_{E_2E_1E_0A}=U
\end{align}
$$
Rearrange that we can see $PL$
$$
A = \underbrace{E_0^{-1}}_{P} \underbrace{(E_1^{-1}E_2^{-1})}_{L}U
$$

#  Solving Linear System by Using LU Factorization

Solve the linear system：
$$
\begin{align}
3x_1-7x_2 -2x_3+2x_4&=-9\\
-3x_1+5x_2 +x_3 &=5\\
6x_1-4x_2 -5x_4&=7\\
-9x_1+5x_2 -5x_3+12x_4&=11\\
\end{align}
$$
In matrix form:
$$
\underbrace{\left[\begin{array}{rrrr}
3 & -7 & -2 & 2 \\
-3 & 5 & 1 & 0 \\
6 & -4 & 0 & -5 \\
-9 & 5 & -5 & 12
\end{array}\right]}_{A}
\left[\begin{array}{r}
x_1 \\
x_2 \\
x_3 \\
x_4
\end{array}\right]
=
\underbrace{\left[\begin{array}{r}
-9 \\
5 \\
7 \\
11
\end{array}\right]}_{b}
$$
Perform $LU$ decomposition:

$$\underbrace{\left[\begin{array}{rrrr}
3 & -7 & -2 & 2 \\
-3 & 5 & 1 & 0 \\
6 & -4 & 0 & -5 \\
-9 & 5 & -5 & 12
\end{array}\right]}_{A}
=\underbrace{
\left[\begin{array}{rrrr}
1 & 0 & 0 & 0 \\
-1 & 1 & 0 & 0 \\
2 & -5 & 1 & 0 \\
-3 & 8 & 3 & 1
\end{array}\right]}_{L}\underbrace{\left[\begin{array}{rrrr}
3 & -7 & -2 & 2 \\
0 & -2 & -1 & 2 \\
0 & 0 & -1 & 1 \\
0 & 0 & 0 & -1
\end{array}\right]}_{U}$$

Replace $A$ by $LU$, we get $L(Ux) = b$, now solve this pair of equations

$$
Ly = b\\
Ux = y
$$

Construct augmented matrix $[L|b]$

$$
\underbrace{
\left[\begin{array}{rrrr}
1 & 0 & 0 & 0 \\
-1 & 1 & 0 & 0 \\
2 & -5 & 1 & 0 \\
-3 & 8 & 3 & 1
\end{array}\right]}_{L}
\underbrace{\left[\begin{array}{r}
y_1 \\
y_2 \\
y_3 \\
y_4
\end{array}\right]}_{y}
=
\underbrace{\left[\begin{array}{r}
-9 \\
5 \\
7 \\
11
\end{array}\right]}_{b}
$$

$$
\left[\begin{array}{rrrr|r}
1 & 0 & 0 & 0 & -9 \\
-1 & 1 & 0 & 0 & 5\\
2 & -5 & 1 & 0 & 7\\
-3 & 8 & 3 & 1 & 11
\end{array}\right]\sim
\left[\begin{array}{rrrr|r}
1 & 0 & 0 & 0 & -9 \\
0 & 1 & 0 & 0 & -4\\
0 & 0 & 1 & 0 & 5\\
0 & 0 & 0 & 1 & 1
\end{array}\right]
$$

$$
\left[\begin{array}{r}
y_1 \\
y_2 \\
y_3 \\
y_4
\end{array}\right]=
\left[\begin{array}{r}
-9 \\
-4 \\
5 \\
1
\end{array}\right]
$$

Next we solve $Ux = y$, to show this in NumPy:

```python
U = np.array([[3, -7, -2, 2], [0, -2, -1, 2], [0, 0, -1, 1], [0, 0, 0,-1]])
y = np.array([-9, -4, 5, 1])
np.linalg.solve(U, y)
```

    array([ 3.,  4., -6., -1.])

If the process is correct, this is the solution of the system and we can verify results by invoking ```np.linalg.solve()```.

```python
A = np.array([[3, -7, -2, 2], [-3, 5, 1, 0], [6, -4, 0, -5], [-9, 5, -5, 12]])
b = np.array([-9, 5, 7, 11])
np.linalg.solve(A, b)
```

    array([ 3.,  4., -6., -1.])

The results are the same, $LU$ decomposition works!