|
| 1 | +import numpy as np |
| 2 | +from tensorcircuit import Circuit |
| 3 | + |
| 4 | +from tencirchem import UCC, HEA, set_backend |
| 5 | +from tencirchem.molecule import h4 |
| 6 | + |
| 7 | +K = set_backend("jax") |
| 8 | + |
| 9 | +ucc = UCC(h4) |
| 10 | +# reference energies |
| 11 | +ucc.print_energy() |
| 12 | + |
| 13 | + |
| 14 | +# symmetry preserving ansatz: npjqi 6:10, 2020 |
| 15 | +n_layers = 5 |
| 16 | +n_params = n_layers * (ucc.n_qubits - 2) |
| 17 | +def circuit(params): |
| 18 | + params = params.reshape(n_layers, ucc.n_qubits - 2) |
| 19 | + c = Circuit(ucc.n_qubits) |
| 20 | + # HF initial state |
| 21 | + for i in range(ucc.n_elec // 2): |
| 22 | + c.x(ucc.n_qubits - 1 - i) |
| 23 | + c.x(ucc.n_qubits // 2 - 1 - i) |
| 24 | + for l in range(n_layers): |
| 25 | + indices = list(range(0, ucc.n_qubits - 1, 2)) + list(range(1, ucc.n_qubits - 1, 2)) |
| 26 | + for i in indices: |
| 27 | + if i < ucc.n_qubits // 2 - 1: |
| 28 | + theta = params[l, i] |
| 29 | + elif i == ucc.n_qubits // 2 - 1: |
| 30 | + # preserve s_z |
| 31 | + theta = 0 |
| 32 | + else: |
| 33 | + theta = params[l, i-1] |
| 34 | + unitary = K.convert_to_tensor([[1, 0, 0, 0], |
| 35 | + [0, K.cos(theta), K.sin(theta), 0], |
| 36 | + [0, K.sin(theta), -K.cos(theta), 0], |
| 37 | + [0, 0, 0, 1]]) |
| 38 | + c.any(i, (i + 1), unitary=unitary) |
| 39 | + return c |
| 40 | + |
| 41 | + |
| 42 | +es = [] |
| 43 | +for i in range(10): |
| 44 | + init_guess = (np.random.rand(n_params) - 0.5) |
| 45 | + hea = HEA(ucc.h_qubit_op, circuit, init_guess, engine="tensornetwork") |
| 46 | + # default parameter shift doesn't work for this type of circuit |
| 47 | + hea.grad = "autodiff" |
| 48 | + e = hea.kernel() |
| 49 | + es.append(e) |
| 50 | +print(sorted(es)) |
0 commit comments