Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for phase, sqrt(X), and delay gates to simulators #951

Merged
merged 15 commits into from
Sep 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion qiskit/providers/aer/backends/qasm_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ class QasmSimulator(AerBackend):
't', 'tdg', 'swap', 'ccx', 'r', 'rx', 'ry', 'rz', 'rxx', 'ryy',
'rzz', 'rzx', 'unitary', 'diagonal', 'initialize', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcrx', 'mcry', 'mcrz', 'mcr',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'multiplexer', 'kraus', 'roerror'
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'p', 'cp', 'mcp', 'sx', 'csx', 'mcsx',
'multiplexer', 'kraus', 'roerror'
],
'gates': []
}
Expand Down
3 changes: 2 additions & 1 deletion qiskit/providers/aer/backends/statevector_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ class StatevectorSimulator(AerBackend):
't', 'tdg', 'swap', 'ccx', 'r', 'rx', 'ry', 'rz', 'rxx', 'ryy',
'rzz', 'rzx', 'unitary', 'diagonal', 'initialize', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcrx', 'mcry', 'mcrz', 'mcr',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'multiplexer',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'p', 'cp', 'mcp', 'sx', 'csx', 'mcsx',
'multiplexer',
],
'gates': []
}
Expand Down
3 changes: 2 additions & 1 deletion qiskit/providers/aer/backends/unitary_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ class UnitarySimulator(AerBackend):
't', 'tdg', 'swap', 'ccx', 'r', 'rx', 'ry', 'rz', 'rxx', 'ryy',
'rzz', 'rzx', 'unitary', 'diagonal', 'cu1', 'cu2',
'cu3', 'cswap', 'mcx', 'mcy', 'mcz', 'mcrx', 'mcry', 'mcrz', 'mcr',
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'multiplexer', 'kraus', 'roerror'
'mcu1', 'mcu2', 'mcu3', 'mcswap', 'p', 'cp', 'mcp', 'sx', 'csx', 'mcsx',
'multiplexer'
],
'gates': []
}
Expand Down
10 changes: 8 additions & 2 deletions qiskit/providers/aer/noise/noise_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import json
import logging
from warnings import warn

from qiskit.circuit import Instruction
from qiskit.providers import BaseBackend
Expand Down Expand Up @@ -94,10 +95,10 @@ class NoiseModel:
# Checks for standard 1-3 qubit instructions
_1qubit_instructions = set([
"x90", "u1", "u2", "u3", "U", "id", "x", "y", "z", "h", "s", "sdg",
"t", "tdg", "r", "rx", "ry", "rz"
"t", "tdg", "r", "rx", "ry", "rz", "p"
])
_2qubit_instructions = set(["cx", "cz", "swap", "rxx", "ryy", "rzz",
"rzx", "cu1", "cu2", "cu3"])
"rzx", "cu1", "cu2", "cu3", "cp"])
_3qubit_instructions = set(["ccx", "cswap"])

def __init__(self, basis_gates=None):
Expand Down Expand Up @@ -415,6 +416,11 @@ def set_x90_single_qubit_gates(self, instructions):
Raises:
NoiseError: if the input instructions are not valid.
"""
warn('This function is deprecated and will be removed in a future release. '
'To use an X90 based noise model use the Sqrt(X) "sx" gate and one of '
' the single-qubit phase gates "u1", "rx", "p" in the noise model and '
' basis gates to decompose into this gateset for noise simulations.',
DeprecationWarning)
for name, label in self._instruction_names_labels(instructions):
# Add X-90 based gate to noisy gates
self._noise_instructions.add(label)
Expand Down
33 changes: 33 additions & 0 deletions releasenotes/notes/basis-gates-acbc8a1a52a49413.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
features:
- |
Adds support for parameterized delay gate ``"delay"`` to the
:class:`~qiskit.providers.aer.StatevectorSimulator`,
:class:`~qiskit.providers.aer.UnitarySimulator`, and
:class:`~qiskit.providers.aer.QasmSimulator`.
By default this gate is treated as an identity gate during simulation.
- |
Adds support for parameterized phase gate ``"p"`` and controlled-phase
gate ``"cp"`` to the :class:`~qiskit.providers.aer.StatevectorSimulator`,
:class:`~qiskit.providers.aer.UnitarySimulator`, and the
``"statevector"`` and ``"density_matrix"`` methods of the
:class:`~qiskit.providers.aer.QasmSimulator`.
- |
Adds support for the multi-controlled phase gate ``"mcphase"`` to the
:class:`~qiskit.providers.aer.StatevectorSimulator`,
:class:`~qiskit.providers.aer.UnitarySimulator`, and the
``"statevector"`` method of the
:class:`~qiskit.providers.aer.QasmSimulator`.
- |
Adds support for the :math:`\sqrt(X)` gate ``"sx"`` to the
class:`~qiskit.providers.aer.StatevectorSimulator`,
:class:`~qiskit.providers.aer.UnitarySimulator`, and the
``"statevector"`` and ``"density_matrix"`` methods of the
:class:`~qiskit.providers.aer.QasmSimulator`.
deprecations:
- |
:meth:`qiskit.providers.aer.noise.NoiseModel.set_x90_single_qubit_gates` has
been deprecated as unrolling to custom basis gates has been added to the
qiskit transpiler. The correct way to use an X90 based noise model is to
define noise on the Sqrt(X) "sx" or "rx" gate and one of the single-qubit
phase gates "u1", "rx", "p" in the noise model.
56 changes: 50 additions & 6 deletions src/framework/linalg/matrix_utils/matrix_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class Matrix {
const static cmatrix_t SDG; // name: "sdg"
const static cmatrix_t T; // name: "t"
const static cmatrix_t TDG; // name: "tdg"
const static cmatrix_t SX; // name: "sx"
const static cmatrix_t X90; // name: "x90"

// Two-qubit gates
Expand Down Expand Up @@ -70,9 +71,15 @@ class Matrix {
static cmatrix_t rzz(double theta);
static cmatrix_t rzx(double theta); // rotation around Tensor(X, Z)

// Phase Gates
static cmatrix_t phase(double theta);
static cmatrix_t phase_diag(double theta);
static cmatrix_t cphase(double theta);
static cmatrix_t cphase_diag(double theta);

// Complex arguments are implemented by taking std::real
// of the input
static cmatrix_t u1(complex_t lam) { return u1(std::real(lam)); }
static cmatrix_t u1(complex_t lam) { return phase(std::real(lam)); }
static cmatrix_t u2(complex_t phi, complex_t lam) {
return u2(std::real(phi), std::real(lam));
}
Expand All @@ -89,6 +96,10 @@ class Matrix {
static cmatrix_t ryy(complex_t theta) { return ryy(std::real(theta)); }
static cmatrix_t rzz(complex_t theta) { return rzz(std::real(theta)); }
static cmatrix_t rzx(complex_t theta) { return rzx(std::real(theta)); }
static cmatrix_t phase(complex_t theta) { return phase(std::real(theta)); }
static cmatrix_t phase_diag(complex_t theta) { return phase_diag(std::real(theta)); }
static cmatrix_t cphase(complex_t theta) { return cphase(std::real(theta)); }
static cmatrix_t cphase_diag(complex_t theta) { return cphase_diag(std::real(theta)); }

// Return the matrix for a named matrix string
// Allowed names correspond to all the const static single-qubit
Expand Down Expand Up @@ -138,6 +149,9 @@ const cmatrix_t Matrix::H = Utils::make_matrix<complex_t>(
{{{1 / std::sqrt(2.), 0}, {1 / std::sqrt(2.), 0}},
{{1 / std::sqrt(2.), 0}, {-1 / std::sqrt(2.), 0}}});

const cmatrix_t Matrix::SX = Utils::make_matrix<complex_t>(
{{{0.5, 0.5}, {0.5, -0.5}}, {{0.5, -0.5}, {0.5, 0.5}}});

const cmatrix_t Matrix::X90 = Utils::make_matrix<complex_t>(
{{{1. / std::sqrt(2.), 0}, {0, -1. / std::sqrt(2.)}},
{{0, -1. / std::sqrt(2.)}, {1. / std::sqrt(2.), 0}}});
Expand Down Expand Up @@ -172,7 +186,8 @@ const stringmap_t<const cmatrix_t *> Matrix::label_map_ = {
{"z", &Matrix::Z}, {"h", &Matrix::H}, {"s", &Matrix::S},
{"sdg", &Matrix::SDG}, {"t", &Matrix::T}, {"tdg", &Matrix::TDG},
{"x90", &Matrix::X90}, {"cx", &Matrix::CX}, {"cy", &Matrix::CY},
{"cz", &Matrix::CZ}, {"swap", &Matrix::SWAP}};
{"cz", &Matrix::CZ}, {"swap", &Matrix::SWAP}, {"sx", &Matrix::SX},
{"delay", &Matrix::I}};

cmatrix_t Matrix::identity(size_t dim) {
cmatrix_t mat(dim, dim);
Expand All @@ -182,10 +197,7 @@ cmatrix_t Matrix::identity(size_t dim) {
}

cmatrix_t Matrix::u1(double lambda) {
cmatrix_t mat(2, 2);
mat(0, 0) = {1., 0.};
mat(1, 1) = std::exp(complex_t(0., lambda));
return mat;
return phase(lambda);
}

cmatrix_t Matrix::u2(double phi, double lambda) {
Expand Down Expand Up @@ -306,6 +318,38 @@ cmatrix_t Matrix::rzx(double theta) {
return mat;
}

cmatrix_t Matrix::phase(double theta) {
cmatrix_t mat(2, 2);
mat(0, 0) = 1;
mat(1, 1) = std::exp(complex_t(0.0, theta));
return mat;
}

cmatrix_t Matrix::phase_diag(double theta) {
cmatrix_t mat(1, 2);
mat(0, 0) = 1;
mat(0, 1) = std::exp(complex_t(0.0, theta));
return mat;
}

cmatrix_t Matrix::cphase(double theta) {
cmatrix_t mat(4, 4);
mat(0, 0) = 1;
mat(1, 1) = 1;
mat(2, 2) = 1;
mat(3, 3) = std::exp(complex_t(0.0, theta));
return mat;
}

cmatrix_t Matrix::cphase_diag(double theta) {
cmatrix_t mat(1, 4);
mat(0, 0) = 1;
mat(0, 1) = 1;
mat(0, 2) = 1;
mat(0, 3) = std::exp(complex_t(0.0, theta));
return mat;
}

//------------------------------------------------------------------------------
} // end namespace Linalg
//------------------------------------------------------------------------------
Expand Down
89 changes: 81 additions & 8 deletions src/framework/linalg/matrix_utils/smatrix_defs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class SMatrix {
const static cmatrix_t SDG; // name: "sdg"
const static cmatrix_t T; // name: "t"
const static cmatrix_t TDG; // name: "tdg"
const static cmatrix_t SX; // name: "sx"
const static cmatrix_t X90; // name: "x90"

// Two-qubit gates
Expand Down Expand Up @@ -71,9 +72,15 @@ class SMatrix {
static cmatrix_t rzz(double theta);
static cmatrix_t rzx(double theta); // rotation around Tensor(X, Z)

// Phase Gates
static cmatrix_t phase(double theta);
static cmatrix_t phase_diag(double theta);
static cmatrix_t cphase_diag(double theta);
static cmatrix_t cphase(double theta);

// Complex arguments are implemented by taking std::real
// of the input
static cmatrix_t u1(complex_t lam) { return u1(std::real(lam)); }
static cmatrix_t u1(complex_t lam) { return phase(std::real(lam)); }
static cmatrix_t u2(complex_t phi, complex_t lam) {
return u2(std::real(phi), std::real(lam));
}
Expand All @@ -90,6 +97,10 @@ class SMatrix {
static cmatrix_t ryy(complex_t theta) { return ryy(std::real(theta)); }
static cmatrix_t rzz(complex_t theta) { return rzz(std::real(theta)); }
static cmatrix_t rzx(complex_t theta) { return rzx(std::real(theta)); }
static cmatrix_t phase(complex_t theta) { return phase(std::real(theta)); }
static cmatrix_t phase_diag(complex_t theta) { return phase_diag(std::real(theta)); }
static cmatrix_t cphase(complex_t theta) { return cphase(std::real(theta)); }
static cmatrix_t cphase_diag(complex_t theta) { return cphase_diag(std::real(theta)); }

// Return superoperator matrix for reset instruction
// on specified dim statespace.
Expand Down Expand Up @@ -135,6 +146,8 @@ const cmatrix_t SMatrix::TDG = Utils::unitary_superop(Matrix::TDG);

const cmatrix_t SMatrix::H = Utils::unitary_superop(Matrix::H);

const cmatrix_t SMatrix::SX = Utils::unitary_superop(Matrix::SX);

const cmatrix_t SMatrix::X90 = Utils::unitary_superop(Matrix::X90);

const cmatrix_t SMatrix::CX = Utils::unitary_superop(Matrix::CX);
Expand All @@ -151,17 +164,13 @@ const stringmap_t<const cmatrix_t *> SMatrix::label_map_ = {
{"z", &SMatrix::Z}, {"h", &SMatrix::H}, {"s", &SMatrix::S},
{"sdg", &SMatrix::SDG}, {"t", &SMatrix::T}, {"tdg", &SMatrix::TDG},
{"x90", &SMatrix::X90}, {"cx", &SMatrix::CX}, {"cy", &SMatrix::CY},
{"cz", &SMatrix::CZ}, {"swap", &SMatrix::SWAP}};
{"cz", &SMatrix::CZ}, {"swap", &SMatrix::SWAP}, {"sx", &SMatrix::SX},
{"delay", &SMatrix::I}};

cmatrix_t SMatrix::identity(size_t dim) { return Matrix::identity(dim * dim); }

cmatrix_t SMatrix::u1(double lambda) {
cmatrix_t mat(4, 4);
mat(0, 0) = {1., 0.};
mat(1, 1) = std::exp(complex_t(0., lambda));
mat(2, 2) = std::exp(complex_t(0., -lambda));
mat(3, 3) = {1., 0.};
return mat;
return phase(lambda);
}

cmatrix_t SMatrix::u2(double phi, double lambda) {
Expand Down Expand Up @@ -206,6 +215,70 @@ cmatrix_t SMatrix::rzx(double theta) {
return Utils::tensor_product(Matrix::rzx(-theta), Matrix::rzx(theta));
}

cmatrix_t SMatrix::phase(double theta) {
cmatrix_t mat(4, 4);
mat(0, 0) = {1., 0.};
mat(1, 1) = std::exp(complex_t(0., theta));
mat(2, 2) = std::exp(complex_t(0., -theta));
mat(3, 3) = {1., 0.};
return mat;
}

cmatrix_t SMatrix::phase_diag(double theta) {
cmatrix_t mat(1, 4);
mat(0, 0) = {1., 0.};
mat(0, 1) = std::exp(complex_t(0., theta));
mat(0, 2) = std::exp(complex_t(0., -theta));
mat(0, 3) = {1., 0.};
return mat;
}

cmatrix_t SMatrix::cphase(double theta) {
const auto exp_p = std::exp(complex_t(0., theta));
const auto exp_m = std::exp(complex_t(0., -theta));
cmatrix_t mat(16, 16);
mat(0, 0) = {1., 0.};
mat(1, 1) = {1., 0.};
mat(2, 2) = {1., 0.};
mat(3, 3) = exp_p;
mat(4, 4) = {1., 0.};
mat(5, 5) = {1., 0.};
mat(6, 6) = {1., 0.};
mat(7, 7) = exp_p;
mat(8, 8) = {1., 0.};
mat(9, 9) = {1., 0.};
mat(10, 10) = {1., 0.};
mat(11, 11) = exp_p;
mat(12, 12) = exp_m;
mat(13, 13) = exp_m;
mat(14, 14) = exp_m;
mat(15, 15) = {1., 0.};
return mat;
}

cmatrix_t SMatrix::cphase_diag(double theta) {
const auto exp_p = std::exp(complex_t(0., theta));
const auto exp_m = std::exp(complex_t(0., -theta));
cmatrix_t mat(1, 16);
mat(0, 0) = {1., 0.};
mat(0, 1) = {1., 0.};
mat(0, 2) = {1., 0.};
mat(0, 3) = exp_p;
mat(0, 4) = {1., 0.};
mat(0, 5) = {1., 0.};
mat(0, 6) = {1., 0.};
mat(0, 7) = exp_p;
mat(0, 8) = {1., 0.};
mat(0, 9) = {1., 0.};
mat(0, 10) = {1., 0.};
mat(0, 11) = exp_p;
mat(0, 12) = exp_m;
mat(0, 13) = exp_m;
mat(0, 14) = exp_m;
mat(0, 15) = {1., 0.};
return mat;
}

cmatrix_t SMatrix::reset(size_t dim) {
cmatrix_t mat(dim * dim, dim * dim);
for (size_t j = 0; j < dim; j++) {
Expand Down
Loading