Skip to main content

Haiqu.mps_loading(mps, shape=‘plr’, num_layers=2, truncation_cutoff=1e-06, fine_tuning_iterations=20, max_time=900, name=None)

Generate a quantum circuit that prepares a quantum state from matrix product state (MPS). The MPS is normalized in the process, and expect physical index to be of size 2. Given a MPS, this method creates a Data Loading job that runs in the Haiqu cloud. The result of this job is a circuit which can be used to supply the state to a quantum algorithm for processing. Two MPS formats are supported:
  1. Standard form (only site tensors):
    │     │     │     │        │
    A₁ ── A₂ ── A₃ ── A₄ ─ ⋯ ─ Aₙ
    
  2. Vidal form (site and bond tensors):
    │           │           │              │
    Γ₁ ── Λ₁ ── Γ₂ ── Λ₂ ── Γ₃ ── Λ₃ ─ ⋯ ─ Γₙ
    
The complexity and quality of the generated circuit can be controlled by the num_layers, truncation_cutoff, and fine_tuning_iterations parameters. Passing the MPS with high bond dimension may degrade the quality and synthesis time.
  • Parameters:
    • mps (Sequence) — The MPS in either standard or Vidal form. Standard form expects a list of rank-3 site tensors (one per each qubit). Vidal form is a tuple of site and bond tensors, where bonds tensors are rank-1 or diagonal rank-2 tensors. The MPS type is determined automatically. Standard form includes left- and right-canonical forms, while Vidal form includes central canonical form.
    • shape (str) — shape of site tensors of the MPS. Site tensors are rank-3 tensors. Shape defines the order of axes in it. p - physical index, l - left index, r - right index. Defaults to “plr”, which is standard order in Qiskit.
    • num_layers (int) — The number of layers in the generated circuit. More layers can improve the quality of the output vector at the cost of a deeper circuit. Defaults to 2.
    • truncation_cutoff (Real) — The entanglement cutoff for later layers. Increasing this threshold may result in a smaller (but more approximate) circuit. Defaults to 1e-6.
    • fine_tuning_iterations (int) — The maximum number of fine-tuning iterations to perform after each layer is added. Increasing this limit may improve the quality of the circuit by using more classical resources. Defaults to 20.
    • max_time (int | float) — Soft time limit for the job (in seconds). The data loading job will first always produce the initial result and then limit the fine-tuning stage by the remaining time left. If time limit exceeds during the fine-tuning - the best current result will be returned. Defaults to 900 (15 min). Max allowed job time is 15 min. The job can take more wall clock time than user specified max_time due to latency, initialization overheads or if the initial result already takes more time.
    • name (str | None) — The name for the job and the produced circuit. If None (default), a name will be automatically generated.
  • Returns: The Data Loading job that will generate the circuit from the MPS.
  • Return type: DataLoadingJobModel

Examples

Loading Qiskit MPS:
>>> qc = qiskit.QuantumCircuit(2)
>>> qc.h(0)
>>> qc.cx(0, 1)  # prepare test Bell state
>>> qc.save_matrix_product_state(label="mps")
>>> mps = AerSimulator().run(qc).result().data(0)["mps"]  # get MPS from Aer Simulator
>>> job = haiqu.mps_loading(mps)
>>> mps_gate = job.result()
>>> print(f"MPS was loaded with fidelity {job.fidelity:.3f}")
MPS was loaded with fidelity 1.000
>>> mps_qc = qiskit.QuantumCircuit(2)
>>> mps_qc.compose(mps_gate, inplace=True)
>>> print(haiqu.statevector_run(mps_qc).result())  # confirm the Bell state was loaded
[array([0.70710678+0.j, 0.        +0.j, 0.        +0.j, 0.70710678+0.j])]
Preparing a ground state of a Hamiltonian:
>>> import quimb.tensor as qtn  # !pip install quimb (if not present)
>>> H = qtn.MPO_ham_heis(4, j=1.0, cyclic=False)  # Heisenberg hamiltonian
>>> dmrg = qtn.DMRG2(H, bond_dims=[4, 8])
>>> dmrg.solve(tol=1e-12)  # find the ground state
>>> job = haiqu.mps_loading(dmrg.state.arrays, shape="lpr")  # Quimb uses another shape
>>> heis_gs = qiskit.QuantumCircuit(4)
>>> heis_gs.compose(job.result(), inplace=True)  # circuit preparing the ground state
>>> print(f"Ground state was loaded with fidelity {job.fidelity:.3f}")
Ground state was loaded with fidelity 1.000