Skip to content

Hardware Efficient Ansatz

In NISQ-era devices, to reduce noise, use short and hardware-fitting quantum programs.

Hardware-efficient ansatz is generated to fit a specific hardware with given connectivity map and basis gates [1] . The hardware-efficient ansatz is built from a layer of single qubit gates followed by a layer of entangling two qubit gates. Repeating this structure allows a more expressive ansatz at the cost of increased depth.

Syntax

HEAParameters:

  • num_qubits: int – Number of qubits in the ansatz.
  • connectivity_map: List[Tuple[int]] – Hardware connectivity map, in the form [ [x0, x1], [x1, x2],...].
  • reps: int – Number of layers in the ansatz.
  • one_qubit_gates: List[str] – List of gates for the one qubit gates layer, e.g., ["x", "ry"].
  • two_qubit_gates: List[str] – List of gates for the two qubit gates entangling layer, e.g., ["cx", "cry"].

If the number of qubits is not specified, the number of the qubits from the connectivity map is used. If the connectivity map is not specified, the connectivity map from the model hardware settings is used. If that is also not specified, all qubit pairs are connected.

The allowed one_qubit_gates: '["x", "y", "z", "h", "p", "i", "rx", "ry", "rz", "s", "sdg", "t", "tdg"]'.

The allowed two_qubit_gates: '["cx", "cy", "cz", "ch", "cp", "crx", "cry", "crz", "rxx", "ryy", "rzz", "swap"]'.

Example

This example demonstrates how to generate a hardware-efficient ansatz. It uses a four qubit hardware with full connectivity.

qmod
{
  "functions": [
    {
      "name": "main",
      "param_decls": {
        "t": {
          "kind": "array",
          "element_type": {
            "kind": "real"
          },
          "size": 12
        }
      },
      "body": [
        {
          "name": "hf"
        },
        {
          "function": "allocate",
          "positional_args": [
            {
              "expr": "len(get_field(molecule_problem_to_hamiltonian(struct_literal(MoleculeProblem,mapping=FermionMapping.JORDAN_WIGNER,z2_symmetries=False,molecule=struct_literal(Molecule,atoms=[struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.0)),struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.735))],spin=1,charge=0),freeze_core=False,remove_orbitals=[]))[0], 'pauli'))"
            },
            {
              "name": "hf"
            }
          ]
        },
        {
          "function": "molecule_hartree_fock",
          "params": {
            "molecule_problem": {
              "expr": "struct_literal(MoleculeProblem,mapping=FermionMapping.JORDAN_WIGNER,z2_symmetries=False,molecule=struct_literal(Molecule,atoms=[struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.0)),struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.735))],spin=1,charge=0),freeze_core=False,remove_orbitals=[])"
            }
          },
          "inouts": {
            "qbv": {
              "name": "hf"
            }
          }
        },
        {
          "function": "full_hea",
          "params": {
            "num_qubits": {
              "expr": "4"
            },
            "is_parametrized": {
              "expr": "[0, 1, 0]"
            },
            "connectivity_map": {
              "expr": "[[0, 1], [1, 2], [2, 3]]"
            },
            "reps": {
              "expr": "3"
            },
            "angle_params": {
              "expr": "t"
            }
          },
          "inouts": {
            "x": {
              "name": "hf"
            }
          },
          "operands": {
            "operands_1qubit": [
              {
                "body": [
                  {
                    "function": "X",
                    "inouts": {
                      "target": {
                        "name": "q"
                      }
                    }
                  }
                ]
              },
              {
                "body": [
                  {
                    "function": "RY",
                    "params": {
                      "theta": {
                        "expr": "angle"
                      }
                    },
                    "inouts": {
                      "target": {
                        "name": "q"
                      }
                    }
                  }
                ]
              }
            ],
            "operands_2qubit": [
              {
                "body": [
                  {
                    "function": "CX",
                    "inouts": {
                      "target": {
                        "name": "q1"
                      },
                      "control": {
                        "name": "q2"
                      }
                    }
                  }
                ]
              }
            ]
          }
        }
      ]
    }
  ],
  "classical_execution_code": "\nvqe_result = vqe(\n    hamiltonian=molecule_problem_to_hamiltonian(struct_literal(MoleculeProblem,mapping=FermionMapping.JORDAN_WIGNER,z2_symmetries=False,molecule=struct_literal(Molecule,atoms=[struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.0)),struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.735))],spin=1,charge=0),freeze_core=False,remove_orbitals=[])), maximize=False,\ninitial_point=[],\noptimizer=Optimizer.COBYLA,\nmax_iteration=30,\ntolerance=0,\nstep_size=0,\nskip_compute_variance=False,\nalpha_cvar=1.0,\n\n)\n\nmolecule_result = molecule_ground_state_solution_post_process(struct_literal(MoleculeProblem,mapping=FermionMapping.JORDAN_WIGNER,z2_symmetries=False,molecule=struct_literal(Molecule,atoms=[struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.0)),struct_literal(ChemistryAtom,element=Element.H,position=struct_literal(Position,x=0.0,y=0.0,z=0.735))],spin=1,charge=0),freeze_core=False,remove_orbitals=[]),vqe_result)\nsave({'molecule_result': molecule_result})\n"
}
from classiq import construct_chemistry_model, synthesize
from classiq.applications.chemistry import Molecule, MoleculeProblem
from classiq.applications.chemistry import HEAParameters, ChemistryExecutionParameters
from classiq.execution import OptimizerType

from classiq import execute

molecule = Molecule(
    atoms=[("H", (0.0, 0.0, 0.0)), ("H", (0.0, 0.0, 0.735))],
)
gs_problem = MoleculeProblem(
    molecule=molecule,
    mapping="jordan_wigner",
)

ansatz_parameters = HEAParameters(
    reps=3,
    num_qubits=4,
    connectivity_map=[(0, 1), (1, 2), (2, 3)],
    one_qubit_gates=["x", "ry"],
    two_qubit_gates=["cx"],
)
execution_params = ChemistryExecutionParameters(
    optimizer=OptimizerType.COBYLA,
    max_iteration=30,
)

model = construct_chemistry_model(
    chemistry_problem=gs_problem,
    use_hartree_fock=True,
    ansatz_parameters=ansatz_parameters,
    execution_parameters=execution_params,
)
qprog = synthesize(model)

result = execute(qprog).result()

The output quantum program:

alt text

[1] Abhinav Kandala, Antonio Mezzacapo, Kristan Temme, Maika Takita, Markus Brink, Jerry M. Chow, Jay M. Gambetta Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets. Nature 549, 242 (2017).