mindquantum.simulator

Quantum simulator that simulate evolution of quantum system.

class mindquantum.simulator.GradOpsWrapper(grad_ops, hams, circ_right, circ_left, encoder_params_name, ansatz_params_name, parallel_worker)[source]

Wrapper the gradient operator that with the information that generate this gradient operator.

Parameters
  • grad_ops (Union[FunctionType, MethodType]) – A function or a method that return forward value and gradient w.r.t parameters.

  • hams (Hamiltonian) – The hamiltonian that generate this grad ops.

  • circ_right (Circuit) – The right circuit that generate this grad ops.

  • circ_left (Circuit) – The left circuit that generate this grad ops.

  • encoder_params_name (list[str]) – The encoder parameters name.

  • ansatz_params_name (list[str]) – The ansatz parameters name.

  • parallel_worker (int) – The number of parallel worker to run the batch.

set_str(grad_str)[source]

Set expression for gradient operator.

Parameters

grad_str (str) – The string of QNN operator.

class mindquantum.simulator.Simulator(backend, n_qubits, *args, seed=None, **kwargs)[source]

Quantum simulator that simulate quantum circuit.

Parameters
  • backend (str) – which backend you want. The supported backend can be found in SUPPORTED_SIMULATOR

  • n_qubits (int) – number of quantum simulator.

  • seed (int) – the random seed for this simulator, if None, seed will generate by numpy.random.randint. Default: None.

Raises

Examples

>>> from mindquantum.algorithm.library import qft
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 2)
>>> sim.apply_circuit(qft(range(2)))
>>> sim.get_qs()
array([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j])
apply_circuit(circuit, pr=None)[source]

Apply a circuit on this simulator.

Parameters
Returns

MeasureResult or None, if the circuit has measure gate, then return a MeasureResult, otherwise return None.

Examples

>>> import numpy as np
>>> from mindquantum.core.circuit import Circuit
>>> from mindquantum.core.gates import H
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 2)
>>> sim.apply_circuit(Circuit().un(H, 2))
>>> sim.apply_circuit(Circuit().ry('a', 0).ry('b', 1), np.array([1.1, 2.2]))
>>> sim
mqvector simulator with 2 qubits  (little endian).
Current quantum state:
-0.0721702531972066¦00⟩
-0.30090405886869676¦01⟩
0.22178317006196263¦10⟩
0.9246947752567126¦11⟩
>>> sim.apply_circuit(Circuit().measure(0).measure(1))
shots: 1
Keys: q1 q0│0.00     0.2         0.4         0.6         0.8         1.0
───────────┼───────────┴───────────┴───────────┴───────────┴───────────┴
         11│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

{'11': 1}
apply_gate(gate, pr=None, diff=False)[source]

Apply a gate on this simulator, can be a quantum gate or a measurement operator.

Parameters
Returns

int or None, if the gate if a measure gate, then return a collapsed state, Otherwise return None.

Raises
  • TypeError – if gate is not a BasicGate.

  • ValueError – if any qubit of gate is higher than simulator qubits.

  • ValueError – if gate is parameterized, but no parameter supplied.

  • TypeError – the pr is not a ParameterResolver if gate is parameterized.

Examples

>>> import numpy as np
>>> from mindquantum.core.gates import RY, Measure
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 1)
>>> sim.apply_gate(RY('a').on(0), np.pi/2)
>>> sim.get_qs()
array([0.70710678+0.j, 0.70710678+0.j])
>>> sim.apply_gate(Measure().on(0))
1
>>> sim.get_qs()
array([0.+0.j, 1.+0.j])
apply_hamiltonian(hamiltonian: Hamiltonian)[source]

Apply hamiltonian to a simulator, this hamiltonian can be hermitian or non hermitian.

Note

The quantum state may be not a normalized quantum state after apply hamiltonian.

Parameters

hamiltonian (Hamiltonian) – the hamiltonian you want to apply.

Examples

>>> from mindquantum.core.circuit import Circuit
>>> from mindquantum.core.operators import QubitOperator, Hamiltonian
>>> from mindquantum.simulator import Simulator
>>> import scipy.sparse as sp
>>> sim = Simulator('mqvector', 1)
>>> sim.apply_circuit(Circuit().h(0))
>>> sim.get_qs()
array([0.70710678+0.j, 0.70710678+0.j])
>>> ham1 = Hamiltonian(QubitOperator('Z0'))
>>> sim.apply_hamiltonian(ham1)
>>> sim.get_qs()
array([ 0.70710678+0.j, -0.70710678+0.j])
>>> sim.reset()
>>> ham2 = Hamiltonian(sp.csr_matrix([[1, 2], [3, 4]]))
>>> sim.apply_hamiltonian(ham2)
>>> sim.get_qs()
array([1.+0.j, 3.+0.j])
copy()[source]

Copy this simulator.

Returns

Simulator, a copy version of this simulator.

Examples

>>> from mindquantum.core.gates import RX
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 1)
>>> sim.apply_gate(RX(1).on(0))
>>> sim.flush()
>>> sim2 = sim.copy()
>>> sim2.apply_gate(RX(-1).on(0))
>>> sim2
mqvector simulator with 1 qubit (little endian).
Current quantum state:
1¦0⟩
flush()[source]

Flush gate that works for projectq simulator.

The projectq simulator will cache several gate and fusion these gate into a bigger gate, and than act on the quantum state. The flush command will ask the simulator to fusion currently stored gate and act on the quantum state.

Examples

>>> from mindquantum.core.gates import H
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('projectq', 1)
>>> sim.apply_gate(H.on(0))
>>> sim.flush()
get_expectation(hamiltonian)[source]

Get expectation of the given hamiltonian. The hamiltonian could be non hermitian.

\[E = \left<\psi\right|H\left|\psi\right>\]
Parameters

hamiltonian (Hamiltonian) – The hamiltonian you want to get expectation.

Returns

numbers.Number, the expectation value.

Examples

>>> from mindquantum.core.circuit import Circuit
>>> from mindquantum.core.operators import QubitOperator, Hamiltonian
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 1)
>>> sim.apply_circuit(Circuit().ry(1.2, 0))
>>> ham = Hamiltonian(QubitOperator('Z0'))
>>> sim.get_expectation(ham)
(0.36235775447667357+0j)
get_expectation_with_grad(hams, circ_right, circ_left=None, simulator_left=None, parallel_worker=None)[source]

Get a function that return the forward value and gradient w.r.t circuit parameters.

This method is designed to calculate the expectation and its gradient shown as below.

\[E = \left<\varphi\right|U_l^\dagger H U_r \left|\psi\right>\]

where \(U_l\) is circ_left, \(U_r\) is circ_right, \(H\) is hams and \(\left|\psi\right>\) is the current quantum state of this simulator, and \(\left|\varphi\right>\) is the quantum state of simulator_left.

Parameters
  • hams (Hamiltonian) – The hamiltonian that need to get expectation.

  • circ_right (Circuit) – The \(U_r\) circuit described above.

  • circ_left (Circuit) – The \(U_l\) circuit described above. By default, this circuit will be none, and in this situation, \(U_l\) will be equals to \(U_r\). Default: None.

  • simulator_left (Simulator) – The simulator that contains \(\left|\varphi\right>\). If None, then \(\left|\varphi\right>\) is assumed to be equals to \(\left|\psi\right>\). Default: None.

  • parallel_worker (int) – The parallel worker numbers. The parallel workers can handle batch in parallel threads. Default: None.

Returns

GradOpsWrapper, a grad ops wrapper than contains information to generate this grad ops.

Examples

>>> import numpy as np
>>> from mindquantum.core.circuit import Circuit
>>> from mindquantum.core.operators import QubitOperator, Hamiltonian
>>> from mindquantum.simulator import Simulator
>>> circ = Circuit().ry('a', 0)
>>> ham = Hamiltonian(QubitOperator('Z0'))
>>> sim = Simulator('mqvector', 1)
>>> grad_ops = sim.get_expectation_with_grad(ham, circ)
>>> grad_ops(np.array([1.0]))
(array([[0.54030231+0.j]]), array([[[-0.84147098+0.j]]]))
>>> sim1 = Simulator('mqvector', 1)
>>> prep_circ = Circuit().h(0)
>>> ansatz = Circuit().ry('a', 0).rz('b', 0).ry('c', 0)
>>> sim1.apply_circuit(prep_circ)
>>> sim2 = Simulator('mqvector', 1)
>>> ham = Hamiltonian(QubitOperator(""))
>>> grad_ops = sim2.get_expectation_with_grad(ham, ansatz, Circuit(), simulator_left=sim1)
>>> f, g = grad_ops(np.array([7.902762e-01, 2.139225e-04, 7.795934e-01]))
>>> f
array([[0.99999989-7.52279618e-05j]])
get_qs(ket=False)[source]

Get current quantum state of this simulator.

Parameters

ket (bool) – Whether to return the quantum state in ket format or not. Default: False.

Returns

numpy.ndarray, the current quantum state.

Examples

>>> from mindquantum.algorithm.library import qft
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 2)
>>> sim.apply_circuit(qft(range(2)))
>>> sim.get_qs()
array([0.5+0.j, 0.5+0.j, 0.5+0.j, 0.5+0.j])
property n_qubits

Get simulator qubit.

Returns

int, the qubit number of simulator.

reset()[source]

Reset simulator to zero state.

Examples

>>> from mindquantum.algorithm.library import qft
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 2)
>>> sim.apply_circuit(qft(range(2)))
>>> sim.reset()
>>> sim.get_qs()
array([1.+0.j, 0.+0.j, 0.+0.j, 0.+0.j])
sampling(circuit, pr=None, shots=1, seed=None)[source]

Sample the measure qubit in circuit.

Sampling does not change the origin quantum state of this simulator.

Parameters
  • circuit (Circuit) – The circuit that you want to evolution and do sampling.

  • pr (Union[None, dict, ParameterResolver]) – The parameter resolver for this circuit, if this circuit is a parameterized circuit. Default: None.

  • shots (int) – How many shots you want to sampling this circuit. Default: 1

  • seed (int) – Random seed for random sampling. If None, seed will be a random int number. Default: None.

Returns

MeasureResult, the measure result of sampling.

Examples

>>> from mindquantum.core.circuit import Circuit
>>> from mindquantum.core.gates import Measure
>>> from mindquantum.simulator import Simulator
>>> circ = Circuit().ry('a', 0).ry('b', 1)
>>> circ += Measure('q0_0').on(0)
>>> circ += Measure('q0_1').on(0)
>>> circ += Measure('q1').on(1)
>>> sim = Simulator('mqvector', circ.n_qubits)
>>> res = sim.sampling(circ, {'a': 1.1, 'b': 2.2}, shots=100, seed=42)
>>> res
shots: 100
Keys: q1 q0_1 q0_0│0.00   0.122       0.245       0.367        0.49       0.612
──────────────────┼───────────┴───────────┴───────────┴───────────┴───────────┴
               000│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

               011│▒▒▒▒▒▒▒▒▒

               100│▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓

               111│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

{'000': 18, '011': 9, '100': 49, '111': 24}
set_qs(quantum_state)[source]

Set quantum state for this simulation.

Parameters

quantum_state (numpy.ndarray) – the quantum state that you want.

Examples

>>> import numpy as np
>>> from mindquantum.simulator import Simulator
>>> sim = Simulator('mqvector', 1)
>>> sim.get_qs()
array([1.+0.j, 0.+0.j])
>>> sim.set_qs(np.array([1, 1]))
>>> sim.get_qs()
array([0.70710678+0.j, 0.70710678+0.j])
set_threads_number(number)[source]

Set maximum number of threads.

Parameters

number (int) – The thread number the simulator will use for thread pool.

mindquantum.simulator.get_supported_simulator()[source]

Get simulator name that supported by MindQuantum.

Returns

list, The supported simulator list.

mindquantum.simulator.inner_product(bra_simulator: Simulator, ket_simulator: Simulator)[source]

Calculate the inner product of two state that in the given simulator.

Parameters
  • bra_simulator (Simulator) – The simulator that serve as bra state.

  • ket_simulator (Simulator) – The simulator that serve as ket state.

Returns

numbers.Number, the inner product of two quantum state.

Examples

>>> from mindquantum.core.gates import RX, RY
>>> from mindquantum.simulator import inner_product, Simulator
>>> bra_simulator = Simulator('mqvector', 1)
>>> bra_simulator.apply_gate(RY(1.2).on(0))
>>> ket_simulator = Simulator('mqvector', 1)
>>> ket_simulator.apply_gate(RX(2.3).on(0))
>>> inner_product(bra_simulator, ket_simulator)
(0.33713923320500694-0.5153852888544989j)