Noisy Algorithm Model

Extracting the Noise Model

The noisy algorithm model of a Hamiltonian is generated by the function HqsNoiseApp.noisy_algorithm_model, with input arguments:

  • hamiltonian: The Hamiltonian for which the noise algorithm model is created.
  • trotter_timestep: The simulation time the circuit propagates the simulated system.
  • device: The device that determines the topology.
  • noise_models: The noise models that determine the noise properties.

The noisy algorithm model represents the effective Lindblad noise that the system simulated with a given Hamiltonian is exposed to due to qubit noise during a single Trotter step, see the mapping section for more details on effective noise mapping.

An example is:

from hqs_noise_app import HqsNoiseApp
from struqture_py import spins
from qoqo import devices, noise_models

# define hamiltonian 
number_spins = 4
hamiltonian = spins.PauliHamiltonian()
hamiltonian.add_operator_product(spins.PauliProduct().z(0).z(2).z(3), 4.0)

# Setting up the device
single_qubit_gates = ["RotateX", "RotateZ"]
two_qubit_gates = ["CNOT"]
gate_times = 1.0
damping = 1e-3
device = devices.AllToAllDevice(
    number_spins, single_qubit_gates, two_qubit_gates, gate_times
)
# While the noise model is not needed to generate the quantum program, it will be
# required when simulating the quantum program.
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate(
    [0, 1, 2, 3], damping
)

# create inputs
trotter_timestep = 0.01
noise_app = HqsNoiseApp()

# obtain noisy algorithm model
noisy_model = noise_app.noisy_algorithm_model(
    hamiltonian, trotter_timestep, device, [noise_model]
)

noisy_model is an object of type 'struqture.spins.PauliLindbladNoiseOperator'.

Printing and Modifying a Noisy Algorithm Model

Information about the created noisy algorithm model can be obtained by:


noisy_model                            # noise terms and rates
noisy_model.keys()                     # strings of the Lindbladian noise matrix M
noisy_model.get(("0Z", "0Z"))          # accessing the rate of a specific noise term

When creating the effective model, we may encounter terms that are effectively zero, but appear as non-zero due to the finite numerical accuracy. To eliminate these terms one can use the truncate function:


# absolute values below the given threshold will be set to zero
truncated_model = noisy_model.truncate(1e-4)

Furthermore, when studying the effect of individual contributions, it may be useful to turn individual noise channels "off" or "on". For this, one can use add_operator_product function:


noisy_model.add_operator_product(("2Z", "2Z"), 0.5)
noisy_model.add_operator_product(("0Z2Z3Z", "0Z2Z3Z"), 0)

System-Bath Noisy Algorithm Model

The noisy algorithm model of a hamiltonian is generated by the function HqsNoiseApp.system_bath_noisy_algorithm_model, with input arguments:

  • hamiltonian: The Hamiltonian for which the noise algorithm model is created.
  • trotter_timestep: The simulation time the circuit propagates the simulated system.
  • device: The device that determines the topology.
  • noise_models: The noise models that determine the noise properties.
  • logical_to_physical_system: An optional mapping from logical to physical qubits for the system.
  • logical_to_physical_bath: An optional mapping from logical to physical qubits for the bath.
  • bath_qubit_connectivity: An optional connectivity between physical system and bath qubits.

An example is detailed below. For this example, we use the following physical device:

0 - 1 - 2 - 3
|   |   |   |
4 - 5 - 6 - 7

where we choose system qubits [4, 5, 6] and bath qubits [0, 1, 2].

from hqs_noise_app import HqsNoiseApp
from struqture_py import mixed_systems
from qoqo import devices, noise_models

# define hamiltonian on the logical indices
hamiltonian = mixed_systems.MixedHamiltonian(2, 0, 0)
# A XX interaction between spins 0 and 1 and spins 1 and 0
hamiltonian.set(mixed_systems.HermitianMixedProduct(["0X1X", ""], [], []), 1.0)
# A XX interaction between spins 1 and 2 and spins 1 and 0
hamiltonian.set(mixed_systems.HermitianMixedProduct(["1X2X", ""], [], []), 1.0)
hamiltonian.set(mixed_systems.HermitianMixedProduct(["0Z", "0Z"], [], []), 0.1)
hamiltonian.set(mixed_systems.HermitianMixedProduct(["1Z", "1Z"], [], []), 0.1)
hamiltonian.set(mixed_systems.HermitianMixedProduct(["2Z", "2Z"], [], []), 0.1)

# Setting up the device
single_qubit_gates = ["RotateX", "RotateZ"]
two_qubit_gates = ["CNOT"]
gate_times = 1.0
damping = 1e-3
device = devices.AllToAllDevice(
    8, single_qubit_gates, two_qubit_gates, gate_times
)
# While the noise model is not needed to generate the quantum program, it will be
# required when simulating the quantum program.
noise_model = noise_models.ContinuousDecoherenceModel().add_damping_rate(
    [0, 1, 2, 3, 4, 5, 6, 7], damping
)
# The logical-to-physical mappings would be as follows:
logical_to_physical_system = {0: 4, 1: 5, 2: 6}
logical_to_physical_bath = {0: 0, 1: 1, 2: 2}
# The corresponding bath connectivity is:
connectivity = {4: [0], 5: [1], 6: [2]}

# create inputs
trotter_timestep=0.01
noise_app = HqsNoiseApp()

# obtain noisy algorithm model
noisy_model = noise_app.system_bath_noisy_algorithm_model(
    hamiltonian,
    trotter_timestep,
    device,
    [noise_model],
    logical_to_physical_system,
    logical_to_physical_bath,
    connectivity    
)

noisy_model is an object of type 'struqture.spins.PauliLindbladNoiseOperator'.