###### tags: `Quantum Computing`
# Hardware Efficient Ansatz
## Original
\begin{eqnarray}
\left|\Psi(\theta)\right> = \prod_{q=1}^{N} U^{q,d}(\vec \theta) \times U_{ent} \times \prod_{q=1}^{N} U^{q,d-1}(\vec \theta) \times \cdots \times U_{ent} \times\prod_{q=1}^{N} U^{q,0}(\vec \theta) \left|0\right>^{\otimes N}
\end{eqnarray}
where
* $N$ is number of qubits,
* $d$ is depth (strictly depth = $d+1$),
* $U_{ent}$ is entanglers that is generated by drift hamiltonian $H_0$, namely $U=e^{-iH_0t}$,
* $U^{q,i}$ represents the Euler rotation of q-th qubit, i-th depth position.
\begin{eqnarray}
U^{q,i}(\vec \theta) = \mathrm{CZ}^q(\theta_1^{q,i}) \mathrm{CZ}^q(\theta_2^{q,i}) \mathrm{CZ}^q(\theta_3^{q,i})
\end{eqnarray}
> Why do we call $H_0$ a drift hamiltonian?
The total number of parameters used here is
\begin{eqnarray}
3 \times N \times (d+1) = N(3d+3).
\end{eqnarray}
When the first parameters of Z rotations of 0th depth is used for initializing states, the number of parameters used are $N(3d-2)$
The hardware efficient quantum circuit is shown below.

## Alternative (By QuantuumNativeDojo)
## Coding Examples
### original
implemented by duckamo
```python=
def HE_Ansatz_Circuit(N,depth,theta_list):
"""
Hardware Efficient Ansatz Circuit
"""
circuit = QuantumCircuit(N)
for d in range(depth):
for i in range(N):
circuit.add_gate(
merge(
merge(RZ(i, theta_list[3*i+3*N*d]),RX(i, theta_list[3*i+1+3*N*d])),RZ(i, theta_list[3*i+2+2*N*d])
))
for i in range(N//2):
circuit.add_gate(CZ(2*i, 2*i+1))
for i in range(N//2-1):
circuit.add_gate(CZ(2*i+1, 2*i+2))
for i in range(N):
circuit.add_gate(merge(RX(i, theta_list[2*i+3*N*depth]), RZ(i, theta_list[2*i+1+3*N*depth])))
return circuit
```
### Alternative (By QuantuumNativeDojo)
```python=
def he_ansatz_circuit(n_qubit, depth, theta_list):
"""he_ansatz_circuit
Returns hardware efficient ansatz circuit.
Args:
n_qubit (:class:`int`):
the number of qubit used (equivalent to the number of fermionic modes)
depth (:class:`int`):
depth of the circuit.
theta_list (:class:`numpy.ndarray`):
rotation angles.
Returns:
:class:`qulacs.QuantumCircuit`
"""
circuit = QuantumCircuit(n_qubit)
for d in range(depth):
for i in range(n_qubit):
circuit.add_gate(merge(RY(i, theta_list[2*i+2*n_qubit*d]), RZ(i, theta_list[2*i+1+2*n_qubit*d])))
for i in range(n_qubit//2):
circuit.add_gate(CZ(2*i, 2*i+1))
for i in range(n_qubit//2-1):
circuit.add_gate(CZ(2*i+1, 2*i+2))
for i in range(n_qubit):
circuit.add_gate(merge(RY(i, theta_list[2*i+2*n_qubit*depth]), RZ(i, theta_list[2*i+1+2*n_qubit*depth])))
return circuit
```
## Refernces
[Hardware-efficient Variational Quantum Eigensolver for Small Molecules and Quantum Magnets](https://arxiv.org/abs/1704.05018)
[Qulacs を用いた variational quantum eigensolver (VQE) の実装](https://dojo.qulacs.org/ja/latest/notebooks/6.2_qulacs_VQE.html)
## See also
[Hardware Efficient Real Ansatz](https://hackmd.io/H_RuCcEuSbyiQe9N6zXv1A)