@@ -1896,6 +1896,348 @@ <h2 id="and-without-the-noise-model">And without the noise model </h2>
18961896</ div >
18971897</ section >
18981898
1899+ < section >
1900+ < h2 id ="hamiltonians-one-qubit-system "> Hamiltonians, one qubit system </ h2 >
1901+
1902+ < p > We start with a simple \( 2\times 2 \) Hamiltonian matrix expressed in
1903+ terms of Pauli \( X \) and \( Z \) matrices, as discussed in the project text as well.
1904+ </ p >
1905+
1906+ < p > We define a symmetric matrix \( H\in {\mathbb{R}}^{2\times 2} \)</ p >
1907+ < p > < br >
1908+ $$
1909+ H = \begin{bmatrix} H_{11} & H_{12} \\ H_{21} & H_{22}
1910+ \end{bmatrix},
1911+ $$
1912+ < p > < br >
1913+ </ section >
1914+
1915+ < section >
1916+ < h2 id ="rewriting-the-hamiltonian "> Rewriting the Hamiltonian </ h2 >
1917+
1918+ < p > We let \( H = H_0 + H_I \), where</ p >
1919+ < p > < br >
1920+ $$
1921+ H_0= \begin{bmatrix} E_1 & 0 \\ 0 & E_2\end{bmatrix},
1922+ $$
1923+ < p > < br >
1924+
1925+ < p > is a diagonal matrix. Similarly,</ p >
1926+ < p > < br >
1927+ $$
1928+ H_I= \begin{bmatrix} V_{11} & V_{12} \\ V_{21} & V_{22}\end{bmatrix},
1929+ $$
1930+ < p > < br >
1931+
1932+ < p > where \( V_{ij} \) represent various interaction matrix elements.
1933+ We can view \( H_0 \) as the non-interacting solution
1934+ </ p >
1935+ < p > < br >
1936+ $$
1937+ \begin{equation}
1938+ H_0\vert 0 \rangle =E_1\vert 0 \rangle,
1939+ \tag{2}
1940+ \end{equation}
1941+ $$
1942+ < p > < br >
1943+
1944+ < p > and</ p >
1945+ < p > < br >
1946+ $$
1947+ \begin{equation}
1948+ H_0\vert 1\rangle =E_2\vert 1\rangle,
1949+ \tag{3}
1950+ \end{equation}
1951+ $$
1952+ < p > < br >
1953+
1954+ < p > where we have defined the orthogonal computational one-qubit basis states \( \vert 0\rangle \) and \( \vert 1\rangle \).</ p >
1955+ </ section >
1956+
1957+ < section >
1958+ < h2 id ="using-pauli-matrices "> Using Pauli matrices </ h2 >
1959+
1960+ < p > We rewrite \( H \) (and \( H_0 \) and \( H_I \)) via Pauli matrices</ p >
1961+ < p > < br >
1962+ $$
1963+ H_0 = \mathcal{E} I + \Omega \sigma_z, \quad \mathcal{E} = \frac{E_1
1964+ + E_2}{2}, \; \Omega = \frac{E_1-E_2}{2},
1965+ $$
1966+ < p > < br >
1967+
1968+ < p > and</ p >
1969+ < p > < br >
1970+ $$
1971+ H_I = c \boldsymbol{I} +\omega_z\sigma_z + \omega_x\sigma_x,
1972+ $$
1973+ < p > < br >
1974+
1975+ < p > with \( c = (V_{11}+V_{22})/2 \), \( \omega_z = (V_{11}-V_{22})/2 \) and \( \omega_x = V_{12}=V_{21} \).
1976+ We let our Hamiltonian depend linearly on a strength parameter \( \lambda \)
1977+ </ p >
1978+
1979+ < p > < br >
1980+ $$
1981+ H=H_0+\lambda H_\mathrm{I},
1982+ $$
1983+ < p > < br >
1984+
1985+ < p > with \( \lambda \in [0,1] \), where the limits \( \lambda=0 \) and \( \lambda=1 \)
1986+ represent the non-interacting (or unperturbed) and fully interacting
1987+ system, respectively. The model is an eigenvalue problem with only
1988+ two available states.
1989+ </ p >
1990+ </ section >
1991+
1992+ < section >
1993+ < h2 id ="selecting-parameters "> Selecting parameters </ h2 >
1994+
1995+ < p > Here we set the parameters \( E_1=0 \),
1996+ \( E_2=4 \), \( V_{11}=-V_{22}=3 \) and \( V_{12}=V_{21}=0.2 \).
1997+ </ p >
1998+
1999+ < p > The non-interacting solutions represent our computational basis.
2000+ Pertinent to our choice of parameters, is that at \( \lambda\geq 2/3 \),
2001+ the lowest eigenstate is dominated by \( \vert 1\rangle \) while the upper
2002+ is \( \vert 0 \rangle \). At \( \lambda=1 \) the \( \vert 0 \rangle \) mixing of
2003+ the lowest eigenvalue is \( 1\% \) while for \( \lambda\leq 2/3 \) we have a
2004+ \( \vert 0 \rangle \) component of more than \( 90\% \). The character of the
2005+ eigenvectors has therefore been interchanged when passing \( z=2/3 \). The
2006+ value of the parameter \( V_{12} \) represents the strength of the coupling
2007+ between the two states.
2008+ </ p >
2009+ </ section >
2010+
2011+ < section >
2012+ < h2 id ="setting-up-the-matrix "> Setting up the matrix </ h2 >
2013+
2014+
2015+ <!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
2016+ < div class ="cell border-box-sizing code_cell rendered ">
2017+ < div class ="input ">
2018+ < div class ="inner_cell ">
2019+ < div class ="input_area ">
2020+ < div class ="highlight " style ="background: #eeeedd ">
2021+ < pre style ="font-size: 80%; line-height: 125%; "> < span style ="color: #8B008B; font-weight: bold "> from</ span > < span style ="color: #008b45; text-decoration: underline "> matplotlib</ span > < span style ="color: #8B008B; font-weight: bold "> import</ span > pyplot < span style ="color: #8B008B; font-weight: bold "> as</ span > plt
2022+ < span style ="color: #8B008B; font-weight: bold "> import</ span > < span style ="color: #008b45; text-decoration: underline "> numpy</ span > < span style ="color: #8B008B; font-weight: bold "> as</ span > < span style ="color: #008b45; text-decoration: underline "> np</ span >
2023+ dim = < span style ="color: #B452CD "> 2</ span >
2024+ Hamiltonian = np.zeros((dim,dim))
2025+ e0 = < span style ="color: #B452CD "> 0.0</ span >
2026+ e1 = < span style ="color: #B452CD "> 4.0</ span >
2027+ Xnondiag = < span style ="color: #B452CD "> 0.20</ span >
2028+ Xdiag = < span style ="color: #B452CD "> 3.0</ span >
2029+ Eigenvalue = np.zeros(dim)
2030+ < span style ="color: #228B22 "> # setting up the Hamiltonian</ span >
2031+ Hamiltonian[< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 0</ span > ] = Xdiag+e0
2032+ Hamiltonian[< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 1</ span > ] = Xnondiag
2033+ Hamiltonian[< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 0</ span > ] = Hamiltonian[< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 1</ span > ]
2034+ Hamiltonian[< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 1</ span > ] = e1-Xdiag
2035+ < span style ="color: #228B22 "> # diagonalize and obtain eigenvalues, not necessarily sorted</ span >
2036+ EigValues, EigVectors = np.linalg.eig(Hamiltonian)
2037+ permute = EigValues.argsort()
2038+ EigValues = EigValues[permute]
2039+ < span style ="color: #228B22 "> # print only the lowest eigenvalue</ span >
2040+ < span style ="color: #658b00 "> print</ span > (EigValues[< span style ="color: #B452CD "> 0</ span > ])
2041+ </ pre >
2042+ </ div >
2043+ </ div >
2044+ </ div >
2045+ </ div >
2046+ < div class ="output_wrapper ">
2047+ < div class ="output ">
2048+ < div class ="output_area ">
2049+ < div class ="output_subarea output_stream output_stdout output_text ">
2050+ </ div >
2051+ </ div >
2052+ </ div >
2053+ </ div >
2054+ </ div >
2055+
2056+ < p > Now rewrite it in terms of the identity matrix and the Pauli matrix X and Z</ p >
2057+
2058+
2059+ <!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
2060+ < div class ="cell border-box-sizing code_cell rendered ">
2061+ < div class ="input ">
2062+ < div class ="inner_cell ">
2063+ < div class ="input_area ">
2064+ < div class ="highlight " style ="background: #eeeedd ">
2065+ < pre style ="font-size: 80%; line-height: 125%; "> < span style ="color: #228B22 "> # Now rewrite it in terms of the identity matrix and the Pauli matrix X and Z</ span >
2066+ X = np.array([[< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 1</ span > ],[< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 0</ span > ]])
2067+ Y = np.array([[< span style ="color: #B452CD "> 0</ span > ,-< span style ="color: #B452CD "> 1</ span > j],[< span style ="color: #B452CD "> 1</ span > j,< span style ="color: #B452CD "> 0</ span > ]])
2068+ Z = np.array([[< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 0</ span > ],[< span style ="color: #B452CD "> 0</ span > ,-< span style ="color: #B452CD "> 1</ span > ]])
2069+ < span style ="color: #228B22 "> # identity matrix</ span >
2070+ I = np.array([[< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 0</ span > ],[< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 1</ span > ]])
2071+
2072+ epsilon = (e0+e1)*< span style ="color: #B452CD "> 0.5</ span > ; omega = (e0-e1)*< span style ="color: #B452CD "> 0.5</ span >
2073+ c = < span style ="color: #B452CD "> 0.0</ span > ; omega_z=Xdiag; omega_x = Xnondiag
2074+ Hamiltonian = (epsilon+c)*I+(omega_z+omega)*Z+omega_x*X
2075+ EigValues, EigVectors = np.linalg.eig(Hamiltonian)
2076+ permute = EigValues.argsort()
2077+ EigValues = EigValues[permute]
2078+ < span style ="color: #228B22 "> # print only the lowest eigenvalue</ span >
2079+ < span style ="color: #658b00 "> print</ span > (EigValues[< span style ="color: #B452CD "> 0</ span > ])
2080+ </ pre >
2081+ </ div >
2082+ </ div >
2083+ </ div >
2084+ </ div >
2085+ < div class ="output_wrapper ">
2086+ < div class ="output ">
2087+ < div class ="output_area ">
2088+ < div class ="output_subarea output_stream output_stdout output_text ">
2089+ </ div >
2090+ </ div >
2091+ </ div >
2092+ </ div >
2093+ </ div >
2094+ </ section >
2095+
2096+ < section >
2097+ < h2 id ="where-are-we-going "> Where are we going? </ h2 >
2098+
2099+ < p > For a one-qubit system we can reach every point on the Bloch sphere
2100+ (as discussed earlier) with a rotation about the \( x \)-axis and the
2101+ \( y \)-axis.
2102+ </ p >
2103+
2104+ < p > We can express this mathematically through the following operations (see whiteboard for the drawing), giving us a new state \( \vert \psi\rangle \)</ p >
2105+ < p > < br >
2106+ $$
2107+ \vert\psi\rangle = R_y(\phi)R_x(\theta)\vert 0 \rangle.
2108+ $$
2109+ < p > < br >
2110+ </ section >
2111+
2112+ < section >
2113+ < h2 id ="possible-ansatzes "> Possible ansatzes </ h2 >
2114+
2115+ < p > We can produce multiple ansatzes for the new state in terms of the
2116+ angles \( \theta \) and \( \phi \). With these ansatzes we can in turn
2117+ calculate the expectation value of the above Hamiltonian, now
2118+ rewritten in terms of various Pauli matrices (and thereby gates), that is compute
2119+ </ p >
2120+
2121+ < p > < br >
2122+ $$
2123+ \langle \psi \vert (c+\mathcal{E})\boldsymbol{I} + (\Omega+\omega_z)\boldsymbol{\sigma}_z + \omega_x\boldsymbol{\sigma}_x\vert \psi \rangle.
2124+ $$
2125+ < p > < br >
2126+
2127+ < p > We can now set up a series of ansatzes for \( \vert \psi \rangle \) as
2128+ function of the angles \( \theta \) and \( \phi \) and find thereafter the
2129+ variational minimum using for example a gradient descent method.
2130+ </ p >
2131+ </ section >
2132+
2133+ < section >
2134+ < h2 id ="more-on-rotation-operators "> More on rotation operators </ h2 >
2135+
2136+ < p > To do so, we need to remind ourselves about the mathematical expressions for
2137+ the rotational matrices/operators.
2138+ </ p >
2139+
2140+ < p > < br >
2141+ $$
2142+ R_x(\theta)=\cos{\frac{\theta}{2}}\boldsymbol{I}-\imath \sin{\frac{\theta}{2}}\boldsymbol{\sigma}_x,
2143+ $$
2144+ < p > < br >
2145+
2146+ < p > and</ p >
2147+
2148+ < p > < br >
2149+ $$
2150+ R_y(\phi)=\cos{\frac{\phi}{2}}\boldsymbol{I}-\imath \sin{\frac{\phi}{2}}\boldsymbol{\sigma}_y.
2151+ $$
2152+ < p > < br >
2153+ </ section >
2154+
2155+ < section >
2156+ < h2 id ="code-example "> Code example </ h2 >
2157+
2158+
2159+ <!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
2160+ < div class ="cell border-box-sizing code_cell rendered ">
2161+ < div class ="input ">
2162+ < div class ="inner_cell ">
2163+ < div class ="input_area ">
2164+ < div class ="highlight " style ="background: #eeeedd ">
2165+ < pre style ="font-size: 80%; line-height: 125%; "> < span style ="color: #228B22 "> # define the rotation matrices</ span >
2166+ < span style ="color: #228B22 "> # Define angles theta and phi</ span >
2167+ theta = < span style ="color: #B452CD "> 0.5</ span > *np.pi; phi = < span style ="color: #B452CD "> 0.2</ span > *np.pi
2168+ Rx = np.cos(theta*< span style ="color: #B452CD "> 0.5</ span > )*I-< span style ="color: #B452CD "> 1</ span > j*np.sin(theta*< span style ="color: #B452CD "> 0.5</ span > )*X
2169+ Ry = np.cos(phi*< span style ="color: #B452CD "> 0.5</ span > )*I-< span style ="color: #B452CD "> 1</ span > j*np.sin(phi*< span style ="color: #B452CD "> 0.5</ span > )*Y
2170+ < span style ="color: #228B22 "> #define basis states</ span >
2171+ basis0 = np.array([< span style ="color: #B452CD "> 1</ span > ,< span style ="color: #B452CD "> 0</ span > ])
2172+ basis1 = np.array([< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 1</ span > ])
2173+
2174+ NewBasis = Ry @ Rx @ basis0
2175+ < span style ="color: #658b00 "> print</ span > (NewBasis)
2176+ < span style ="color: #228B22 "> # Compute the expectation value</ span >
2177+ < span style ="color: #228B22 "> #Note hermitian conjugation</ span >
2178+ Energy = NewBasis.conj().T @ Hamiltonian @ NewBasis
2179+ < span style ="color: #658b00 "> print</ span > (Energy)
2180+ </ pre >
2181+ </ div >
2182+ </ div >
2183+ </ div >
2184+ </ div >
2185+ < div class ="output_wrapper ">
2186+ < div class ="output ">
2187+ < div class ="output_area ">
2188+ < div class ="output_subarea output_stream output_stdout output_text ">
2189+ </ div >
2190+ </ div >
2191+ </ div >
2192+ </ div >
2193+ </ div >
2194+
2195+ < p > Not an impressive results. We set up now a loop over many angles \( \theta \) and \( \phi \) and compute the energies</ p >
2196+
2197+ <!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
2198+ < div class ="cell border-box-sizing code_cell rendered ">
2199+ < div class ="input ">
2200+ < div class ="inner_cell ">
2201+ < div class ="input_area ">
2202+ < div class ="highlight " style ="background: #eeeedd ">
2203+ < pre style ="font-size: 80%; line-height: 125%; "> < span style ="color: #228B22 "> # define a number of angles</ span >
2204+ n = < span style ="color: #B452CD "> 20</ span >
2205+ angle = np.arange(< span style ="color: #B452CD "> 0</ span > ,< span style ="color: #B452CD "> 180</ span > ,< span style ="color: #B452CD "> 10</ span > )
2206+ n = np.size(angle)
2207+ ExpectationValues = np.zeros((n,n))
2208+ < span style ="color: #8B008B; font-weight: bold "> for</ span > i < span style ="color: #8B008B "> in</ span > < span style ="color: #658b00 "> range</ span > (n):
2209+ theta = np.pi*angle[i]/< span style ="color: #B452CD "> 180.0</ span >
2210+ Rx = np.cos(theta*< span style ="color: #B452CD "> 0.5</ span > )*I-< span style ="color: #B452CD "> 1</ span > j*np.sin(theta*< span style ="color: #B452CD "> 0.5</ span > )*X
2211+ < span style ="color: #8B008B; font-weight: bold "> for</ span > j < span style ="color: #8B008B "> in</ span > < span style ="color: #658b00 "> range</ span > (n):
2212+ phi = np.pi*angle[j]/< span style ="color: #B452CD "> 180.0</ span >
2213+ Ry = np.cos(phi*< span style ="color: #B452CD "> 0.5</ span > )*I-< span style ="color: #B452CD "> 1</ span > j*np.sin(phi*< span style ="color: #B452CD "> 0.5</ span > )*Y
2214+ NewBasis = Ry @ Rx @ basis0
2215+ Energy = NewBasis.conj().T @ Hamiltonian @ NewBasis
2216+ Edifference=< span style ="color: #658b00 "> abs</ span > (np.real(EigValues[< span style ="color: #B452CD "> 0</ span > ]-Energy))
2217+ ExpectationValues[i,j]=Edifference
2218+
2219+ < span style ="color: #658b00 "> print</ span > (np.min(ExpectationValues))
2220+ </ pre >
2221+ </ div >
2222+ </ div >
2223+ </ div >
2224+ </ div >
2225+ < div class ="output_wrapper ">
2226+ < div class ="output ">
2227+ < div class ="output_area ">
2228+ < div class ="output_subarea output_stream output_stdout output_text ">
2229+ </ div >
2230+ </ div >
2231+ </ div >
2232+ </ div >
2233+ </ div >
2234+
2235+ < p > Clearly, this is not the very best way of proceeding. Rather, here we
2236+ would compute the gradient and thereby find the minimum as function of
2237+ the angles \( \theta \) and \( \phi \). This will lead us to the so-called Variational Quantum Eigensolver to be discussed next week.
2238+ </ p >
2239+ </ section >
2240+
18992241
19002242
19012243</ div > <!-- class="slides" -->
0 commit comments