/* automatically generated by rust-bindgen 0.59.1 */

#[doc = " A logger of QASM instructions"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct QASMLogger {
    pub buffer: *mut ::std::os::raw::c_char,
    pub bufferSize: ::std::os::raw::c_int,
    pub bufferFill: ::std::os::raw::c_int,
    pub isLogging: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_QASMLogger() {
    assert_eq!(
        ::std::mem::size_of::<QASMLogger>(),
        24usize,
        concat!("Size of: ", stringify!(QASMLogger))
    );
    assert_eq!(
        ::std::mem::align_of::<QASMLogger>(),
        8usize,
        concat!("Alignment of ", stringify!(QASMLogger))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QASMLogger>())).buffer as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(QASMLogger),
            "::",
            stringify!(buffer)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QASMLogger>())).bufferSize as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(QASMLogger),
            "::",
            stringify!(bufferSize)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QASMLogger>())).bufferFill as *const _ as usize },
        12usize,
        concat!(
            "Offset of field: ",
            stringify!(QASMLogger),
            "::",
            stringify!(bufferFill)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QASMLogger>())).isLogging as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(QASMLogger),
            "::",
            stringify!(isLogging)
        )
    );
}
#[doc = " Represents an array of complex numbers grouped into an array of"]
#[doc = " real components and an array of coressponding complex components."]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Ania Brown"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ComplexArray {
    pub real: *mut f64,
    pub imag: *mut f64,
}
#[test]
fn bindgen_test_layout_ComplexArray() {
    assert_eq!(
        ::std::mem::size_of::<ComplexArray>(),
        16usize,
        concat!("Size of: ", stringify!(ComplexArray))
    );
    assert_eq!(
        ::std::mem::align_of::<ComplexArray>(),
        8usize,
        concat!("Alignment of ", stringify!(ComplexArray))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexArray>())).real as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexArray),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexArray>())).imag as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexArray),
            "::",
            stringify!(imag)
        )
    );
}
pub const pauliOpType_PAULI_I: pauliOpType = 0;
pub const pauliOpType_PAULI_X: pauliOpType = 1;
pub const pauliOpType_PAULI_Y: pauliOpType = 2;
pub const pauliOpType_PAULI_Z: pauliOpType = 3;
#[doc = " Codes for specifying Pauli operators"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
pub type pauliOpType = ::std::os::raw::c_uint;
#[doc = " Represents one complex number."]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Ania Brown"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Complex {
    pub real: f64,
    pub imag: f64,
}
#[test]
fn bindgen_test_layout_Complex() {
    assert_eq!(
        ::std::mem::size_of::<Complex>(),
        16usize,
        concat!("Size of: ", stringify!(Complex))
    );
    assert_eq!(
        ::std::mem::align_of::<Complex>(),
        8usize,
        concat!("Alignment of ", stringify!(Complex))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Complex>())).real as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(Complex),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Complex>())).imag as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(Complex),
            "::",
            stringify!(imag)
        )
    );
}
#[doc = " Represents a 2x2 matrix of complex numbers."]
#[doc = ""]
#[doc = " In C, a ::ComplexMatrix2 can be initialised by separately specifying"]
#[doc = " the real and imaginary components as nested arrays. \\n"]
#[doc = " For example,"]
#[doc = " ```"]
#[doc = " ComplexMatrix2 m = {"]
#[doc = "     .real = {{1,2},"]
#[doc = "              {3,4}},"]
#[doc = "     .imag = {{5,6},"]
#[doc = "              {7, 8}}};"]
#[doc = " ```"]
#[doc = " specifies matrix"]
#[doc = " \\f["]
#[doc = "   m = \\begin{pmatrix}"]
#[doc = "      1 + 5\\,i & 2+6\\,i \\\\"]
#[doc = "      3 + 7\\,i & 4+ 8\\,i"]
#[doc = "   \\end{pmatrix}"]
#[doc = " \\f]"]
#[doc = ""]
#[doc = " @see"]
#[doc = " - ::ComplexMatrix4"]
#[doc = " - createComplexMatrixN()"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Balint Koczor"]
#[doc = " @author Tyson Jones (doc)"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ComplexMatrix2 {
    pub real: [[f64; 2usize]; 2usize],
    pub imag: [[f64; 2usize]; 2usize],
}
#[test]
fn bindgen_test_layout_ComplexMatrix2() {
    assert_eq!(
        ::std::mem::size_of::<ComplexMatrix2>(),
        64usize,
        concat!("Size of: ", stringify!(ComplexMatrix2))
    );
    assert_eq!(
        ::std::mem::align_of::<ComplexMatrix2>(),
        8usize,
        concat!("Alignment of ", stringify!(ComplexMatrix2))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrix2>())).real as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrix2),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrix2>())).imag as *const _ as usize },
        32usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrix2),
            "::",
            stringify!(imag)
        )
    );
}
#[doc = " Represents a 4x4 matrix of complex numbers"]
#[doc = ""]
#[doc = " In C, a ::ComplexMatrix4 can be initialised by separately specifying"]
#[doc = " the real and imaginary components as nested arrays. Note that in C99, a short row"]
#[doc = " that ends with a 0 with be padded with 0. \\n"]
#[doc = " For example,"]
#[doc = " ```"]
#[doc = " ComplexMatrix4 m = {"]
#[doc = "      .real = {{1,2, 3, 4},"]
#[doc = "               {0},"]
#[doc = "               {5,6,7,8},"]
#[doc = "               {0}},"]
#[doc = "      .imag = {{0},{0},{0},{1,1,1,1}}};"]
#[doc = " ```"]
#[doc = " specifies matrix"]
#[doc = " \\f["]
#[doc = "   m = \\begin{pmatrix}"]
#[doc = "      1 & 2 & 3 & 4 \\\\"]
#[doc = "      0 & 0 & 0 & 0 \\\\"]
#[doc = "      5 & 6 & 7 & 8 \\\\"]
#[doc = "      i & i & i & i"]
#[doc = "   \\end{pmatrix}"]
#[doc = " \\f]"]
#[doc = ""]
#[doc = " @see"]
#[doc = " - ::ComplexMatrix2"]
#[doc = " - createComplexMatrixN()"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Balint Koczor"]
#[doc = " @author Tyson Jones (doc)"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ComplexMatrix4 {
    pub real: [[f64; 4usize]; 4usize],
    pub imag: [[f64; 4usize]; 4usize],
}
#[test]
fn bindgen_test_layout_ComplexMatrix4() {
    assert_eq!(
        ::std::mem::size_of::<ComplexMatrix4>(),
        256usize,
        concat!("Size of: ", stringify!(ComplexMatrix4))
    );
    assert_eq!(
        ::std::mem::align_of::<ComplexMatrix4>(),
        8usize,
        concat!("Alignment of ", stringify!(ComplexMatrix4))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrix4>())).real as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrix4),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrix4>())).imag as *const _ as usize },
        128usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrix4),
            "::",
            stringify!(imag)
        )
    );
}
#[doc = " Represents a general 2^N by 2^N matrix of complex numbers."]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ComplexMatrixN {
    pub numQubits: ::std::os::raw::c_int,
    pub real: *mut *mut f64,
    pub imag: *mut *mut f64,
}
#[test]
fn bindgen_test_layout_ComplexMatrixN() {
    assert_eq!(
        ::std::mem::size_of::<ComplexMatrixN>(),
        24usize,
        concat!("Size of: ", stringify!(ComplexMatrixN))
    );
    assert_eq!(
        ::std::mem::align_of::<ComplexMatrixN>(),
        8usize,
        concat!("Alignment of ", stringify!(ComplexMatrixN))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrixN>())).numQubits as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrixN),
            "::",
            stringify!(numQubits)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrixN>())).real as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrixN),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<ComplexMatrixN>())).imag as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(ComplexMatrixN),
            "::",
            stringify!(imag)
        )
    );
}
#[doc = " Represents a 3-vector of real numbers"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Ania Brown"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Vector {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}
#[test]
fn bindgen_test_layout_Vector() {
    assert_eq!(
        ::std::mem::size_of::<Vector>(),
        24usize,
        concat!("Size of: ", stringify!(Vector))
    );
    assert_eq!(
        ::std::mem::align_of::<Vector>(),
        8usize,
        concat!("Alignment of ", stringify!(Vector))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Vector>())).x as *const _ as usize },
        0usize,
        concat!("Offset of field: ", stringify!(Vector), "::", stringify!(x))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Vector>())).y as *const _ as usize },
        8usize,
        concat!("Offset of field: ", stringify!(Vector), "::", stringify!(y))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Vector>())).z as *const _ as usize },
        16usize,
        concat!("Offset of field: ", stringify!(Vector), "::", stringify!(z))
    );
}
pub const phaseFunc_NORM: phaseFunc = 0;
pub const phaseFunc_SCALED_NORM: phaseFunc = 1;
pub const phaseFunc_INVERSE_NORM: phaseFunc = 2;
pub const phaseFunc_SCALED_INVERSE_NORM: phaseFunc = 3;
pub const phaseFunc_SCALED_INVERSE_SHIFTED_NORM: phaseFunc = 4;
pub const phaseFunc_PRODUCT: phaseFunc = 5;
pub const phaseFunc_SCALED_PRODUCT: phaseFunc = 6;
pub const phaseFunc_INVERSE_PRODUCT: phaseFunc = 7;
pub const phaseFunc_SCALED_INVERSE_PRODUCT: phaseFunc = 8;
pub const phaseFunc_DISTANCE: phaseFunc = 9;
pub const phaseFunc_SCALED_DISTANCE: phaseFunc = 10;
pub const phaseFunc_INVERSE_DISTANCE: phaseFunc = 11;
pub const phaseFunc_SCALED_INVERSE_DISTANCE: phaseFunc = 12;
pub const phaseFunc_SCALED_INVERSE_SHIFTED_DISTANCE: phaseFunc = 13;
#[doc = " Flags for specifying named phase functions."]
#[doc = " These can be passed to functions applyNamedPhaseFunc(), applyNamedPhaseFuncOverrides(),"]
#[doc = " applyParamNamedPhaseFunc(), and applyParamNamedPhaseFuncOverrides()."]
#[doc = ""]
#[doc = " Norm based phase functions:"]
#[doc = "    - \\p NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\sqrt{x^2 + y^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\text{coeff} \\sqrt{x^2 + y^2 + \\dots}\\f$"]
#[doc = "    - \\p INVERSE_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$1/\\sqrt{x^2 + y^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_INVERSE_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{x^2 + y^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_INVERSE_SHIFTED_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{(x-\\Delta_x)^2 + (y-\\Delta_y)^2 + \\dots}\\f$"]
#[doc = ""]
#[doc = " Product based phase functions:"]
#[doc = "    - \\p PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$x \\; y \\; z \\dots\\f$"]
#[doc = "    - \\p SCALED_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$\\text{coeff} \\; x \\; y \\; z \\dots\\f$"]
#[doc = "    - \\p INVERSE_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$1/(x \\; y \\; z \\dots)\\f$"]
#[doc = "    - \\p SCALED_INVERSE_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$\\text{coeff}/(x \\; y \\; z \\dots)\\f$"]
#[doc = ""]
#[doc = " Euclidean distance based phase functions:"]
#[doc = "    - \\p DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$\\sqrt{(x_1-x_2)^2 + (y_1-y_2)^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$\\text{coeff}\\sqrt{(x_1-x_2)^2 + (y_1-y_2)^2 + \\dots}\\f$"]
#[doc = "    - \\p INVERSE_DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$1/\\sqrt{(x_1-x_2)^2 + (y_1-y_2)^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_INVERSE_DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{(x_1-x_2)^2 + (y_1-y_2)^2 + \\dots}\\f$"]
#[doc = "    - \\p SCALED_INVERSE_SHIFTED_DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{(x_1-x_2-\\Delta_x)^2 + (y_1-y_2-\\Delta_y)^2 + \\dots}\\f$"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
#[doc = " @author Richard Meister (shifted functions)"]
pub type phaseFunc = ::std::os::raw::c_uint;
pub const bitEncoding_UNSIGNED: bitEncoding = 0;
pub const bitEncoding_TWOS_COMPLEMENT: bitEncoding = 1;
#[doc = " Flags for specifying how the bits in sub-register computational basis states"]
#[doc = " are mapped to indices in functions like applyPhaseFunc()."]
#[doc = ""]
#[doc = "    - \\p UNSIGNED means the bits encode an unsigned integer, hence"]
#[doc = " \\f["]
#[doc = " \\begin{aligned}"]
#[doc = "     |00\\rangle & \\rightarrow \\, 0 \\\\"]
#[doc = "     |01\\rangle & \\rightarrow \\, 1 \\\\"]
#[doc = "     |10\\rangle & \\rightarrow \\, 2 \\\\"]
#[doc = "     |11\\rangle & \\rightarrow \\, 3"]
#[doc = " \\end{aligned}"]
#[doc = " \\f]"]
#[doc = "    - \\p TWOS_COMPLEMENT means the bits encode a signed integer through"]
#[doc = "      [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement), such that"]
#[doc = " \\f["]
#[doc = " \\begin{aligned}"]
#[doc = "     |000\\rangle & \\rightarrow \\, 0 \\\\"]
#[doc = "     |001\\rangle & \\rightarrow \\, 1 \\\\"]
#[doc = "     |010\\rangle & \\rightarrow \\, 2 \\\\"]
#[doc = "     |011\\rangle & \\rightarrow \\, 3 \\\\"]
#[doc = "     |100\\rangle & \\rightarrow \\,-4 \\\\"]
#[doc = "     |101\\rangle & \\rightarrow \\,-3 \\\\"]
#[doc = "     |110\\rangle & \\rightarrow \\,-2 \\\\"]
#[doc = "     |111\\rangle & \\rightarrow \\,-1"]
#[doc = " \\end{aligned}"]
#[doc = " \\f]"]
#[doc = " > Remember that the qubits specified within a sub-register, and their ordering (least to most"]
#[doc = " > significant) determine the bits of a computational basis state, before intrepretation"]
#[doc = " > as an encoding of an integer."]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
pub type bitEncoding = ::std::os::raw::c_uint;
#[doc = " A Pauli Hamiltonian, expressed as a real-weighted sum of pauli products,"]
#[doc = " and which can hence represent any Hermitian operator."]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct PauliHamil {
    #[doc = "! The Pauli operators acting on each qubit, flattened over every operator."]
    #[doc = "! This is a flat array of length PauliHamil.numSumTerms * PauliHamil.numQubits."]
    pub pauliCodes: *mut pauliOpType,
    #[doc = "! The real coefficient of each Pauli product. This is an array of length PauliHamil.numSumTerms;"]
    pub termCoeffs: *mut f64,
    #[doc = "! The number of terms in the weighted sum, or the number of Pauli products."]
    pub numSumTerms: ::std::os::raw::c_int,
    #[doc = "! The number of qubits informing the Hilbert dimension of the Hamiltonian."]
    pub numQubits: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_PauliHamil() {
    assert_eq!(
        ::std::mem::size_of::<PauliHamil>(),
        24usize,
        concat!("Size of: ", stringify!(PauliHamil))
    );
    assert_eq!(
        ::std::mem::align_of::<PauliHamil>(),
        8usize,
        concat!("Alignment of ", stringify!(PauliHamil))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<PauliHamil>())).pauliCodes as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(PauliHamil),
            "::",
            stringify!(pauliCodes)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<PauliHamil>())).termCoeffs as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(PauliHamil),
            "::",
            stringify!(termCoeffs)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<PauliHamil>())).numSumTerms as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(PauliHamil),
            "::",
            stringify!(numSumTerms)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<PauliHamil>())).numQubits as *const _ as usize },
        20usize,
        concat!(
            "Offset of field: ",
            stringify!(PauliHamil),
            "::",
            stringify!(numQubits)
        )
    );
}
#[doc = " Represents a diagonal complex operator on the full Hilbert state of a \\p Qureg."]
#[doc = " The operator need not be unitary nor Hermitian (which would constrain it to"]
#[doc = " real values)"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Tyson Jones"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct DiagonalOp {
    #[doc = "! The number of qubits this operator can act on (informing its size)"]
    pub numQubits: ::std::os::raw::c_int,
    #[doc = "! The number of the 2^numQubits amplitudes stored on each distributed node"]
    pub numElemsPerChunk: ::std::os::raw::c_longlong,
    #[doc = "! The number of nodes between which the elements of this operator are split"]
    pub numChunks: ::std::os::raw::c_int,
    #[doc = "! The position of the chunk of the operator held by this process in the full operator"]
    pub chunkId: ::std::os::raw::c_int,
    #[doc = "! The real values of the 2^numQubits complex elements"]
    pub real: *mut f64,
    #[doc = "! The imaginary values of the 2^numQubits complex elements"]
    pub imag: *mut f64,
    #[doc = "! A copy of the elements stored persistently on the GPU"]
    pub deviceOperator: ComplexArray,
}
#[test]
fn bindgen_test_layout_DiagonalOp() {
    assert_eq!(
        ::std::mem::size_of::<DiagonalOp>(),
        56usize,
        concat!("Size of: ", stringify!(DiagonalOp))
    );
    assert_eq!(
        ::std::mem::align_of::<DiagonalOp>(),
        8usize,
        concat!("Alignment of ", stringify!(DiagonalOp))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).numQubits as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(numQubits)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).numElemsPerChunk as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(numElemsPerChunk)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).numChunks as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(numChunks)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).chunkId as *const _ as usize },
        20usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(chunkId)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).real as *const _ as usize },
        24usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(real)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).imag as *const _ as usize },
        32usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(imag)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<DiagonalOp>())).deviceOperator as *const _ as usize },
        40usize,
        concat!(
            "Offset of field: ",
            stringify!(DiagonalOp),
            "::",
            stringify!(deviceOperator)
        )
    );
}
#[doc = " Represents a system of qubits."]
#[doc = " Qubits are zero-based"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Ania Brown"]
#[doc = " @author Tyson Jones (density matrix)"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Qureg {
    #[doc = "! Whether this instance is a density-state representation"]
    pub isDensityMatrix: ::std::os::raw::c_int,
    #[doc = "! The number of qubits represented in either the state-vector or density matrix"]
    pub numQubitsRepresented: ::std::os::raw::c_int,
    #[doc = "! Number of qubits in the state-vector - this is double the number represented for mixed states"]
    pub numQubitsInStateVec: ::std::os::raw::c_int,
    #[doc = "! Number of probability amplitudes held in stateVec by this process"]
    #[doc = "! In the non-MPI version, this is the total number of amplitudes"]
    pub numAmpsPerChunk: ::std::os::raw::c_longlong,
    #[doc = "! Total number of amplitudes, which are possibly distributed among machines"]
    pub numAmpsTotal: ::std::os::raw::c_longlong,
    #[doc = "! The position of the chunk of the state vector held by this process in the full state vector"]
    pub chunkId: ::std::os::raw::c_int,
    #[doc = "! Number of chunks the state vector is broken up into -- the number of MPI processes used"]
    pub numChunks: ::std::os::raw::c_int,
    #[doc = "! Computational state amplitudes - a subset thereof in the MPI version"]
    pub stateVec: ComplexArray,
    #[doc = "! Temporary storage for a chunk of the state vector received from another process in the MPI version"]
    pub pairStateVec: ComplexArray,
    #[doc = "! Storage for wavefunction amplitudes in the GPU version"]
    pub deviceStateVec: ComplexArray,
    #[doc = "! Storage for reduction of probabilities on GPU"]
    pub firstLevelReduction: *mut f64,
    #[doc = "! Storage for reduction of probabilities on GPU"]
    pub secondLevelReduction: *mut f64,
    #[doc = "! Storage for generated QASM output"]
    pub qasmLog: *mut QASMLogger,
}
#[test]
fn bindgen_test_layout_Qureg() {
    assert_eq!(
        ::std::mem::size_of::<Qureg>(),
        112usize,
        concat!("Size of: ", stringify!(Qureg))
    );
    assert_eq!(
        ::std::mem::align_of::<Qureg>(),
        8usize,
        concat!("Alignment of ", stringify!(Qureg))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).isDensityMatrix as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(isDensityMatrix)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).numQubitsRepresented as *const _ as usize },
        4usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(numQubitsRepresented)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).numQubitsInStateVec as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(numQubitsInStateVec)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).numAmpsPerChunk as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(numAmpsPerChunk)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).numAmpsTotal as *const _ as usize },
        24usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(numAmpsTotal)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).chunkId as *const _ as usize },
        32usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(chunkId)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).numChunks as *const _ as usize },
        36usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(numChunks)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).stateVec as *const _ as usize },
        40usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(stateVec)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).pairStateVec as *const _ as usize },
        56usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(pairStateVec)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).deviceStateVec as *const _ as usize },
        72usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(deviceStateVec)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).firstLevelReduction as *const _ as usize },
        88usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(firstLevelReduction)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).secondLevelReduction as *const _ as usize },
        96usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(secondLevelReduction)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<Qureg>())).qasmLog as *const _ as usize },
        104usize,
        concat!(
            "Offset of field: ",
            stringify!(Qureg),
            "::",
            stringify!(qasmLog)
        )
    );
}
#[doc = " Information about the environment the program is running in."]
#[doc = " In practice, this holds info about MPI ranks and helps to hide MPI initialization code"]
#[doc = ""]
#[doc = " @ingroup type"]
#[doc = " @author Ania Brown"]
#[doc = " @author Tyson Jones (seeding)"]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct QuESTEnv {
    pub rank: ::std::os::raw::c_int,
    pub numRanks: ::std::os::raw::c_int,
    pub seeds: *mut ::std::os::raw::c_ulong,
    pub numSeeds: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_QuESTEnv() {
    assert_eq!(
        ::std::mem::size_of::<QuESTEnv>(),
        24usize,
        concat!("Size of: ", stringify!(QuESTEnv))
    );
    assert_eq!(
        ::std::mem::align_of::<QuESTEnv>(),
        8usize,
        concat!("Alignment of ", stringify!(QuESTEnv))
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QuESTEnv>())).rank as *const _ as usize },
        0usize,
        concat!(
            "Offset of field: ",
            stringify!(QuESTEnv),
            "::",
            stringify!(rank)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QuESTEnv>())).numRanks as *const _ as usize },
        4usize,
        concat!(
            "Offset of field: ",
            stringify!(QuESTEnv),
            "::",
            stringify!(numRanks)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QuESTEnv>())).seeds as *const _ as usize },
        8usize,
        concat!(
            "Offset of field: ",
            stringify!(QuESTEnv),
            "::",
            stringify!(seeds)
        )
    );
    assert_eq!(
        unsafe { &(*(::std::ptr::null::<QuESTEnv>())).numSeeds as *const _ as usize },
        16usize,
        concat!(
            "Offset of field: ",
            stringify!(QuESTEnv),
            "::",
            stringify!(numSeeds)
        )
    );
}
extern "C" {
    #[doc = " Creates a state-vector Qureg object representing a set of qubits which will remain in a pure state."]
    #[doc = ""]
    #[doc = " Allocates space for a state-vector of complex amplitudes, which assuming a single"]
    #[doc = " ::qreal floating-point number requires <b>qrealBytes</b>, requires memory"]
    #[doc = " \\f["]
    #[doc = "      \\text{qrealBytes} \\times 2 \\times 2^\\text{numQubits}\\;\\;\\text{(bytes)},"]
    #[doc = " \\f]"]
    #[doc = " though there are additional memory costs in GPU and distributed modes."]
    #[doc = ""]
    #[doc = " The returned ::Qureg begins in the zero state, as produced by initZeroState()."]
    #[doc = ""]
    #[doc = " Once created, the following ::Qureg fields are relevant in all backends:"]
    #[doc = " - Qureg.numQubitsRepresented"]
    #[doc = " - Qureg.isDensityMatrix"]
    #[doc = ""]
    #[doc = " > ::QuESTEnv \\p env must be prior created with createQuESTEnv()."]
    #[doc = ""]
    #[doc = " ### Serial"]
    #[doc = " In serial and local (non-distributed) multithreaded modes, a state-vector \\p Qureg"]
    #[doc = " costs only the memory above. For example, at double precision"]
    #[doc = " (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:"]
    #[doc = " \\p numQubits  | memory"]
    #[doc = " ------------- | -------------"]
    #[doc = " 10            | 16 KiB"]
    #[doc = " 16            | 1 MiB"]
    #[doc = " 20            | 16 MiB"]
    #[doc = " 26            | 1 GiB"]
    #[doc = " 30            | 16 GiB"]
    #[doc = ""]
    #[doc = " Individual amplitudes should be fetched and modified with functions like getAmp() and setAmps()."]
    #[doc = " However, it is sometimes useful to access the state-vector directly, for example to"]
    #[doc = " create your own low-level (high performance) multithreaded functions."]
    #[doc = " In those instants, Qureg.stateVec can be accessed directly, storing the real"]
    #[doc = " and imaginary components of the state-vector amplitudes in:"]
    #[doc = " - `Qureg.stateVec.real`"]
    #[doc = " - `Qureg.stateVec.imag`"]
    #[doc = ""]
    #[doc = " The total number of amplitudes in the state-vector is"]
    #[doc = " - Qureg.numAmpsTotal"]
    #[doc = ""]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = " Qureg qureg = createQureg(10, env);"]
    #[doc = ""]
    #[doc = " // ruin a perfectly good state-vector"]
    #[doc = " for (long long int i=0; i<qureg.numAmpsTotal; i++) {"]
    #[doc = "     qureg.stateVec.real[i] = rand();"]
    #[doc = "     qureg.stateVec.imag[i] = rand();"]
    #[doc = " }"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " ### GPU"]
    #[doc = ""]
    #[doc = " In GPU-accelerated mode, an <em>additional</em> state-vector is created in GPU memory."]
    #[doc = " Therefore both RAM and VRAM must be of sufficient memory to store the state-vector,"]
    #[doc = " each of the size indicated in the Serial table above."]
    #[doc = ""]
    #[doc = " > Note that many GPUs do not support quad precision ::qreal."]
    #[doc = ""]
    #[doc = " Individual amplitudes of the created ::Qureg should be fetched and modified with functions like getAmp() and setAmps()."]
    #[doc = " This is especially important since the GPU state-vector can be accessed directly,"]
    #[doc = " and changes to Qureg.stateVec will be ignored and overwritten."]
    #[doc = " To modify the state-vector \"directly\", one must use copyStateFromGPU() and"]
    #[doc = " copyStateToGPU() before and after."]
    #[doc = ""]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = " Qureg qureg = createQureg(10, env);"]
    #[doc = ""]
    #[doc = " // ruin a perfectly good state-vector"]
    #[doc = " for (long long int i=0; i<qureg.numAmpsTotal; i++) {"]
    #[doc = "     qureg.stateVec.real[i] = rand();"]
    #[doc = "     qureg.stateVec.imag[i] = rand();"]
    #[doc = " }"]
    #[doc = " copyStateToGPU();"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " ### Distributed"]
    #[doc = ""]
    #[doc = " In distributed mode, the state-vector is uniformly partitioned between the <b>N</b>"]
    #[doc = " distributed nodes."]
    #[doc = ""]
    #[doc = " > Only a power-of-2 number of nodes <b>N</b> may be used (e.g. <b>N = 1, 2, 4, 8, </b>...)."]
    #[doc = " > There must additionally be at least 1 amplitude of a state-vector stored on each node."]
    #[doc = " > This means one cannot create a state-vector ::Qureg with fewer than \\f$\\log_2(\\text{N})\\f$ qubits."]
    #[doc = ""]
    #[doc = " In addition to Qureg.stateVec, additional memory is allocated on each node for"]
    #[doc = " communication buffers, of size equal to the state-vector partition."]
    #[doc = " Hence the total memory <em>per-node</em> required is:"]
    #[doc = " \\f["]
    #[doc = "      2 \\times \\text{qrealBytes} \\times 2 \\times 2^\\text{numQubits}/N  \\;\\;\\text{(bytes)},"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " For example, at double precision"]
    #[doc = " (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:"]
    #[doc = ""]
    #[doc = " | \\p numQubits | memory per node  |||||"]
    #[doc = " |-------------|-------|-------|-------|--------| ------ |"]
    #[doc = " |            | <b>N = 2</b>  | <b>N = 4</b> | <b>N = 8</b> | <b>N = 16</b> | <b>N = 32</b> |"]
    #[doc = " | 10            | 16 KiB | 8 KiB | 4 KiB | 2 KiB  | 1 KiB  |"]
    #[doc = " | 20           | 16 MiB | 8 MiB | 4 MiB | 2 MiB  | 1 MiB  |"]
    #[doc = " | 30           | 16 GiB | 8 GiB | 4 GiB | 2 GiB  | 1 GiB  |"]
    #[doc = " | 40           | 16 TiB | 8 TiB | 4 TiB | 2 TiB  | 1 TiB  |"]
    #[doc = ""]
    #[doc = " State-vector amplitudes should be set and modified using getAmp() and setAmps()."]
    #[doc = " Direct modification is possible, but should be done extremely carefully, since"]
    #[doc = " each node only stores a <em>partition</em> of the full state-vector, which itself"]
    #[doc = " mightn't fit on any single node. Furthermore, an asynchronous MPI process may"]
    #[doc = " may unexpectedly modify local amplitudes; avoid this with syncQuESTEnv()."]
    #[doc = ""]
    #[doc = " The fields relevant to distribution are:"]
    #[doc = ""]
    #[doc = " - Qureg.numAmpsPerChunk: the length of Qureg.stateVec (`.real` and `.imag`) on each node."]
    #[doc = " - Qureg.chunkId: the id of the node, from <b>0</b> to <b>N-1</b>."]
    #[doc = ""]
    #[doc = " Therefore, this code is valid"]
    #[doc = " ```"]
    #[doc = "syncQuESTEnv(env);"]
    #[doc = " // set state |i> to have amplitude i"]
    #[doc = " for (long long int i=0; i<qureg.numAmpsPerChunk; i++)"]
    #[doc = "     qureg.stateVec.real[i] = i + qureg.chunkId * qureg.numAmpsPerChunk;"]
    #[doc = " ```"]
    #[doc = " while the following erroneous code would cause a segmentation fault:"]
    #[doc = " ```"]
    #[doc = " // incorrectly attempt to set state |i> to have amplitude i"]
    #[doc = " for (long long int i=0; i<qureg.numAmpsTotal; i++)"]
    #[doc = "     qureg.stateVec.real[i] = i;"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDensityQureg() to create a density matrix of the equivalent number of qubits, which can enter noisy states."]
    #[doc = " - createCloneQureg() to create a new qureg of the size and state of an existing qureg."]
    #[doc = " - destroyQureg() to free the allocated ::Qureg memory."]
    #[doc = " - reportQuregParams() to print information about a ::Qureg."]
    #[doc = " - copyStateFromGPU() and copyStateToGPU() for directly modifying state-vectors in GPU mode."]
    #[doc = " - syncQuESTEnv() for directly modifying state-vectors in distributed mode."]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @returns an object representing the set of qubits"]
    #[doc = " @param[in] numQubits number of qubits in the system"]
    #[doc = " @param[in] env object representing the execution environment (local, multinode etc)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if \\p numQubits is so large that the number of amplitudes cannot fit in a long long int type,"]
    #[doc = " - if in distributed mode, there are more nodes than elements in the would-be state-vector"]
    #[doc = " @throws exit"]
    #[doc = " - if in GPU mode, but GPU memory cannot be allocated."]
    #[doc = " @author Ania Brown"]
    #[doc = " @author Tyson Jones (validation, doc)"]
    pub fn createQureg(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> Qureg;
}
extern "C" {
    #[doc = " Creates a density matrix Qureg object representing a set of qubits which"]
    #[doc = " can enter noisy and mixed states."]
    #[doc = ""]
    #[doc = " Allocates space for a matrix of complex amplitudes, which assuming a single"]
    #[doc = " ::qreal floating-point number requires <b>qrealBytes</b>, requires memory"]
    #[doc = " \\f["]
    #[doc = "      \\text{qrealBytes} \\times 2 \\times 2^{2 \\times\\text{numQubits}}\\;\\;\\text{(bytes)},"]
    #[doc = " \\f]"]
    #[doc = " though there are additional memory costs in GPU and distributed modes."]
    #[doc = " Notice this is the memory cost of a state-vector created with createQureg()"]
    #[doc = " of twice as many qubits."]
    #[doc = ""]
    #[doc = " The returned ::Qureg begins in the zero state, as produced by initZeroState()."]
    #[doc = ""]
    #[doc = " Once created, the following ::Qureg fields are relevant in all backends:"]
    #[doc = " - Qureg.numQubitsRepresented"]
    #[doc = " - Qureg.isDensityMatrix"]
    #[doc = ""]
    #[doc = " Behind the scenes, density matrice are stored as state-vectors, flattened column-wise."]
    #[doc = " As such, individual amplitudes should be fetched with getDensityAmp(), in lieu"]
    #[doc = " of direct access."]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = " > ::QuESTEnv \\p env must be prior created with createQuESTEnv()."]
    #[doc = ""]
    #[doc = " ### Serial"]
    #[doc = " In serial and local (non-distributed) multithreaded modes, a density matrix \\p Qureg"]
    #[doc = " costs only the memory above. For example, at double precision"]
    #[doc = " (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:"]
    #[doc = " \\p numQubits  | memory"]
    #[doc = " ------------- | -------------"]
    #[doc = " 10            | 16 MiB"]
    #[doc = " 12            | 256 MiB"]
    #[doc = " 14            | 4 GiB"]
    #[doc = " 16            | 64 GiB"]
    #[doc = " 18            | 1 TiB"]
    #[doc = " 20            | 16 TiB"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " ### GPU"]
    #[doc = ""]
    #[doc = " In GPU-accelerated mode, an <em>additional</em> density matrix is created in GPU memory."]
    #[doc = " Therefore both RAM and VRAM must be of sufficient memory to store the state-vector,"]
    #[doc = " each of the size indicated in the Serial table above."]
    #[doc = ""]
    #[doc = " > Note that many GPUs do not support quad precision ::qreal."]
    #[doc = ""]
    #[doc = " ### Distributed"]
    #[doc = ""]
    #[doc = " In distributed mode, the density matrix is uniformly partitioned between the <b>N</b>"]
    #[doc = " distributed nodes (column-wise)."]
    #[doc = ""]
    #[doc = " > Only a power-of-2 number of nodes <b>N</b> may be used (e.g. <b>N = 1, 2, 4, 8, </b>...)."]
    #[doc = " > There must additionally be at least 1 amplitude of a density matrix stored on each node."]
    #[doc = " > This means one cannot create a density matrix ::Qureg with fewer than \\f$\\log_2(\\text{N})/2\\f$ qubits."]
    #[doc = ""]
    #[doc = " Additional memory is allocated on each node for communication buffers, of size"]
    #[doc = " equal to the density matrix partition."]
    #[doc = " Hence the total memory <em>per-node</em> required is:"]
    #[doc = " \\f["]
    #[doc = "      2 \\times \\text{qrealBytes} \\times 2 \\times 2^{2\\times\\text{numQubits}}/N  \\;\\;\\text{(bytes)},"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " For example, at double precision"]
    #[doc = " (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:"]
    #[doc = ""]
    #[doc = " | \\p numQubits | memory per node  |||||"]
    #[doc = " |-------------|-------|-------|-------|--------| ------ |"]
    #[doc = " |            | <b>N = 2</b>  | <b>N = 4</b> | <b>N = 8</b> | <b>N = 16</b> | <b>N = 32</b> |"]
    #[doc = " | 10           | 16 MiB | 8 MiB | 4 MiB | 2 MiB  | 1 MiB  |"]
    #[doc = " | 15           | 16 GiB | 8 GiB | 4 GiB | 2 GiB  | 1 GiB  |"]
    #[doc = " | 20           | 16 TiB | 8 TiB | 4 TiB | 2 TiB  | 1 TiB  |"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createQureg() to create a state-vector of the equivalent number of qubits, with a square-root memory cost"]
    #[doc = " - createCloneQureg() to create a new qureg of the size and state of an existing qureg."]
    #[doc = " - destroyQureg() to free the allocated \\p Qureg memory."]
    #[doc = " - reportQuregParams() to print information about a ::Qureg."]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @returns an object representing the set of qubits"]
    #[doc = " @param[in] numQubits number of qubits in the system"]
    #[doc = " @param[in] env object representing the execution environment (local, multinode etc)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if \\p numQubits is so large that the number of amplitudes cannot fit in a long long int type,"]
    #[doc = " - if in distributed mode, there are more nodes than elements in the would-be state-vector"]
    #[doc = " @throws exit"]
    #[doc = " - if in GPU mode, but GPU memory cannot be allocated."]
    #[doc = " @author Tyson Jones"]
    pub fn createDensityQureg(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> Qureg;
}
extern "C" {
    #[doc = " Create a new ::Qureg which is an exact clone of the passed qureg, which can be"]
    #[doc = " either a state-vector or a density matrix."]
    #[doc = ""]
    #[doc = " The returned \\ref Qureg will have the same"]
    #[doc = " dimensions as the passed \\p qureg and begin in an identical quantum state."]
    #[doc = " This must be destroyed by the user later with destroyQureg()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - destroyQureg()"]
    #[doc = " - cloneQureg()"]
    #[doc = " - createQureg()"]
    #[doc = " - createDensityQureg()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @returns an object representing the set of qubits"]
    #[doc = " @param[in] qureg an existing \\ref Qureg to be cloned"]
    #[doc = " @param[in] env the ::QuESTEnv"]
    #[doc = " @author Tyson Jones"]
    pub fn createCloneQureg(qureg: Qureg, env: QuESTEnv) -> Qureg;
}
extern "C" {
    #[doc = " Deallocate a ::Qureg, freeing its memory."]
    #[doc = ""]
    #[doc = " This frees all memory bound to \\p qureg, including its state-vector or"]
    #[doc = " density matrix in RAM, in VRAM (in GPU mode), and communication buffers"]
    #[doc = " (in distributed mode)."]
    #[doc = ""]
    #[doc = " The \\p qureg must have been previously created with createQureg(),"]
    #[doc = " createDensityQureg() or createCloneQureg()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createQureg()"]
    #[doc = " - createDensityQureg()"]
    #[doc = " - createCloneQureg()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in,out] qureg the ::Qureg to be destroyed"]
    #[doc = " @param[in] env the ::QuESTEnv"]
    #[doc = " @author Ania Brown"]
    #[doc = " @author Tyson Jones (improved doc)"]
    pub fn destroyQureg(qureg: Qureg, env: QuESTEnv);
}
extern "C" {
    #[doc = " Allocate dynamic memory for a square complex matrix of any size,"]
    #[doc = " which can be passed to functions like multiQubitUnitary() and applyMatrixN()."]
    #[doc = ""]
    #[doc = " The returned matrix will have dimensions"]
    #[doc = " \\f["]
    #[doc = "      2^{\\text{numQubits}} \\times 2^{\\text{numQubits}},"]
    #[doc = " \\f]"]
    #[doc = " stored as nested arrays ComplexMatrixN.real and ComplexMatrixN.imag,"]
    #[doc = " initialised to zero."]
    #[doc = ""]
    #[doc = " Unlike a ::Qureg, the memory of a ::ComplexMatrixN is always stored in RAM,"]
    #[doc = " and non-distributed. Hence, elements can be directly accessed and modified:"]
    #[doc = " ```"]
    #[doc = " int numQubits = 5;"]
    #[doc = " int dim = (1 << numQubits);"]
    #[doc = " ComplexMatrixN m = createComplexMatrixN(numQubits);"]
    #[doc = ""]
    #[doc = " for (int r=0; r<dim; r++) {"]
    #[doc = "     for (int c=0; c<dim; c++) {"]
    #[doc = "         m.real[r][c] = rand();"]
    #[doc = "         m.imag[r][c] = rand();"]
    #[doc = "     }"]
    #[doc = " }"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = " A ::ComplexMatrixN can be initialised in bulk using initComplexMatrixN(),"]
    #[doc = " though this is not C++ compatible."]
    #[doc = ""]
    #[doc = " Like ::ComplexMatrix2 and ::ComplexMatrix4 (which are incidentally stored in the stack),"]
    #[doc = " the returned ::ComplexMatrixN is safe to return from functions."]
    #[doc = ""]
    #[doc = " > The ::ComplexMatrixN must eventually be freed using destroyComplexMatrixN(),"]
    #[doc = " > since it is created in the dynamic heap. One can instead use getStaticComplexMatrixN()"]
    #[doc = " > to create a ComplexMatrixN struct in the stack (which doesn't need to be later destroyed),"]
    #[doc = " > though this may cause a stack overflow if the matrix is too large (approx 10+ qubits)."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - destroyComplexMatrixN()"]
    #[doc = " - getStaticComplexMatrixN()"]
    #[doc = " - initComplexMatrixN()"]
    #[doc = " - applyMatrixN()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - mixMultiQubitKrausMap()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] numQubits the number of qubits of which the returned ComplexMatrixN will correspond"]
    #[doc = " @returns a dynamic ComplexMatrixN struct, that is one where the .real and .imag"]
    #[doc = "  fields are arrays kept in the heap and must be later destroyed."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if the memory was not allocated successfully"]
    #[doc = " @author Tyson Jones"]
    pub fn createComplexMatrixN(numQubits: ::std::os::raw::c_int) -> ComplexMatrixN;
}
extern "C" {
    #[doc = " Destroy a ComplexMatrixN instance created with createComplexMatrixN()"]
    #[doc = ""]
    #[doc = " It is invalid to attempt to destroy a matrix created with getStaticComplexMatrixN()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getStaticComplexMatrixN()"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] matr the dynamic matrix (created with createComplexMatrixN()) to deallocate"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p matr was not yet allocated."]
    #[doc = " @throws malloc_error"]
    #[doc = " -  if \\p matr was static (created with getStaticComplexMatrixN())"]
    #[doc = " @author Tyson Jones"]
    pub fn destroyComplexMatrixN(matr: ComplexMatrixN);
}
extern "C" {
    #[doc = " Initialises a ComplexMatrixN instance to have the passed"]
    #[doc = " \\p real and \\p imag values. This allows succint population of any-sized"]
    #[doc = " ComplexMatrixN, e.g. through 2D arrays:"]
    #[doc = ""]
    #[doc = "     ComplexMatrixN m = createComplexMatrixN(3);"]
    #[doc = "     initComplexMatrixN(m,"]
    #[doc = "         (qreal[8][8]) {{1,2,3,4,5,6,7,8}, {0}},"]
    #[doc = "         (qreal[8][8]) {{0}});"]
    #[doc = ""]
    #[doc = " \\p m can be created by either createComplexMatrixN() or getStaticComplexMatrixN()."]
    #[doc = ""]
    #[doc = " This function is only callable in C, since C++ signatures cannot"]
    #[doc = " contain variable-length 2D arrays"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] m the matrix to initialise"]
    #[doc = " @param[in] real matrix of real values; can be 2D array of array of pointers"]
    #[doc = " @param[in] imag matrix of imaginary values; can be 2D array of array of pointers"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p m has not been allocated (e.g. with createComplexMatrixN())"]
    #[doc = " @author Tyson Jones"]
    pub fn initComplexMatrixN(m: ComplexMatrixN, real: *mut *mut f64, imag: *mut *mut f64);
}
extern "C" {
    #[doc = " Dynamically allocates a Hamiltonian expressed as a real-weighted sum of products of Pauli operators."]
    #[doc = ""]
    #[doc = " A ::PauliHamil is merely an encapsulation of the multiple parameters of functions"]
    #[doc = " like applyPauliSum()."]
    #[doc = ""]
    #[doc = " The Pauli operators (PauliHamil.pauliCodes) are all initialised to identity"]
    #[doc = " (::PAULI_I), but the coefficients (PauliHamil.termCoeffs) are not initialised."]
    #[doc = ""]
    #[doc = " The Hamiltonian can be used in functions like applyPauliHamil() and applyTrotterCircuit(),"]
    #[doc = " with \\p Qureg instances of the same number of qubits."]
    #[doc = ""]
    #[doc = " A ::PauliHamil can be modified directly (see ::PauliHamil), or through initPauliHamil()."]
    #[doc = " It can furthermore be created and initialised from a file description directly with"]
    #[doc = " createPauliHamilFromFile()."]
    #[doc = ""]
    #[doc = " > The returned dynamic \\p PauliHamil instance must later be freed via destroyPauliHamil()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createPauliHamilFromFile()"]
    #[doc = " - createDiagonalOpFromPauliHamilFile()"]
    #[doc = " - initPauliHamil()"]
    #[doc = " - destroyPauliHamil()"]
    #[doc = " - applyPauliSum()"]
    #[doc = " - applyTrotterCircuit()"]
    #[doc = " - calcExpecPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] numQubits the number of qubits on which this Hamiltonian acts"]
    #[doc = " @param[in] numSumTerms the number of weighted terms in the sum, or the number of Pauli products"]
    #[doc = " @returns a dynamic \\p PauliHamil struct, with fields \\p pauliCodes and \\p termCoeffs stored in the heap"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if \\p numSumTerms <= 0"]
    #[doc = " @author Tyson Jones"]
    pub fn createPauliHamil(
        numQubits: ::std::os::raw::c_int,
        numSumTerms: ::std::os::raw::c_int,
    ) -> PauliHamil;
}
extern "C" {
    #[doc = " Destroy a ::PauliHamil instance, created with either createPauliHamil() or createPauliHamilFromFile()."]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] hamil a dynamic \\p PauliHamil instantiation"]
    #[doc = " @author Tyson Jones"]
    pub fn destroyPauliHamil(hamil: PauliHamil);
}
extern "C" {
    #[doc = " Creates a \\p PauliHamil instance, a real-weighted sum of products of Pauli operators,"]
    #[doc = " populated with the data in filename \\p fn."]
    #[doc = ""]
    #[doc = " Each line in the plaintext file is interpreted as a separate product of Pauli operators"]
    #[doc = " in the total sum."]
    #[doc = " Each line must be a space-separated list with format"]
    #[doc = ""]
    #[doc = "     c p1 p2 p3 ... pN"]
    #[doc = ""]
    #[doc = " where \\p c is the real coefficient of the term, and \\p p1 ... \\p pN are"]
    #[doc = " numbers in <b>{0,1,2,3}</b> to indicate ::PAULI_I, ::PAULI_X, ::PAULI_Y, ::PAULI_Z"]
    #[doc = " operators respectively, which act on qubits \\p 0 through \\p N-1 (all qubits)."]
    #[doc = ""]
    #[doc = " For example, the file containing"]
    #[doc = ""]
    #[doc = "     0.31 1 0 1 2"]
    #[doc = "     -0.2 3 2 0 0"]
    #[doc = ""]
    #[doc = " encodes a two-term four-qubit Hamiltonian"]
    #[doc = " \\f["]
    #[doc = "      0.31 \\, X_0 \\, X_2 \\, Y_3 -0.2 \\, Z_0 \\, Y_1 \\,."]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " The initialised ::PauliHamil can be previewed with reportPauliHamil()."]
    #[doc = ""]
    #[doc = " The number of qubits and terms are inferred from the file."]
    #[doc = " The created Hamiltonian can be used just like one created via createPauliHamil()."]
    #[doc = " It can be modified directly (see ::PauliHamil), or through initPauliHamil()."]
    #[doc = ""]
    #[doc = " > The returned dynamic \\p PauliHamil instance must later be freed via destroyPauliHamil()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - reportPauliHamil()"]
    #[doc = " - destroyPauliHamil()"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - initPauliHamil()"]
    #[doc = " - createDiagonalOpFromPauliHamilFile()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] fn filename of the plaintext file specifying the pauli operators and coefficients"]
    #[doc = " @returns a dynamic ::PauliHamil struct"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if the file with name \\p fn cannot be read"]
    #[doc = " - if the file is not correctly formatted as described above"]
    #[doc = " @author Tyson Jones"]
    pub fn createPauliHamilFromFile(fn_: *mut ::std::os::raw::c_char) -> PauliHamil;
}
extern "C" {
    #[doc = " Initialise ::PauliHamil instance \\p hamil with the given term coefficients and"]
    #[doc = " Pauli codes (one for every qubit in every term)."]
    #[doc = ""]
    #[doc = " Arguments \\p coeffs and \\p codes encode a weighted sum of Pauli operators, with the same"]
    #[doc = " format as other QuEST functions (like calcExpecPauliSum())."]
    #[doc = ""]
    #[doc = " This is useful to set the elements of the ::PauliHamil in batch. \\n"]
    #[doc = " For example"]
    #[doc = " ```"]
    #[doc = " int numQubits = 3;"]
    #[doc = " int numTerms = 2;"]
    #[doc = " PauliHamil hamil = createPauliHamil(numQubits, numTerms);"]
    #[doc = ""]
    #[doc = " // hamil = 0.5 X0 Y1 - 0.5 Z1 X3"]
    #[doc = " initPauliHamil(hamil,"]
    #[doc = "     (qreal[]) {0.5, -0.5},"]
    #[doc = "     (enum pauliOpType[]) {PAULI_X,PAULI_Y,PAULI_I, PAULI_I, PAULI_Z, PAULI_X});"]
    #[doc = " ```"]
    #[doc = ""]
    #[doc = " The initialised ::PauliHamil can be previewed with reportPauliHamil()."]
    #[doc = ""]
    #[doc = " > \\p hamil must be already created with createPauliHamil(), or createPauliHamilFromFile()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - reportPauliHamil()"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - createPauliHamilFromFile()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in, out] hamil an existing ::PauliHamil instance to be modified"]
    #[doc = " @param[in] coeffs an array of sum term coefficients, which must have length `hamil.numSumTerms`"]
    #[doc = " @param[in] codes a flat array of Pauli codes, of length `hamil.numSumTerms`*`hamil.numQubits`"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p hamil has invalid parameters (\\p numQubits <= 0, \\p numSumTerms <= 0)"]
    #[doc = " - if any code in \\p codes is not a valid Pauli code (::pauliOpType)"]
    #[doc = " @author Tyson Jones"]
    pub fn initPauliHamil(hamil: PauliHamil, coeffs: *mut f64, codes: *mut pauliOpType);
}
extern "C" {
    #[doc = " Creates a ::DiagonalOp representing a diagonal operator on the"]
    #[doc = " full Hilbert space of a ::Qureg."]
    #[doc = ""]
    #[doc = " The resulting operator need not be unitary nor Hermitian, and can be"]
    #[doc = " applied to any ::Qureg of a compatible number of qubits."]
    #[doc = ""]
    #[doc = " This function allocates space for \\f$2^{\\text{numQubits}}\\f$ complex amplitudes,"]
    #[doc = " which are initially zero. This is the same cost as a local state-vector of equal"]
    #[doc = " number of qubits; see the Serial section of createQureg()."]
    #[doc = " Note that this is a <em>paralell</em> data-type, so its"]
    #[doc = " ultimate memory costs depend on the hardware backends, as elaborated below."]
    #[doc = ""]
    #[doc = " The operator elements should be modified with initDiagonalOp() and setDiagonalOpElems(),"]
    #[doc = " and must be later freed with destroyDiagonalOp()."]
    #[doc = ""]
    #[doc = " ### GPU"]
    #[doc = ""]
    #[doc = " In GPU-accelerated mode, this function also creates additional equally-sized"]
    #[doc = " persistent memory on the GPU."]
    #[doc = " If you wish to modify the operator elements directly (in lieu of setDiagonalOpElems()),"]
    #[doc = " you must thereafter call syncDiagonalOp() to update the operator stored in VRAM."]
    #[doc = ""]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = " DiagonalOp op = createDiagonalOp(4, env);"]
    #[doc = " for (long long int i=0; i<op.numElemsPerChunk; i++) {"]
    #[doc = "     op.real[i] = rand();"]
    #[doc = "     op.imag[i] = rand();"]
    #[doc = " }"]
    #[doc = " syncDiagonalOp(op);"]
    #[doc = " ```"]
    #[doc = ""]
    #[doc = " ### Distribution"]
    #[doc = ""]
    #[doc = " In distributed mode, the memory for the diagonal operator is divided evenly"]
    #[doc = " between the \\f$N\\f$ available nodes, such that each node contains only"]
    #[doc = " \\f$2^{\\text{numQubits}}/N\\f$ complex values. This is assigned to"]
    #[doc = " DiagonalOp.numElemsPerChunk."]
    #[doc = ""]
    #[doc = " Users must therefore exercise care in modifying DiagonalOp.real and DiagonalOp.imag"]
    #[doc = " directly."]
    #[doc = ""]
    #[doc = " For example, the following is valid code when when distributed between <b>N = 2</b> nodes:"]
    #[doc = " ```"]
    #[doc = "      // create diag({1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16})"]
    #[doc = "      int numQubits = 4;"]
    #[doc = "      DiagonalOp op = createDiagonalOp(numQubits4, env);"]
    #[doc = "      for (int i=0; i<8; i++) {"]
    #[doc = "          if (env.rank == 0)"]
    #[doc = "              op.real[i] = (i+1);"]
    #[doc = "          if (env.rank == 1)"]
    #[doc = "              op.real[i] = (i+1+8);"]
    #[doc = "      }"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDiagonalOpFromPauliHamilFile()"]
    #[doc = " - setDiagonalOpElems()"]
    #[doc = " - initDiagonalOp()"]
    #[doc = " - syncDiagonalOp()"]
    #[doc = " - applyDiagonalOp()"]
    #[doc = " - calcExpecDiagonalOp()"]
    #[doc = " - destroyDiagonalOp()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @returns a dynamic DiagonalOp instance initialised to diag(0,0,...)."]
    #[doc = " @param[in] numQubits number of qubits which inform the Hilbert dimension of the operator."]
    #[doc = " @param[in] env the ::QuESTEnv"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if \\p numQubits is so large that the number of elements cannot fit in a long long int type,"]
    #[doc = " - if in distributed mode, there are more nodes than elements in the operator"]
    #[doc = " @throws exit"]
    #[doc = " - if the memory could not be allocated"]
    #[doc = " @author Tyson Jones"]
    pub fn createDiagonalOp(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> DiagonalOp;
}
extern "C" {
    #[doc = " Destroys a ::DiagonalOp created with createDiagonalOp(), freeing its memory."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDiagonalOp()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] op the ::DiagonalOp to destroy"]
    #[doc = " @param[in] env the ::QuESTEnv"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p op was not previously created"]
    #[doc = " @author Tyson Jones"]
    pub fn destroyDiagonalOp(op: DiagonalOp, env: QuESTEnv);
}
extern "C" {
    #[doc = " Overwrites the entire ::DiagonalOp \\p op with the given \\p real and \\p imag"]
    #[doc = " complex elements."]
    #[doc = ""]
    #[doc = " Both \\p real and \\p imag must have length equal to <b>pow(2, </b>`op.numQubits`<b>)</b>."]
    #[doc = ""]
    #[doc = " In GPU mode, this updates both the RAM (\\p op.real and \\p op.imag) <em>and</em>"]
    #[doc = " persistent GPU memory; there is no need to call syncDiagonalOp() afterward."]
    #[doc = ""]
    #[doc = " In distributed mode, this function assumes \\p real and \\p imag exist fully on every"]
    #[doc = " node. For ::DiagonalOp which are too large to fit into a single node, use"]
    #[doc = " setDiagonalOpElems() or syncDiagonalOp()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - setDiagonalOpElems()"]
    #[doc = " - initDiagonalOpFromPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in,out] op the diagonal operator to modify"]
    #[doc = " @param[in] real the real components of the full set of new elements"]
    #[doc = " @param[in] imag the imaginary components of the full set of new elements"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p op was not created"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if either \\p real or \\p imag have length smaller than <b>pow(2, </b>`op.numQubits`<b>)</b>"]
    #[doc = " @author Tyson Jones"]
    pub fn initDiagonalOp(op: DiagonalOp, real: *mut f64, imag: *mut f64);
}
extern "C" {
    #[doc = " Populates the diagonal operator \\p op to be equivalent to the given Pauli"]
    #[doc = " Hamiltonian \\p hamil, assuming \\p hamil contains only `PAULI_Z` operators."]
    #[doc = ""]
    #[doc = " Given a ::PauliHamil \\p hamil featuring only `PAULI_Z` and `PAULI_I`, with"]
    #[doc = " term coefficients \\f$\\{\\lambda_j\\}\\f$, which"]
    #[doc = " hence has form"]
    #[doc = " \\f["]
    #[doc = "      \\begin{aligned}"]
    #[doc = "      \\text{hamil} &= \\sum\\limits_j^{\\text{numSumTerms}} \\lambda_j"]
    #[doc = "                      \\bigotimes\\limits_{k_j} \\hat{Z}_k \\\\"]
    #[doc = "      &\\equiv \\begin{pmatrix}"]
    #[doc = "              r_1 \\\\ & r_2 \\\\ & & r_3 \\\\ & & & \\ddots \\\\ & & & & r_{2^{\\,\\text{numQubits}}}"]
    #[doc = "          \\end{pmatrix},"]
    #[doc = "      \\end{aligned}"]
    #[doc = " \\f]"]
    #[doc = " this function modifies \\p op to"]
    #[doc = " \\f["]
    #[doc = "      \\text{op} \\; \\rightarrow \\; \\text{diag}"]
    #[doc = "          \\big( \\; r_1, \\; r_2, \\; r_3, \\; \\dots, \\; r_{2^{\\,\\text{numQubits}}} \\, \\big),"]
    #[doc = " \\f]"]
    #[doc = " where the real amplitudes have form"]
    #[doc = " \\f["]
    #[doc = "       r_i = \\sum\\limits_j \\, s_{ij} \\, \\lambda_j, \\;\\;\\;\\; s_{ij} = \\pm  1 \\,."]
    #[doc = " \\f]"]
    #[doc = " This is useful since calculations with ::DiagonalOp are significantly faster than"]
    #[doc = " the equivalent calculations with a general ::PauliHamil. For example,"]
    #[doc = " applyDiagonalOp() requires a factor `numSumTerms * numQubits` fewer operations"]
    #[doc = " than applyPauliHamil()."]
    #[doc = ""]
    #[doc = " > In distributed mode, each node will contain only a sub-partition of the full diagonal matrix."]
    #[doc = " > In GPU mode, both the CPU and GPU memory copies of \\p op will be updated, so there"]
    #[doc = " > is no need to call syncDiagonalOp() afterward."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDiagonalOp()"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - createDiagonalOpFromPauliHamilFile()"]
    #[doc = " - initDiagonalOp()"]
    #[doc = " - setDiagonalOpElems()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in,out] op an existing ::DiagonalOp (e.g. created with createDiagonalOp()) to modify"]
    #[doc = " @param[in] hamil a ::PauliHamil of equal dimension to \\p op, containing only `PAULI_Z` and `PAULI_I` operators"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p hamil has invalid parameters (\\p numQubits <= 0, \\p numSumTerms <= 0)"]
    #[doc = " - if \\p op and \\p hamil have unequal dimensions"]
    #[doc = " - if \\p hamil contains any operator other than `PAULI_Z` and `PAULI_I`"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if either \\p op or \\p hamil have not been already created"]
    #[doc = " @author Tyson Jones"]
    #[doc = " @author Milos Prokop (serial prototype)"]
    pub fn initDiagonalOpFromPauliHamil(op: DiagonalOp, hamil: PauliHamil);
}
extern "C" {
    #[doc = " Creates and initialiases a diagonal operator from the Z Pauli Hamiltonian encoded in"]
    #[doc = " file with filename \\p fn."]
    #[doc = ""]
    #[doc = " This is a convenience function to prepare a diagonal operator from a plaintext"]
    #[doc = " description of an all-Z Pauli Hamiltonian. The returned ::DiagonalOp is a"]
    #[doc = " distributed data structure, and significantly faster to use (through functions"]
    #[doc = " like calcExpecDiagonalOp()) than ::PauliHamil functions (like calcExpecPauliHamil())."]
    #[doc = ""]
    #[doc = " - See createDiagonalOp() for info about the returned operator."]
    #[doc = " - See initDiagonalOpFromPauliHamil() for info about the initialised state."]
    #[doc = " - See createPauliHamilFromFile() for info about the required file format."]
    #[doc = ""]
    #[doc = " > The returned ::DiagonalOp must be later freed with destroyDiagonalOp()."]
    #[doc = " > Note a ::PauliHamil from \\p fn is temporarily internally created."]
    #[doc = ""]
    #[doc = " This function is equivalent to"]
    #[doc = " ```"]
    #[doc = " // produce diagonal matrix d"]
    #[doc = " PauliHamil h = createPauliHamilFromFile(fn);"]
    #[doc = " DiagonalOp d = createDiagonalOp(h.numQubits, env);"]
    #[doc = " initDiagonalOpFromPauliHamil(d, h);"]
    #[doc = " destroyPauliHamil(h);"]
    #[doc = " ```"]
    #[doc = " <br>"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - initDiagonalOpFromPauliHamil()"]
    #[doc = " - createPauliHamilFromFile()"]
    #[doc = " - createDiagonalOp()"]
    #[doc = " - destroyDiagonalOp()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] fn filename of a plaintext file encoding an all-Z Pauli Hamiltonian"]
    #[doc = " @param[in] env the session ::QuESTEnv"]
    #[doc = " @returns a created ::DiagonalOp equivalent to the Hamiltonian in \\p fn"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if file \\p fn cannot be read"]
    #[doc = " - if file \\p fn does not encode a valid ::PauliHamil"]
    #[doc = " - if the encoded ::PauliHamil consists of operators other than `PAULI_Z` and `PAULI_I`"]
    #[doc = " @author Tyson Jones"]
    #[doc = " @author Milos Prokop (serial prototype)"]
    pub fn createDiagonalOpFromPauliHamilFile(
        fn_: *mut ::std::os::raw::c_char,
        env: QuESTEnv,
    ) -> DiagonalOp;
}
extern "C" {
    #[doc = " Modifies a subset (starting at index \\p startInd, and ending at index"]
    #[doc = " \\p startInd <b>+</b> \\p numElems) of the elements in ::DiagonalOp \\p op"]
    #[doc = " with the given complex numbers (passed as \\p real and \\p imag components)."]
    #[doc = ""]
    #[doc = " In GPU mode, this updates both the RAM (\\p op.real and \\p op.imag), and the"]
    #[doc = " persistent GPU memory."]
    #[doc = ""]
    #[doc = " In distributed mode, this function assumes the subset \\p real and \\p imag exist"]
    #[doc = " (at least) on the node containing the ultimately updated elements.\\n"]
    #[doc = " For example, below is the correct way to modify the full 8 elements of \\p op"]
    #[doc = " when split between 2 nodes."]
    #[doc = " ```"]
    #[doc = "     DiagonalOp op = createDiagonalOp(3, env);"]
    #[doc = ""]
    #[doc = "     int numElems = 4;"]
    #[doc = "     qreal re[] = {1,2,3,4};"]
    #[doc = "     qreal im[] = {1,2,3,4};"]
    #[doc = "     setDiagonalOpElems(op, 0, re, im, numElems);"]
    #[doc = ""]
    #[doc = "     // modify re and im to the next set of elements"]
    #[doc = "     for (int i=0; i<4; i++) {"]
    #[doc = "       re[i] += 4;"]
    #[doc = "       im[i] += 4;"]
    #[doc = "     }"]
    #[doc = "     setDiagonalOpElems(op, 4, re, im, numElems);"]
    #[doc = " ```"]
    #[doc = ""]
    #[doc = " In this way, one can avoid a single node containing all new elements which might"]
    #[doc = " not fit. If more elements are passed than exist on an individual node, each"]
    #[doc = " node merely ignores the additional elements."]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in,out] op the ::DiagonalOp to modify"]
    #[doc = " @param[in] startInd the starting index (globally) of the subset of elements to modify"]
    #[doc = " @param[in] real  the real components of the new elements"]
    #[doc = " @param[in] imag  the imaginary components of the new elements"]
    #[doc = " @param[in] numElems the number of new elements (the length of \\p real and \\p imag)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p op was not created"]
    #[doc = " - if \\p startInd is an invalid index (<0 or >=<b>pow(2,</b>`op.numQubits`<b>)</b>)"]
    #[doc = " - if \\p numElems is an invalid number of elements (<=0 or ><b>pow(2,</b>`op.numQubits`<b>)</b>)"]
    #[doc = " - if there are fewer than \\p numElems elements in \\p op after \\p startInd"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if either \\p real or \\p imag have fewer elements than \\p numElems"]
    #[doc = " @author Tyson Jones"]
    pub fn setDiagonalOpElems(
        op: DiagonalOp,
        startInd: ::std::os::raw::c_longlong,
        real: *mut f64,
        imag: *mut f64,
        numElems: ::std::os::raw::c_longlong,
    );
}
extern "C" {
    #[doc = " Apply a diagonal operator, which is possibly non-unitary and non-Hermitian,"]
    #[doc = " to the entire \\p qureg."]
    #[doc = ""]
    #[doc = " Let \\f$d_j = \\text{op.real}[j] + (\\text{op.imag}[j])\\,\\text{i} \\f$, and"]
    #[doc = " \\f["]
    #[doc = "  \\hat{D} = \\begin{pmatrix}"]
    #[doc = "  d_0 \\\\"]
    #[doc = "  & d_1 \\\\"]
    #[doc = "  & & \\ddots \\\\"]
    #[doc = "  & & & d_{2^{\\text{op.numQubits}}-1}"]
    #[doc = "  \\end{pmatrix}."]
    #[doc = " \\f]"]
    #[doc = " If \\p qureg is a state-vector \\f$|\\psi\\rangle\\f$, this function performs"]
    #[doc = "  \\f$|\\psi\\rangle \\rightarrow \\hat{D} \\, |\\psi\\rangle\\f$. \\n"]
    #[doc = " If \\p qureg is a density-matrix \\f$\\rho\\f$, this function performs"]
    #[doc = "  \\f$\\rho \\rightarrow \\hat{D}\\, \\rho\\f$. Notice this has not applied \\f$\\hat{D}\\f$"]
    #[doc = " in the fashion of a unitary."]
    #[doc = ""]
    #[doc = " > If your operator is unitary with unit amplitudes, the phases of which can be"]
    #[doc = " > described by an analytic expression, you should instead use applyPhaseFunc()"]
    #[doc = " > or applyNamedPhaseFunc() for significant memory and runtime savings."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDiagonalOp()"]
    #[doc = " - calcExpecDiagonalOp()"]
    #[doc = " - applyPhaseFunc()"]
    #[doc = " - applyNamedPhaseFunc()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state to operate the diagonal operator upon"]
    #[doc = " @param[in] op the diagonal operator to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p op was not created"]
    #[doc = " - if \\p op acts on a different number of qubits than \\p qureg represents"]
    #[doc = " @author Tyson Jones"]
    pub fn applyDiagonalOp(qureg: Qureg, op: DiagonalOp);
}
extern "C" {
    #[doc = " Computes the expected value of the diagonal operator \\p op for state \\p qureg."]
    #[doc = " Since \\p op is not necessarily Hermitian, the expected value may be a complex"]
    #[doc = " number."]
    #[doc = ""]
    #[doc = " Let \\f$ D \\f$ be the diagonal operator \\p op, with diagonal elements \\f$ d_i \\f$."]
    #[doc = " Then if \\p qureg is a state-vector \\f$|\\psi\\rangle \\f$, this function computes"]
    #[doc = " \\f["]
    #[doc = "\\langle \\psi | D | \\psi \\rangle = \\sum_i |\\psi_i|^2 \\, d_i"]
    #[doc = " \\f]"]
    #[doc = " If \\p qureg is a density matrix \\f$ \\rho \\f$, this function computes"]
    #[doc = " \\f["]
    #[doc = "\\text{Trace}( D \\rho ) = \\sum_i \\rho_{ii} \\, d_i"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createDiagonalOp()"]
    #[doc = " - applyDiagonalOp()"]
    #[doc = " - calcExpecPauliSum()"]
    #[doc = " - calcExpecPauliProd()"]
    #[doc = " - calcExpecPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg a state-vector or density matrix"]
    #[doc = " @param[in] op    the diagonal operator to compute the expected value of"]
    #[doc = " @return the expected vaulue of the operator"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p op was not created"]
    #[doc = " - if \\p op acts on a different number of qubits than \\p qureg represents"]
    #[doc = " @author Tyson Jones"]
    pub fn calcExpecDiagonalOp(qureg: Qureg, op: DiagonalOp) -> Complex;
}
extern "C" {
    #[doc = " Print the current state vector of probability amplitudes for a set of qubits to file."]
    #[doc = " File format:"]
    #[doc = " @verbatim"]
    #[doc = "real, imag"]
    #[doc = "realComponent1, imagComponent1"]
    #[doc = "realComponent2, imagComponent2"]
    #[doc = "..."]
    #[doc = "realComponentN, imagComponentN"]
    #[doc = "@endverbatim"]
    #[doc = ""]
    #[doc = " File naming convention:"]
    #[doc = ""]
    #[doc = " For each node that the program runs on, a file 'state_rank_[node_rank].csv' is generated. If there is"]
    #[doc = " more than one node, ranks after the first do not include the header"]
    #[doc = " @verbatim"]
    #[doc = "real, imag"]
    #[doc = "@endverbatim"]
    #[doc = " so that files are easier to combine."]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in,out] qureg object representing the set of qubits"]
    #[doc = " @author Ania Brown"]
    pub fn reportState(qureg: Qureg);
}
extern "C" {
    #[doc = " Print the current state vector of probability amplitudes for a set of qubits to standard out."]
    #[doc = " For debugging purposes. Each rank should print output serially."]
    #[doc = " Only print output for systems <= 5 qubits"]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @author Ania Brown"]
    pub fn reportStateToScreen(qureg: Qureg, env: QuESTEnv, reportRank: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Report metainformation about a set of qubits: number of qubits, number of probability amplitudes."]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in] qureg object representing the set of qubits"]
    #[doc = " @author Ania Brown"]
    pub fn reportQuregParams(qureg: Qureg);
}
extern "C" {
    #[doc = " Print the \\p PauliHamil to screen."]
    #[doc = " The output features a new line for each term, each with format"]
    #[doc = ""]
    #[doc = "     c p1 p2 p3 ... pN"]
    #[doc = ""]
    #[doc = " where \\p c is the real coefficient of the term, and \\p p1 ... \\p pN are"]
    #[doc = " numbers \\p 0, \\p 1, \\p 2, \\p 3 to indicate identity, pauliX, pauliY and pauliZ"]
    #[doc = " operators respectively, acting on qubits \\p 0 through \\p N-1 (all qubits)."]
    #[doc = " A tab character separates c and p1, but single spaces separate the Pauli operators."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - initPauliHamil()"]
    #[doc = " - createPauliHamilFromFile()"]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in] hamil an instantiated PauliHamil"]
    #[doc = " @throws invalidQuESTInputError if the parameters of \\p hamil are invalid, i.e."]
    #[doc = "      if \\p numQubits <= 0, or if \\p numSumTerms <= 0, or if \\p pauliCodes"]
    #[doc = "      contains an invalid Pauli code."]
    #[doc = " @author Tyson Jones"]
    pub fn reportPauliHamil(hamil: PauliHamil);
}
extern "C" {
    #[doc = " Returns the number of qubits represented by \\p qureg."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getNumAmps()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg a state-vecor or density matrix"]
    #[doc = " @return `qureg.numQubitsRepresented`"]
    #[doc = " @author Tyson Jones"]
    pub fn getNumQubits(qureg: Qureg) -> ::std::os::raw::c_int;
}
extern "C" {
    #[doc = " Returns the number of complex amplitudes in a state-vector \\p qureg."]
    #[doc = ""]
    #[doc = " In distributed mode, this returns the total number of amplitudes in the full"]
    #[doc = " representation of \\p qureg, and so may be larger than the number stored on"]
    #[doc = " each node. For the latter, refer to Qureg.numAmpsPerChunk."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg a state-vecotor"]
    #[doc = " @return the total number of complex amplitudes representing \\p qureg."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a density matrix"]
    #[doc = " @author Tyson Jones"]
    pub fn getNumAmps(qureg: Qureg) -> ::std::os::raw::c_longlong;
}
extern "C" {
    #[doc = " Initialises a qureg to have all-zero-amplitudes. This is an unphysical state"]
    #[doc = " useful for iteratively building a state with functions like setWeightedQureg(),"]
    #[doc = " and should not be confused with initZeroState()."]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg a ::Qureg of which to clear all amplitudes"]
    #[doc = " @author Tyson Jones"]
    pub fn initBlankState(qureg: Qureg);
}
extern "C" {
    #[doc = " Initialise \\p qureg into the zero state."]
    #[doc = ""]
    #[doc = " If \\p qureg is a state-vector of \\f$N\\f$ qubits, it is modified to state"]
    #[doc = " \\f$ {| 0 \\rangle}^{\\otimes N} \\f$. \\n"]
    #[doc = " If \\p qureg is a density matrix of \\f$ N \\f$ qubits, it is modified to state"]
    #[doc = " \\f$ {| 0 \\rangle\\langle 0 |}^{\\otimes N} \\f$"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the object representing the set of all qubits to initialise"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn initZeroState(qureg: Qureg);
}
extern "C" {
    #[doc = " Initialise \\p qureg into the plus state."]
    #[doc = ""]
    #[doc = " If \\p qureg is a state-vector of \\f$N\\f$ qubits, it is modified to state"]
    #[doc = " \\f["]
    #[doc = "   {| + \\rangle}^{\\otimes N} = \\frac{1}{\\sqrt{2^N}} (| 0 \\rangle + | 1 \\rangle)^{\\otimes N}\\,."]
    #[doc = " \\f]"]
    #[doc = " If \\p qureg is a density matrix of \\f$N\\f$ qubits, it is modified to state"]
    #[doc = " \\f["]
    #[doc = "   {| + \\rangle\\langle+|}^{\\otimes N} = \\frac{1}{{2^N}} \\sum_i\\sum_j |i\\rangle\\langle j|\\,."]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the object representing the set of qubits to be initialised"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn initPlusState(qureg: Qureg);
}
extern "C" {
    #[doc = " Initialise \\p qureg into the classical state (also known as a"]
    #[doc = " \"computational basis state\") with index \\p stateInd."]
    #[doc = ""]
    #[doc = " If \\p qureg is a state-vector, it will become"]
    #[doc = "      \\f$ | \\text{stateInd} \\rangle \\f$. \\n"]
    #[doc = " If \\p qureg is a density matrix, it will become"]
    #[doc = "      \\f$ | \\text{stateInd} \\rangle \\langle \\text{stateInd} | \\f$."]
    #[doc = ""]
    #[doc = " Classical states are indexed from zero, so that \\p stateInd <b>= 0</b> produces"]
    #[doc = " \\f$ | 00 \\dots 00 \\rangle \\f$,"]
    #[doc = " and  \\p stateInd <b>= 1</b> produces \\f$ | 00 \\dots 01 \\rangle \\f$, and"]
    #[doc = " \\p stateInd <b>=</b> \\f$ 2^N - 1 \\f$ produces"]
    #[doc = " \\f$ | 11 \\dots 11 \\rangle \\f$."]
    #[doc = ""]
    #[doc = " Subsequent calls to getProbAmp() will yield 0 for all indices except \\p stateInd,"]
    #[doc = " and the phase of \\p stateInd's amplitude will be 1 (real)."]
    #[doc = ""]
    #[doc = " This function can be used to initialise \\p qureg into a specific binary state"]
    #[doc = " (e.g. \\p 11001) using a binary literal (supported by only some compilers):"]
    #[doc = " ```"]
    #[doc = "      initClassicalState(qureg, 0b11001);"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - initPureState()"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the ::Qureg to modify"]
    #[doc = " @param[in] stateInd the index of the basis state to modify \\p qureg into"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p stateInd is outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " @author Tyson Jones"]
    pub fn initClassicalState(qureg: Qureg, stateInd: ::std::os::raw::c_longlong);
}
extern "C" {
    #[doc = " Initialise \\p qureg into to a given pure state of an equivalent Hilbert dimension."]
    #[doc = ""]
    #[doc = " If \\p qureg is a state-vector, this merely clones \\p pure into \\p qureg. \\n"]
    #[doc = " If \\p qureg is a density matrix, this makes \\p qureg 100% likely to be in the \\p pure state."]
    #[doc = ""]
    #[doc = " ::Qureg \\p pure is not modified."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - initClassicalState()"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the ::Qureg to modify"]
    #[doc = " @param[in] pure a state-vector containing the pure state into which to initialise \\p qureg"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg and \\p pure have mismatching dimensions"]
    #[doc = " - if \\p pure is a density matrix"]
    #[doc = " @author Tyson Jones"]
    pub fn initPureState(qureg: Qureg, pure_: Qureg);
}
extern "C" {
    #[doc = " Initialises \\p qureg to be in the un-normalised, non-physical state with"]
    #[doc = " with \\f$n\\f$-th complex amplitude given by \\f$2n/10 + i(2n+1)/10\\f$."]
    #[doc = ""]
    #[doc = " This is used internally for debugging and testing."]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in,out] qureg the register to have its amplitudes overwritten"]
    #[doc = " @author Ania Brown"]
    #[doc = " @author Tyson Jones (doc)"]
    pub fn initDebugState(qureg: Qureg);
}
extern "C" {
    #[doc = " Initialise \\p qureg by specifying all amplitudes."]
    #[doc = " For density matrices, it is assumed the amplitudes have been flattened"]
    #[doc = " column-wise into the given arrays."]
    #[doc = ""]
    #[doc = " The real and imaginary components of the amplitudes are passed in separate arrays,"]
    #[doc = " \\p reals and \\p imags,"]
    #[doc = " each of which must have length `qureg.numAmpsTotal`."]
    #[doc = " There is no automatic checking that the passed arrays are L2 normalised, so this"]
    #[doc = " can be used to prepare \\p qureg in a non-physical state."]
    #[doc = ""]
    #[doc = " In distributed mode, this would require the complete state to fit in"]
    #[doc = " every node. To manually prepare a state for which all amplitudes cannot fit into a single node,"]
    #[doc = " use setAmps()"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - setAmps()"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the ::Qureg to overwrite"]
    #[doc = " @param[in] reals array of the real components of the new amplitudes"]
    #[doc = " @param[in] imags array of the imaginary components of the new amplitudes"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if either \\p reals or \\p imags have fewer than `qureg.numAmpsTotal` elements"]
    #[doc = " @author Tyson Jones"]
    pub fn initStateFromAmps(qureg: Qureg, reals: *mut f64, imags: *mut f64);
}
extern "C" {
    #[doc = " Overwrites a subset of the amplitudes in state-vector \\p qureg, with those passed in \\p reals and \\p imags."]
    #[doc = ""]
    #[doc = " Only amplitudes with indices in <b>[</b>\\p startInd<b>,</b> \\p startInd <b>+</b> \\p numAmps<b>]</b>"]
    #[doc = " will be changed. The resulting \\p qureg may not necessarily be in an L2 normalised state."]
    #[doc = ""]
    #[doc = " In distributed mode, this function assumes the subset \\p reals and \\p imags exist"]
    #[doc = " (at least) on the node containing the ultimately updated elements.\\n"]
    #[doc = " For example, below is the correct way to modify the full 8 elements of \\p qureg"]
    #[doc = " when split between 2 nodes."]
    #[doc = " ```"]
    #[doc = "     Qureg qureg = createQureg(3, env);"]
    #[doc = ""]
    #[doc = "     long long int numAmps = 4;"]
    #[doc = "     qreal re[] = {1,2,3,4};"]
    #[doc = "     qreal im[] = {1,2,3,4};"]
    #[doc = "     setAmps(qureg, 0, re, im, numAmps);"]
    #[doc = ""]
    #[doc = "     // modify re and im to the next set of elements"]
    #[doc = "     for (int i=0; i<4; i++) {"]
    #[doc = "       re[i] += 4;"]
    #[doc = "       im[i] += 4;"]
    #[doc = "     }"]
    #[doc = "     setAmps(qureg, 4, re, im, numAmps);"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - setWeightedQureg()"]
    #[doc = " - initStateFromAmps()"]
    #[doc = " - initBlankState()"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in,out] qureg the state-vector to modify"]
    #[doc = " @param[in] startInd the index of the first amplitude in \\p qureg to modify"]
    #[doc = " @param[in] reals array of the real components of the new amplitudes"]
    #[doc = " @param[in] imags array of the imaginary components of the new amplitudes"]
    #[doc = " @param[in] numAmps the length of each of the reals and imags arrays."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a state-vector (i.e. is a density matrix)"]
    #[doc = " - if \\p startInd is outside [0, `qureg.numAmpsTotal`]"]
    #[doc = " - if \\p numAmps is outside [0, `qureg.numAmpsTotal`]"]
    #[doc = " - if \\p numAmps + \\p startInd >= `qureg.numAmpsTotal`"]
    #[doc = " @author Tyson Jones"]
    pub fn setAmps(
        qureg: Qureg,
        startInd: ::std::os::raw::c_longlong,
        reals: *mut f64,
        imags: *mut f64,
        numAmps: ::std::os::raw::c_longlong,
    );
}
extern "C" {
    #[doc = " Overwrite the amplitudes of \\p targetQureg with those from \\p copyQureg."]
    #[doc = ""]
    #[doc = " Registers must either both be state-vectors, or both be density matrices, and"]
    #[doc = " of equal dimensions."]
    #[doc = " Only the quantum state is cloned, while auxilary info (like recorded QASM) is unchanged."]
    #[doc = " copyQureg is unaffected."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createCloneQureg()"]
    #[doc = " - initPureState()"]
    #[doc = " - setWeightedQureg()"]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in, out] targetQureg the qureg to have its quantum state overwritten"]
    #[doc = " @param[in] copyQureg the qureg to have its quantum state cloned into targetQureg."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQureg is a state-vector while \\p copyQureg is a density matrix (and vice versa)"]
    #[doc = " - if \\p targetQureg and \\p copyQureg have different dimensions"]
    #[doc = " @author Tyson Jones"]
    pub fn cloneQureg(targetQureg: Qureg, copyQureg: Qureg);
}
extern "C" {
    #[doc = " Shift the phase between \\f$ |0\\rangle \\f$ and \\f$ |1\\rangle \\f$ of a single qubit by a given angle."]
    #[doc = ""]
    #[doc = " > This is equivalent to a Z-axis rotation of the Bloch-sphere up to a global phase factor."]
    #[doc = " For angle \\f$\\theta\\f$, this effects single-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & 0 \\\\"]
    #[doc = " 0 & \\exp(i \\theta)"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-4, 0) {targetQubit};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_\\theta$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - controlledPhaseShift()"]
    #[doc = " - multiControlledPhaseShift()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to undergo a phase shift"]
    #[doc = " @param[in] angle amount by which to shift the phase in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)."]
    #[doc = " @author Tyson Jones"]
    pub fn phaseShift(qureg: Qureg, targetQubit: ::std::os::raw::c_int, angle: f64);
}
extern "C" {
    #[doc = " Introduce a phase factor \\f$ \\exp(i \\theta) \\f$ on state \\f$ |11\\rangle \\f$ of qubits"]
    #[doc = " \\p idQubit1 and \\p idQubit2."]
    #[doc = " For angle \\f$\\theta\\f$, this effects the unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & & & \\\\"]
    #[doc = " & 1 & & \\\\"]
    #[doc = " & & 1 & \\\\"]
    #[doc = " & & & \\exp(i \\theta)"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on \\p idQubit1 and \\p idQubit2."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {qubit1};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {qubit2};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_\\theta$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - phaseShift()"]
    #[doc = " - multiControlledPhaseShift()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] idQubit1 first qubit in the state to phase shift"]
    #[doc = " @param[in] idQubit2 second qubit in the state to phase shift"]
    #[doc = " @param[in] angle amount by which to shift the phase in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p idQubit1 or \\p idQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p idQubit1 and \\p idQubit2 are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledPhaseShift(
        qureg: Qureg,
        idQubit1: ::std::os::raw::c_int,
        idQubit2: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Introduce a phase factor \\f$ \\exp(i \\theta) \\f$ on state \\f$ |1 \\dots 1 \\rangle \\f$"]
    #[doc = " of the passed qubits."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {controls};"]
    #[doc = "\\node[draw=none] at (1, .7) {$\\theta$};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 6) {$\\vdots$};"]
    #[doc = "\\draw (0, 5) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw (0, 4) -- (0, 2);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 0);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw[fill=black] (0, 0) circle (.2);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - phaseShift()"]
    #[doc = " - controlledPhaseShift()"]
    #[doc = " - controlledPhaseFlip()"]
    #[doc = " - multiControlledPhaseFlip()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits array of qubits to phase shift"]
    #[doc = " @param[in] numControlQubits the length of array \\p controlQubits"]
    #[doc = " @param[in] angle amount by which to shift the phase in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented])"]
    #[doc = " - if any qubit index in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented])"]
    #[doc = " - if the qubits in \\p controlQubits are not unique"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledPhaseShift(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControlQubits: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate."]
    #[doc = " For each state, if both input qubits have value one, multiply the amplitude of that state by -1. This applies the two-qubit unitary:"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & 1 \\\\"]
    #[doc = " & & & -1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {idQubit1};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {idQubit2};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 0);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw[fill=black] (0, 0) circle (.2);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - pauliZ()"]
    #[doc = " - phaseShift()"]
    #[doc = " - multiControlledPhaseFlip()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] idQubit1, idQubit2 qubits to operate upon"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p idQubit1 or \\p idQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p idQubit1 and \\p idQubit2 are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledPhaseFlip(
        qureg: Qureg,
        idQubit1: ::std::os::raw::c_int,
        idQubit2: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply the multiple-qubit controlled phase flip gate, also known as the multiple-qubit controlled pauliZ gate."]
    #[doc = " For each state, if all control qubits have value one, multiply the amplitude of that state by -1. This applies the many-qubit unitary:"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & 1 \\\\"]
    #[doc = " & & & & -1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control qubits."]
    #[doc = ""]
    #[doc = " \\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 6) {$\\vdots$};"]
    #[doc = "\\draw (0, 5) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw (0, 4) -- (0, 2);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 0);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw[fill=black] (0, 0) circle (.2);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits array of input qubits"]
    #[doc = " @param[in] numControlQubits number of input qubits"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if any qubit in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if any qubit in \\p qubits is repeated"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledPhaseFlip(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControlQubits: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply the single-qubit S gate."]
    #[doc = " This is a rotation of \\f$\\pi/2\\f$ around the Z-axis on the Bloch sphere, or the unitary:"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & 0 \\\\"]
    #[doc = " 0 & i"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {S};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - tGate()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate upon"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn sGate(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply the single-qubit T gate."]
    #[doc = " This is a rotation of \\f$\\pi/4\\f$ around the Z-axis on the Bloch sphere, or the unitary:"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & 0 \\\\"]
    #[doc = " 0 & \\exp\\left(i \\frac{\\pi}{4}\\right)"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {T};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - sGate()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate upon"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn tGate(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Create the QuEST execution environment."]
    #[doc = " This should be called only once, and the environment should be freed with destroyQuESTEnv at the end"]
    #[doc = " of the user's code."]
    #[doc = " If something needs to be done to set up the execution environment, such as"]
    #[doc = " initializing MPI when running in distributed mode, it is handled here."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - reportQuESTEnv()"]
    #[doc = " - destroyQuESTEnv()"]
    #[doc = " - syncQuESTEnv()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @return object representing the execution environment. A single instance is used for each program"]
    #[doc = " @author Ania Brown"]
    pub fn createQuESTEnv() -> QuESTEnv;
}
extern "C" {
    #[doc = " Destroy the QuEST environment."]
    #[doc = " If something needs to be done to clean up the execution environment, such as"]
    #[doc = " finalizing MPI when running in distributed mode, it is handled here"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createQuESTEnv()"]
    #[doc = ""]
    #[doc = " @ingroup type"]
    #[doc = " @param[in] env object representing the execution environment. A single instance is used for each program"]
    #[doc = " @author Ania Brown"]
    pub fn destroyQuESTEnv(env: QuESTEnv);
}
extern "C" {
    #[doc = " Report information about the QuEST environment"]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in] env object representing the execution environment. A single instance is used for each program"]
    #[doc = " @author Ania Brown"]
    pub fn reportQuESTEnv(env: QuESTEnv);
}
extern "C" {
    #[doc = " Sets \\p str to a string containing information about the runtime environment,"]
    #[doc = " including whether simulation is using CUDA (for GPU), OpenMP (for multithreading)"]
    #[doc = " and/or MPI (for distribution). The number of CPU threads and distributed ranks is"]
    #[doc = " also reported. Note there is currently no reporting of the number of GPU cores used."]
    #[doc = ""]
    #[doc = " The string format is:"]
    #[doc = " ```"]
    #[doc = " \"CUDA=b OpenMP=b MPI=b threads=n ranks=n\""]
    #[doc = " ```"]
    #[doc = " where <b>b</b> is 0 or 1, and <b>n</b> are integers."]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in] env object representing the execution environment. A single instance is used for each program"]
    #[doc = " @param[out] str to be populated with the output string"]
    #[doc = " @author Ania Brown"]
    #[doc = " @author Tyson Jones"]
    pub fn getEnvironmentString(env: QuESTEnv, str_: *mut ::std::os::raw::c_char);
}
extern "C" {
    #[doc = " Get the complex amplitude at a given index in the state vector."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getDensityAmp()"]
    #[doc = " - getRealAmp()"]
    #[doc = " - getImagAmp()"]
    #[doc = " - getProbAmp()"]
    #[doc = " - getNumAmps()"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a set of qubits"]
    #[doc = " @param[in] index index in state vector of probability amplitudes"]
    #[doc = " @return amplitude at index, returned as a Complex struct (with .real and .imag attributes)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a density matrix"]
    #[doc = " - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented"]
    #[doc = " @author Tyson Jones"]
    pub fn getAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> Complex;
}
extern "C" {
    #[doc = " Get the real component of the complex probability amplitude at an index in the state vector."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getAmp()"]
    #[doc = " - getDensityAmp()"]
    #[doc = " - getImagAmp()"]
    #[doc = " - getProbAmp()"]
    #[doc = " - getNumAmps()"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a set of qubits"]
    #[doc = " @param[in] index index in state vector of probability amplitudes"]
    #[doc = " @return real component at that index"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a density matrix"]
    #[doc = " - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented"]
    #[doc = " @author Ania Brown"]
    pub fn getRealAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
}
extern "C" {
    #[doc = " Get the imaginary component of the complex probability amplitude at an index in the state vector."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getAmp()"]
    #[doc = " - getDensityAmp()"]
    #[doc = " - getRealAmp()"]
    #[doc = " - getProbAmp()"]
    #[doc = " - getNumAmps()"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a set of qubits"]
    #[doc = " @param[in] index index in state vector of probability amplitudes"]
    #[doc = " @return imaginary component at that index"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a density matrix"]
    #[doc = " - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented"]
    #[doc = " @author Ania Brown"]
    pub fn getImagAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
}
extern "C" {
    #[doc = " Get the probability of a state-vector at an index in the full state vector."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getAmp()"]
    #[doc = " - getDensityAmp()"]
    #[doc = " - getRealAmp()"]
    #[doc = " - getImagAmp()"]
    #[doc = " - getNumAmps()"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a set of qubits"]
    #[doc = " @param[in] index index in state vector of probability amplitudes"]
    #[doc = " @return realEl*realEl + imagEl*imagEl"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a density matrix"]
    #[doc = " - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented"]
    #[doc = " @author Ania Brown"]
    pub fn getProbAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
}
extern "C" {
    #[doc = " Get an amplitude from a density matrix at a given row and column."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - getAmp()"]
    #[doc = " - getRealAmp()"]
    #[doc = " - getImagAmp()"]
    #[doc = " - getProbAmp()"]
    #[doc = " - getNumAmps()"]
    #[doc = " - getNumQubits()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a density matrix"]
    #[doc = " @param[in] row row of the desired amplitude in the density matrix"]
    #[doc = " @param[in] col column of the desired amplitude in the density matrix"]
    #[doc = " @return a Complex scalar representing the desired amplitude"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is a state-vector,"]
    #[doc = " - if \\p row or \\p col are outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented"]
    #[doc = " @author Tyson Jones"]
    pub fn getDensityAmp(
        qureg: Qureg,
        row: ::std::os::raw::c_longlong,
        col: ::std::os::raw::c_longlong,
    ) -> Complex;
}
extern "C" {
    #[doc = " A debugging function which calculates the probability of the qubits in \\p qureg"]
    #[doc = " being in any state, which should always be 1 for correctly normalised states"]
    #[doc = " (hence returning a real number)."]
    #[doc = " For state-vectors \\f$ \\psi \\f$, this is the norm of the entire state-vector"]
    #[doc = " (the sum of the absolute-value-squared of every amplitude):"]
    #[doc = " \\f["]
    #[doc = "      \\sum\\limits_i |\\psi_i|^2"]
    #[doc = " \\f]"]
    #[doc = " and for density matrices \\f$ \\rho \\f$, it is the trace:"]
    #[doc = " \\f["]
    #[doc = "      \\text{Trace}(\\rho) = \\sum\\limits_i \\rho_{i,i} \\;"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " For un-normalised density matrices (those directly modified or initialised by the user),"]
    #[doc = " this function returns the real component of the trace."]
    #[doc = ""]
    #[doc = " Note this calculation utilises Kahan summation for greater accuracy, and hence is"]
    #[doc = " not parallelised and so will be slower than other functions."]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing a set of qubits"]
    #[doc = " @return the total probability of the qubits in \\p qureg being in any state"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn calcTotalProb(qureg: Qureg) -> f64;
}
extern "C" {
    #[doc = " Apply a single-qubit unitary parameterised by two given complex scalars."]
    #[doc = " Given valid complex numbers \\f$\\alpha\\f$ and \\f$\\beta\\f$, applies the unitary"]
    #[doc = " \\f["]
    #[doc = " U ="]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " \\alpha & -\\beta^* \\\\"]
    #[doc = " \\beta & \\alpha^*"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " which is general up to a global phase factor."]
    #[doc = " Valid \\f$\\alpha\\f$, \\f$\\beta\\f$ satisfy \\f$|\\alpha|^2 + |\\beta|^2 = 1\\f$."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - controlledCompactUnitary()"]
    #[doc = " - unitary()"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @param[in] alpha complex unitary parameter (row 1, column 1)"]
    #[doc = " @param[in] beta complex unitary parameter (row 2, column 1)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p alpha, \\p beta don't satisfy |`alpha`|^2 + |`beta`|^2 = 1"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn compactUnitary(
        qureg: Qureg,
        targetQubit: ::std::os::raw::c_int,
        alpha: Complex,
        beta: Complex,
    );
}
extern "C" {
    #[doc = " Apply a general single-qubit unitary (including a global phase factor)."]
    #[doc = " The passed 2x2 ComplexMatrix must be unitary, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " If \\p qureg is a state-vector, then the resulting state is \\f$ u \\, |\\text{qureg}\\rangle \\f$.\\n"]
    #[doc = " If \\p qureg is a density-matrix \\f$ \\rho \\f$, then the resulting state is \\f$ u \\, \\rho \\, u^\\dagger \\f$."]
    #[doc = ""]
    #[doc = " > Use applyMatrix2() to left-multiply a non-unitary ::ComplexMatrix2"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix2"]
    #[doc = " - controlledUnitary()"]
    #[doc = " - multiControlledUnitary()"]
    #[doc = " - multiStateControlledUnitary()"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - applyMatrix2()"]
    #[doc = " - compactUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn unitary(qureg: Qureg, targetQubit: ::std::os::raw::c_int, u: ComplexMatrix2);
}
extern "C" {
    #[doc = " Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere. For angle \\f$\\theta\\f$, applies"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " \\cos\\theta/2 & -i \\sin \\theta/2\\\\"]
    #[doc = " -i \\sin \\theta/2 & \\cos \\theta/2"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {rot};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_x(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - controlledRotateX()"]
    #[doc = " - rotateY()"]
    #[doc = " - rotateZ()"]
    #[doc = " - rotateAroundAxis()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] rotQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn rotateX(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
}
extern "C" {
    #[doc = " Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere."]
    #[doc = " For angle \\f$\\theta\\f$, applies"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " \\cos\\theta/2 & - \\sin \\theta/2\\\\"]
    #[doc = " \\sin \\theta/2 & \\cos \\theta/2"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {rot};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_y(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - controlledRotateY()"]
    #[doc = " - rotateX()"]
    #[doc = " - rotateZ()"]
    #[doc = " - rotateAroundAxis()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] rotQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate in radians"]
    #[doc = " @throws invalidQuESTInputError"]
    #[doc = "      if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)."]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc, debug)"]
    pub fn rotateY(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
}
extern "C" {
    #[doc = " Rotate a single qubit by a given angle around the Z-axis of the Bloch-sphere (also known as a phase shift gate)."]
    #[doc = " For angle \\f$\\theta\\f$, applies"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " \\exp(-i \\theta/2) & 0 \\\\"]
    #[doc = " 0 & \\exp(i \\theta/2)"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {rot};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_z(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - controlledRotateZ()"]
    #[doc = " - rotateY()"]
    #[doc = " - rotateX()"]
    #[doc = " - rotateAroundAxis()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = " - phaseShift()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] rotQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn rotateZ(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
}
extern "C" {
    #[doc = " Rotate a single qubit by a given angle around a given \\ref Vector on the Bloch-sphere."]
    #[doc = " The vector must not be zero (else an error is thrown), but needn't be unit magnitude, since"]
    #[doc = " it will be normalised by QuEST."]
    #[doc = ""]
    #[doc = " For angle \\f$\\theta\\f$ and axis vector \\f$\\vec{n}\\f$, applies \\f$R_{\\hat{n}} = \\exp \\left(- i \\frac{\\theta}{2} \\hat{n} \\cdot \\vec{\\sigma} \\right) \\f$"]
    #[doc = " where \\f$\\vec{\\sigma}\\f$ is the vector of Pauli matrices."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - controlledRotateAroundAxis()"]
    #[doc = " - rotateX()"]
    #[doc = " - rotateY()"]
    #[doc = " - rotateZ()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] rotQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate in radians"]
    #[doc = " @param[in] axis vector around which to rotate (can be non-unit; will be normalised)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p axis is the zero vector"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn rotateAroundAxis(
        qureg: Qureg,
        rotQubit: ::std::os::raw::c_int,
        angle: f64,
        axis: Vector,
    );
}
extern "C" {
    #[doc = " Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere."]
    #[doc = " The target qubit is rotated in states where the control qubit has value 1."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_x(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - rotateX()"]
    #[doc = " - controlledRotateY()"]
    #[doc = " - controlledRotateZ()"]
    #[doc = " - controlledRotateAroundAxis()"]
    #[doc = " - controlledPhaseShift()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit qubit which has value 1 in the rotated states"]
    #[doc = " @param[in] targetQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate the target qubit in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledRotateX(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere."]
    #[doc = " The target qubit is rotated in states where the control qubit has value 1."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_y(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " - rotateY()"]
    #[doc = " - controlledRotateX()"]
    #[doc = " - controlledRotateZ()"]
    #[doc = " - controlledRotateAroundAxis()"]
    #[doc = " - controlledPhaseShift()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit qubit which has value 1 in the rotated states"]
    #[doc = " @param[in] targetQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate the target qubit in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledRotateY(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere."]
    #[doc = " The target qubit is rotated in states where the control qubit has value 1."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_z(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - rotateZ()"]
    #[doc = " - controlledRotateX()"]
    #[doc = " - controlledRotateY()"]
    #[doc = " - controlledRotateAroundAxis()"]
    #[doc = " - controlledPhaseShift()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit qubit which has value 1 in the rotated states"]
    #[doc = " @param[in] targetQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate the target qubit in radians"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledRotateZ(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Applies a controlled rotation by a given angle around a given vector on the Bloch-sphere."]
    #[doc = " The vector must not be zero (else an error is thrown), but needn't be unit magnitude."]
    #[doc = ""]
    #[doc = " For angle \\f$\\theta\\f$ and axis vector \\f$\\vec{n}\\f$, applies \\f$R_{\\hat{n}} = \\exp \\left(- i \\frac{\\theta}{2} \\hat{n} \\cdot \\vec{\\sigma} \\right) \\f$ to states where the target qubit is 1"]
    #[doc = " (\\f$\\vec{\\sigma}\\f$ is the vector of Pauli matrices)."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$R_{\\hat{n}}(\\theta)$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - rotateAroundAxis()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit qubit with value 1 in the rotated states"]
    #[doc = " @param[in] targetQubit qubit to rotate"]
    #[doc = " @param[in] angle angle by which to rotate in radians"]
    #[doc = " @param[in] axis vector around which to rotate (can be non-unit; will be normalised)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " - if \\p axis is the zero vector"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledRotateAroundAxis(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        angle: f64,
        axis: Vector,
    );
}
extern "C" {
    #[doc = " Apply a controlled unitary (single control, single target) parameterised by two given complex scalars."]
    #[doc = " Given valid complex numbers \\f$\\alpha\\f$ and \\f$\\beta\\f$, applies the two-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\"]
    #[doc = " & & \\alpha & -\\beta^* \\\\"]
    #[doc = " & & \\beta & \\alpha^*"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " to the control and target qubits."]
    #[doc = " Valid \\f$\\alpha\\f$, \\f$\\beta\\f$ satisfy \\f$|\\alpha|^2 + |\\beta|^2 = 1\\f$."]
    #[doc = " The target unitary is general up to a global phase factor."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$U_{\\alpha, \\beta}$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - compactUnitary()"]
    #[doc = " - controlledUnitary()"]
    #[doc = " - multiControlledUnitary()"]
    #[doc = " - multiStateControlledUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit apply the target unitary if this qubit has value 1"]
    #[doc = " @param[in] targetQubit qubit on which to apply the target unitary"]
    #[doc = " @param[in] alpha complex unitary parameter (row 1, column 1)"]
    #[doc = " @param[in] beta complex unitary parameter (row 2, column 1)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " - if \\p alpha, \\p beta don't satisfy |`alpha`|^2 + |`beta`|^2 = 1"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn controlledCompactUnitary(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        alpha: Complex,
        beta: Complex,
    );
}
extern "C" {
    #[doc = " Apply a general controlled unitary (single control, single target), which can include a global phase factor."]
    #[doc = " The given unitary is applied to the target qubit if the control qubit has value 1,"]
    #[doc = " effecting the two-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\"]
    #[doc = " & & u_{00} & u_{01}\\\\"]
    #[doc = " & & u_{10} & u_{11}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix2"]
    #[doc = " - unitary()"]
    #[doc = " - multiControlledUnitary()"]
    #[doc = " - multiStateControlledUnitary()"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit apply unitary if this qubit is 1"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @param[in] u single-qubit unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " - if \\p u is not unitary"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn controlledUnitary(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        u: ComplexMatrix2,
    );
}
extern "C" {
    #[doc = " Apply a general multiple-control single-target unitary, which can include"]
    #[doc = " a global phase factor. Any number of control qubits can be specified,"]
    #[doc = " and if all have value 1, the given unitary is applied to the target qubit."]
    #[doc = " This effects the many-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & u_{00} & u_{01}\\\\"]
    #[doc = " & & & u_{10} & u_{11}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = " The given 2x2 ComplexMatrix must be unitary, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 3) {controls};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 6) {$\\vdots$};"]
    #[doc = "\\draw (0, 5) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw (0, 4) -- (0, 2);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix2"]
    #[doc = " - unitary()"]
    #[doc = " - controlledUnitary()"]
    #[doc = " - multiStateControlledUnitary()"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits applies unitary if all qubits in this array equal 1"]
    #[doc = " @param[in] numControlQubits number of control qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @param[in] u single-qubit unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented])"]
    #[doc = " - if any qubit index (\\p targetQubit or one in \\p controlQubits) is outside [0, \\p qureg.numQubitsRepresented])"]
    #[doc = " - if any qubit in \\p controlQubits is repeated"]
    #[doc = " - if \\p controlQubits contains \\p targetQubit"]
    #[doc = " - if \\p u is not unitary"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn multiControlledUnitary(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControlQubits: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
        u: ComplexMatrix2,
    );
}
extern "C" {
    #[doc = " Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate."]
    #[doc = " This is a rotation of \\f$\\pi\\f$ around the x-axis on the Bloch sphere. I.e."]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 0 & 1 \\\\"]
    #[doc = " 1 & 0"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw (0, 0) circle (.5);"]
    #[doc = "\\draw (0, .5) -- (0, -.5);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - rotateX()"]
    #[doc = " - pauliY()"]
    #[doc = " - pauliZ()"]
    #[doc = " - controlledNot()"]
    #[doc = " - multiQubitNot()"]
    #[doc = " - multiControlledMultiQubitNot()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn pauliX(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate."]
    #[doc = " This is a rotation of \\f$\\pi\\f$ around the Y-axis on the Bloch sphere. I.e."]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 0 & -i \\\\"]
    #[doc = " i & 0"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$\\sigma_y$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - rotateY()"]
    #[doc = " - pauliX()"]
    #[doc = " - pauliZ()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn pauliY(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate."]
    #[doc = " This is a rotation of \\f$\\pi\\f$ around the Z-axis (a phase shift) on the Bloch sphere. I.e."]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & 0 \\\\"]
    #[doc = " 0 & -1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " with circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {$\\sigma_z$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - phaseShift()"]
    #[doc = " - rotateZ()"]
    #[doc = " - pauliX()"]
    #[doc = " - pauliY()"]
    #[doc = " - controlledPhaseFlip()"]
    #[doc = " - multiControlledPhaseFlip()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn pauliZ(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply the single-qubit Hadamard gate."]
    #[doc = " This takes \\f$|0\\rangle\\f$ to \\f$|+\\rangle\\f$ and \\f$|1\\rangle\\f$ to \\f$|-\\rangle\\f$, and is equivalent to a rotation of"]
    #[doc = " \\f$\\pi\\f$ around the x-axis then \\f$\\pi/2\\f$ about the y-axis on the Bloch-sphere. I.e."]
    #[doc = " \\f["]
    #[doc = " \\frac{1}{\\sqrt{2}}"]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 & 1 \\\\"]
    #[doc = " 1 & -1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {H};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate on"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn hadamard(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply the controlled not (single control, single target) gate, also"]
    #[doc = " known as the c-X, c-sigma-X, c-Pauli-X and c-bit-flip gate."]
    #[doc = " This applies pauliX to the target qubit if the control qubit has value 1."]
    #[doc = " This effects the two-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & & 1 \\\\"]
    #[doc = " & & 1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, -.5);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw (0, 0) circle (.5);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - multiControlledMultiQubitNot()"]
    #[doc = " - pauliX()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg the state-vector or density matrix to modify"]
    #[doc = " @param[in] controlQubit nots the target if this qubit is 1"]
    #[doc = " @param[in] targetQubit qubit to not"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix, doc)"]
    pub fn controlledNot(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply a NOT (or Pauli X) gate with multiple control and target qubits."]
    #[doc = " This applies pauliX to qubits \\p targs on every basis state for which the"]
    #[doc = " control qubits \\p ctrls are all in the \\f$|1\\rangle\\f$ state. The ordering within"]
    #[doc = " each of \\p ctrls and \\p targs has no effect on the operation."]
    #[doc = " > This function is equivalent, but significantly faster (approximately \\p numTargs times)"]
    #[doc = " > than applying controlled NOTs on each qubit in \\p targs in turn, since:"]
    #[doc = " > \\f["]
    #[doc = " >     C_{a, \\,b, \\,\\dots}( X_c \\otimes X_d \\otimes \\dots ) \\equiv"]
    #[doc = " >     C_{a, \\,b, \\,\\dots}( X_c) \\; \\otimes \\; C_{a, \\,b, \\,\\dots}(X_d) \\; \\otimes \\; \\dots"]
    #[doc = " > \\f]"]
    #[doc = ""]
    #[doc = " The effected unitary, if \\p targs and \\p ctrls happened to be contiguous, has matrix:"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & &   &    & {{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}}}} \\\\"]
    #[doc = " & & & &   & 1  &   \\\\"]
    #[doc = " & & & & 1 &    &  \\\\"]
    #[doc = " & & & {{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}}}} & & &"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " and circuit diagram:"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 1) {targets};"]
    #[doc = "\\node[draw=none] at (-3.5, 5) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 8) {$\\vdots$};"]
    #[doc = "\\draw (0, 7) -- (0, 6);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 6) -- (2, 6);"]
    #[doc = "\\draw[fill=black] (0, 6) circle (.2);"]
    #[doc = "\\draw (0, 6) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, -1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,2) -- (2, 2);"]
    #[doc = "\\draw (0, 2) circle (.4);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = "\\draw (0, 0) circle (.4);"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, -1.5) {$\\vdots$};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = " > In distributed mode, this operation requires at most a single round of pair-wise"]
    #[doc = " > communication between nodes, and hence is as efficient as pauliX()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - multiQubitNot()"]
    #[doc = " - controlledNot()"]
    #[doc = " - pauliX()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg a state-vector or density matrix to modify"]
    #[doc = " @param[in] ctrls a list of the control qubit indices"]
    #[doc = " @param[in] numCtrls the length of list \\p ctrls"]
    #[doc = " @param[in] targs a list of the qubits to be targeted by the X gates"]
    #[doc = " @param[in] numTargs the length of list \\p targs"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p ctrls and \\p targs is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p ctrls or \\p targs contain any repetitions"]
    #[doc = " - if any qubit in \\p ctrls is also in \\p targs (and vice versa)"]
    #[doc = " - if \\p numTargs <b>< 1</b>"]
    #[doc = " - if \\p numCtrls <b>< 1</b> (use multiQubitNot() for no controls)"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p ctrls contains fewer elements than \\p numCtrls"]
    #[doc = " - if \\p targs contains fewer elements than \\p numTargs"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledMultiQubitNot(
        qureg: Qureg,
        ctrls: *mut ::std::os::raw::c_int,
        numCtrls: ::std::os::raw::c_int,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply the controlled pauliY (single control, single target) gate, also"]
    #[doc = " known as the c-Y and c-sigma-Y gate."]
    #[doc = " This applies pauliY to the target qubit if the control qubit has value 1."]
    #[doc = " This effects the two-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & & -i \\\\"]
    #[doc = " & & i"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {control};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw[fill=black] (0, 2) circle (.2);"]
    #[doc = "\\draw (0, 2) -- (0, 1);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 0) {Y};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit applies pauliY to the target if this qubit is 1"]
    #[doc = " @param[in] targetQubit qubit to not"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubit and \\p targetQubit are equal"]
    #[doc = " @author Tyson Jones"]
    #[doc = " @author Ania Brown (debug)"]
    pub fn controlledPauliY(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Gives the probability of a specified qubit being measured in the given outcome (0 or 1)."]
    #[doc = " This performs no actual measurement and does not change the state of the qubits."]
    #[doc = ""]
    #[doc = " For state-vectors, this function works by summing the absolute-value-squared of every"]
    #[doc = " amplitude in the state-vector for which \\p measureQubit \\p = \\p 0."]
    #[doc = " If \\p outcome \\p = \\p 1, it returns \\p 1 minus this value. Hence for unnormalised"]
    #[doc = " state-vectors, this result will differ from the absolute-value-squared of every"]
    #[doc = " amplitude where \\p measureQubit \\p = \\p outcome."]
    #[doc = ""]
    #[doc = " For density matrices, this function sums the diagonal values (should be real)"]
    #[doc = " corresponding to \\p measureQubit \\p = \\p 0 (returning 1 minus this if \\p outcome \\p = \\p 1)."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcProbOfAllOutcomes()"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - measure()"]
    #[doc = " - measureWithStats()"]
    #[doc = " - collapseToOutcome()"]
    #[doc = " - calcTotalProb()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg object representing the set of all qubits"]
    #[doc = " @param[in] measureQubit qubit to study"]
    #[doc = " @param[in] outcome for which to find the probability of the qubit being measured in"]
    #[doc = " @return probability of qubit measureQubit being measured in the given outcome"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p measureQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p outcome is not in {0, 1}"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix)"]
    pub fn calcProbOfOutcome(
        qureg: Qureg,
        measureQubit: ::std::os::raw::c_int,
        outcome: ::std::os::raw::c_int,
    ) -> f64;
}
extern "C" {
    #[doc = " Populates \\p outcomeProbs with the probabilities of every outcome of the sub-register"]
    #[doc = " contained in \\p qubits."]
    #[doc = ""]
    #[doc = " > This performs no actual measurement and does not modify \\p qureg."]
    #[doc = ""]
    #[doc = " - For \\p qubits <b>= {a, b, c, ...}</b>, \\p outcomeProbs"]
    #[doc = "   is populated to"]
    #[doc = "   \\f["]
    #[doc = "     \\text{outcomeProbs} = \\{ \\; |\\alpha_0|^2, \\; |\\alpha_1|^2, \\; |\\alpha_2|^2, \\; |\\alpha_3|^2, \\; ... \\; \\},"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$|\\alpha_j|^2\\f$ are the probabilities of the respective outcome states (interpreting"]
    #[doc = "   \\p qubits as ordered least to most significant)"]
    #[doc = "   \\f["]
    #[doc = "      |\\dots\\textbf{c\\,b\\,a}\\rangle_i \\; \\; = \\;\\; |000\\rangle,  \\;\\; |001\\rangle \\;\\; |010\\rangle \\;\\; |011\\rangle, \\;\\; \\dots"]
    #[doc = "   \\f]"]
    #[doc = "   understood in a state-vector \\p qureg \\f$|\\psi\\rangle\\f$ as"]
    #[doc = "   \\f["]
    #[doc = "      |\\psi\\rangle = \\sum\\limits_i^{\\text{numQubits}} \\alpha_i \\; |\\dots\\textbf{c\\,b\\,a}\\rangle_i"]
    #[doc = "        \\; \\otimes \\; |\\phi\\rangle_i,"]
    #[doc = "   \\f]"]
    #[doc = "   or in a density matrix \\p qureg \\f$\\rho\\f$ as"]
    #[doc = "   \\f["]
    #[doc = "      \\begin{aligned}"]
    #[doc = "      \\rho &= \\sum\\limits_{i,j}^{\\text{numQubits}} \\; \\beta_{ij} \\; |\\dots\\textbf{c\\,b\\,a}\\rangle_i\\,\\langle\\dots\\textbf{c\\,b\\,a}|_j"]
    #[doc = "            \\; \\otimes \\; \\mu_{ij} \\\\"]
    #[doc = "           &= \\sum\\limits_i^{\\text{numQubits}} \\; |\\alpha_i|^2 \\;  |\\dots\\textbf{c\\,b\\,a}\\rangle\\langle\\dots\\textbf{c\\,b\\,a}|_i  \\;\\; + \\,"]
    #[doc = "            \\sum\\limits_{i \\ne j}^{\\text{numQubits}} \\; \\beta_{ij} \\; |\\dots\\textbf{c\\,b\\,a}\\rangle_i\\,\\langle\\dots\\textbf{c\\,b\\,a}|_j"]
    #[doc = "            \\; \\otimes \\; \\mu_{ij},"]
    #[doc = "       \\end{aligned}"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$|\\phi\\rangle_i\\f$ and \\f$\\mu_{ij}\\f$ are understood to be the separated states of the remaining qubits."]
    #[doc = ""]
    #[doc = " > \\p outcomeProbs must be a pre-allocated array of length \\f$2^{\\text{numQubits}}\\f$,"]
    #[doc = " > which is equivalent to <b>1<<</b>\\p numQubits. In distributed mode, every node receives"]
    #[doc = " > the full list of outcome probabilities."]
    #[doc = ""]
    #[doc = " - Note that the indices in \\p qubits need not be adjacent nor ordered. The order of"]
    #[doc = "   \\p qubits determines the order of \\p outcomeProbs, whereby \\p qubits are treated"]
    #[doc = "   as <em>increasing</em> significance."]
    #[doc = "   \\n\\n"]
    #[doc = ""]
    #[doc = " - For example, given a \\p qureg initialised into state-vector"]
    #[doc = "   \\f["]
    #[doc = "      |\\psi\\rangle ="]
    #[doc = "          \\alpha_0 |000\\rangle \\;+\\; \\alpha_1 |001\\rangle \\;+\\;"]
    #[doc = "          \\alpha_2 |010\\rangle \\;+\\; \\alpha_3 |011\\rangle \\;+\\;"]
    #[doc = "          \\alpha_4 |100\\rangle \\;+\\; \\alpha_5 |101\\rangle \\;+\\;"]
    #[doc = "          \\alpha_6 |110\\rangle \\;+\\; \\alpha_7 |111\\rangle,"]
    #[doc = "   \\f]"]
    #[doc = "   then executing"]
    #[doc = "   ```"]
    #[doc = "   int qubits[] = {2, 0};"]
    #[doc = "   int numQubits = 2;"]
    #[doc = ""]
    #[doc = "   qreal outcomeProbs[1<<numQubits];"]
    #[doc = "   calcProbOfAllOutcomes(outcomeProbs, qureg, qubits, numQubits);"]
    #[doc = "   ```"]
    #[doc = "   would populate \\p outcomeProbs with"]
    #[doc = "   \\f["]
    #[doc = "      \\text{outcomeProbs} = \\{ \\;\\; |\\alpha_0|^2+|\\alpha_2|^2, \\;\\; |\\alpha_4|^2+|\\alpha_6|^2, \\;\\;"]
    #[doc = "                                 |\\alpha_1|^2+|\\alpha_3|^2, \\;\\; |\\alpha_5|^2+|\\alpha_7|^2  \\;\\; \\}."]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " > Since all probability amplitudes of a state-vector are ultimately involved in"]
    #[doc = " > the output probabilities, calcProbOfAllOutcomes() works as expected for"]
    #[doc = " > un-normalised states. This is similarly true for density matrices, where all"]
    #[doc = " > diagonal elements are involved, although only the real values of the diagonal elements"]
    #[doc = " > will be consulted."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcProbOfOutcome()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[out] outcomeProbs a pre-allocated array of length <b>1<<</b>\\p numQubits,"]
    #[doc = "      which will be modified to contain all outcome probabilities"]
    #[doc = " @param[in] qureg a state-vector or density matrix to study"]
    #[doc = " @param[in] qubits a list of qubits to study"]
    #[doc = " @param[in] numQubits the length of list \\p qubits"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numQubits <= 0"]
    #[doc = " - if any index in \\p qubits is invalid, i.e. outside <b>[0,</b> \\p qureg.numQubitsRepresented <b>)</b>"]
    #[doc = " - if \\p qubits contains any repetitions"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p outcomeProbs is not pre-allocated"]
    #[doc = " - if \\p outcomeProbs contains space for fewer than <b>1<<</b>\\p numQubits elements"]
    #[doc = " @author Tyson Jones"]
    pub fn calcProbOfAllOutcomes(
        outcomeProbs: *mut f64,
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubits: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Measures a single qubit, collapsing it randomly to 0 or 1."]
    #[doc = ""]
    #[doc = " Outcome probabilities are weighted by the state vector, which is irreversibly"]
    #[doc = " changed after collapse to be consistent with the outcome."]
    #[doc = ""]
    #[doc = " > The random outcome generator is seeded by seedQuESTDefault() within"]
    #[doc = " > createQuESTEnv(), unless later overridden by seedQuEST()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - measureWithStats()"]
    #[doc = " - collapseToOutcome()"]
    #[doc = " - seedQuEST()"]
    #[doc = " - seedQuESTDefault()"]
    #[doc = ""]
    #[doc = " @ingroup normgate"]
    #[doc = " @param[in, out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] measureQubit qubit to measure"]
    #[doc = " @return the measurement outcome, 0 or 1"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p measureQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Ania Brown (state-vector)"]
    #[doc = " @author Tyson Jones (density matrix)"]
    pub fn measure(qureg: Qureg, measureQubit: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
}
extern "C" {
    #[doc = " Computes the inner product \\f$ \\langle \\text{bra} | \\text{ket} \\rangle \\f$ of two"]
    #[doc = " equal-size state vectors, given by"]
    #[doc = " \\f["]
    #[doc = "\\langle \\text{bra} | \\text{ket} \\rangle = \\sum_i {\\text{bra}_i}^* \\; \\times \\; \\text{ket}_i"]
    #[doc = " \\f]"]
    #[doc = " The same \\p qureg may be passed as both \\p bra and \\p ket,"]
    #[doc = " though we recommend users check state-vector normalisation with \\p calcTotalProb which"]
    #[doc = " employs Kahan summation for greater accuracy."]
    #[doc = " Neither state-vector is modified."]
    #[doc = ""]
    #[doc = " This function returns the correct inner product even if \\p bra and \\p ket are"]
    #[doc = " not correctly normalised states."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcDensityInnerProduct()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] bra qureg to be the 'bra' (i.e. have its values conjugate transposed) in the inner product"]
    #[doc = " @param[in] ket qureg to be the 'ket' in the inner product"]
    #[doc = " @return the complex inner product of \\p bra and \\p ket"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p bra and \\p ket are not both state-vectors"]
    #[doc = " - if \\p bra and \\p ket do not have equal dimensions"]
    #[doc = " @author Tyson Jones"]
    pub fn calcInnerProduct(bra: Qureg, ket: Qureg) -> Complex;
}
extern "C" {
    #[doc = " Computes the Hilbert-Schmidt scalar product"]
    #[doc = " (which is equivalent to the Frobenius inner product of matrices)"]
    #[doc = " of two density matrices \\p rho1 and \\p rho2 of equivalent size."]
    #[doc = " That is, we define the Hilbert-Schmidt scalar product"]
    #[doc = " \\f["]
    #[doc = "((\\rho_1, \\rho_2))_{HS} := \\text{Tr}[ \\rho_1^\\dagger \\rho_2 ],"]
    #[doc = " \\f]"]
    #[doc = " which is equivalent to the sum of products of matrix elemets, i.e.,"]
    #[doc = " \\f["]
    #[doc = "((\\rho_1, \\rho_2))_{HS} = \\sum\\limits_i \\sum\\limits_j  (\\rho_1)_{ij}^* (\\rho_2)_{ij}"]
    #[doc = " \\f]"]
    #[doc = " Assuming that both density matrices are Hermitian,"]
    #[doc = " the resulting scalar product is real and invariant under"]
    #[doc = " reordering its arguments as"]
    #[doc = " \\f["]
    #[doc = "((\\rho_1, \\rho_2))_{HS} = ((\\rho_2, \\rho_1))_{HS} = \\text{Tr}[\\rho_1 \\rho_2]"]
    #[doc = " \\f]"]
    #[doc = " If both \\p rho1 and \\p rho2 are density matrices of pure states"]
    #[doc = " \\p bra and \\p ket, then the equality holds"]
    #[doc = " \\f["]
    #[doc = "((\\rho_1, \\rho_2))_{HS} = |\\langle \\text{bra} | \\text{ket} \\rangle|^2."]
    #[doc = " \\f]"]
    #[doc = " If either or both of \\p rho1 and \\p rho2 are non Hermitian (i.e. invalid density"]
    #[doc = " matrices), then this function returns the real component of the scalar product,"]
    #[doc = " and discards the imaginary component. That is, it returns"]
    #[doc = " \\f["]
    #[doc = "\\text{Re}\\{ \\text{Tr}[ \\rho_1^\\dagger \\rho_2 ] \\} = \\text{Re}\\{ \\text{Tr}[ \\rho_2^\\dagger \\rho_1 ] \\}."]
    #[doc = " \\f]"]
    #[doc = " This is still sometimes useful, e.g. in calculating the inner product with an"]
    #[doc = " anti-commutator, e.g. (for Hermitian \\f$ \\sigma \\f$, \\f$ \\rho \\f$, \\f$ H \\f$)"]
    #[doc = " \\f["]
    #[doc = "      ((\\sigma, H \\rho + \\rho H))_{HS} = 2 \\; \\text{Re} \\{ ((\\sigma, H \\rho))_{HS} \\}"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ H \\rho \\f$ could be a weighted sum of Pauli products applied to \\f$ \\rho \\f$"]
    #[doc = " through applyPauliSum()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcInnerProduct()"]
    #[doc = " - calcHilbertSchmidtDistance()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] rho1 qureg as a density matrix (to have its values conjugate transposed)"]
    #[doc = " @param[in] rho2 qureg as a density matrix"]
    #[doc = " @returns the real Hilbert-Schmidt scalar product of density matrices"]
    #[doc = "\\p rho1 and \\p rho2 (assuming Hermiticity)"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p rho1 and \\p rho2 are not both density matrices"]
    #[doc = " - if \\p rho1 and \\p rho2 have mismatching dimensions"]
    #[doc = " @author Balint Koczor (CPU)"]
    #[doc = " @author Tyson Jones (GPU)"]
    pub fn calcDensityInnerProduct(rho1: Qureg, rho2: Qureg) -> f64;
}
extern "C" {
    #[doc = " Obtain the seeds presently used in random number generation."]
    #[doc = ""]
    #[doc = " This function sets argument \\p seeds to the address of the array of keys"]
    #[doc = " which have seeded QuEST's"]
    #[doc = " <a href=\"http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\">Mersenne Twister</a>"]
    #[doc = " random number generator. \\p numSeeds is set to the length of \\p seeds."]
    #[doc = " These are the seeds which inform the outcomes of random functions like"]
    #[doc = " measure(), and are set using seedQuEST() and seedQuESTDefault()."]
    #[doc = ""]
    #[doc = " > The output \\p seeds array <b>must not</b> be freed, and should not be modified."]
    #[doc = ""]
    #[doc = " Obtaining QuEST's seeds is useful for seeding your own random number generators,"]
    #[doc = " so that a simulation (with random QuEST measurements, and your own random decisions)"]
    #[doc = " can be precisely repeated later, just by calling seedQuEST()."]
    #[doc = ""]
    #[doc = " Note this function merely sets the arguments to the attributes for \\p env."]
    #[doc = " I.e."]
    #[doc = " ```"]
    #[doc = "     unsigned long int* seeds;"]
    #[doc = "     int numSeeds;"]
    #[doc = "     getQuESTSeeds(env, &seeds, &numSeeds);"]
    #[doc = ""]
    #[doc = "     func(seeds, numSeeds);"]
    #[doc = " ```"]
    #[doc = " is equivalent to"]
    #[doc = " ```"]
    #[doc = "     func(env.seeds, env.numSeeds);"]
    #[doc = " ```"]
    #[doc = " However, one should not rely upon their local pointer from getQuESTSeeds() to be"]
    #[doc = " automatically updated after a subsequent call to seedQuEST() or seedQuESTDefault()."]
    #[doc = " Instead, getQuESTSeeds() should be recalled."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - seedQuEST()"]
    #[doc = " - seedQuESTDefault()"]
    #[doc = ""]
    #[doc = " @ingroup debug"]
    #[doc = " @param[in] env the ::QuESTEnv runtime environment"]
    #[doc = " @param[in] seeds a pointer to an unitialised array to be modified"]
    #[doc = " @param[in] numSeeds a pointer to an integer to be modified"]
    #[doc = " @author Tyson Jones"]
    pub fn getQuESTSeeds(
        env: QuESTEnv,
        seeds: *mut *mut ::std::os::raw::c_ulong,
        numSeeds: *mut ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit dephasing noise."]
    #[doc = " With probability \\p prob, applies Pauli Z to \\p targetQubit."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{prob}) \\, \\rho + \\text{prob} \\; Z_q \\, \\rho \\, Z_q"]
    #[doc = " \\f]"]
    #[doc = " where q = \\p targetQubit."]
    #[doc = " \\p prob cannot exceed 1/2, which maximally mixes \\p targetQubit."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixTwoQubitDephasing()"]
    #[doc = " - mixDamping()"]
    #[doc = " - mixDepolarising()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixPauli()"]
    #[doc = " - mixDensityMatrix()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] targetQubit qubit upon which to induce dephasing noise"]
    #[doc = " @param[in] prob the probability of the phase error occuring"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p prob is not in [0, 1/2]"]
    #[doc = " @author Tyson Jones (GPU, doc)"]
    #[doc = " @author Ania Brown (CPU, distributed)"]
    pub fn mixDephasing(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce two-qubit dephasing noise."]
    #[doc = " With probability \\p prob, applies Pauli Z to either or both qubits."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{3} \\; \\left("]
    #[doc = "      Z_a \\, \\rho \\, Z_a +"]
    #[doc = "      Z_b \\, \\rho \\, Z_b +"]
    #[doc = "      Z_a Z_b \\, \\rho \\, Z_a Z_b"]
    #[doc = " \\right)"]
    #[doc = " \\f]"]
    #[doc = " where a = \\p qubit1, b = \\p qubit2."]
    #[doc = " \\p prob cannot exceed 3/4, at which maximal mixing occurs."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixDephasing()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] qubit1 qubit upon which to induce dephasing noise"]
    #[doc = " @param[in] qubit2 qubit upon which to induce dephasing noise"]
    #[doc = " @param[in] prob the probability of the phase error occuring"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if either \\p qubit1 or \\p qubit2 is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p qubit1 = \\p qubit2"]
    #[doc = " - if \\p prob is not in [0, 3/4]"]
    #[doc = " @author Tyson Jones (GPU, doc)"]
    #[doc = " @author Ania Brown (CPU, distributed)"]
    pub fn mixTwoQubitDephasing(
        qureg: Qureg,
        qubit1: ::std::os::raw::c_int,
        qubit2: ::std::os::raw::c_int,
        prob: f64,
    );
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit homogeneous depolarising noise."]
    #[doc = " This is equivalent to, with probability \\p prob, uniformly randomly applying"]
    #[doc = " either Pauli X, Y, or Z to \\p targetQubit."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{3} \\; \\left("]
    #[doc = "      X_q \\, \\rho \\, X_q +"]
    #[doc = "      Y_q \\, \\rho \\, Y_q +"]
    #[doc = "      Z_q \\, \\rho \\, Z_q"]
    #[doc = " \\right)"]
    #[doc = " \\f]"]
    #[doc = " where q = \\p targetQubit."]
    #[doc = " \\p prob cannot exceed 3/4, at which maximal mixing occurs."]
    #[doc = " The produced state is equivalently expressed as"]
    #[doc = " \\f["]
    #[doc = "      \\left( 1 - \\frac{4}{3} \\text{prob} \\right) \\rho +"]
    #[doc = "      \\left( \\frac{4}{3} \\text{prob} \\right) \\frac{\\vec{\\bf{1}}}{2}"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ \\frac{\\vec{\\bf{1}}}{2} \\f$ is the maximally mixed state of the target"]
    #[doc = " qubit."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixTwoQubitDepolarising()"]
    #[doc = " - mixDephasing()"]
    #[doc = " - mixDamping()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixPauli()"]
    #[doc = " - mixDensityMatrix()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] targetQubit qubit upon which to induce depolarising noise"]
    #[doc = " @param[in] prob the probability of the depolarising error occuring"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p prob is not in [0, 3/4]"]
    #[doc = " @author Tyson Jones (GPU, doc)"]
    #[doc = " @author Ania Brown (CPU, distributed)"]
    pub fn mixDepolarising(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit amplitude damping (decay to 0 state)."]
    #[doc = " With probability \\p prob, applies damping (transition from 1 to 0 state)."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = "K_0 \\rho K_0^\\dagger + K_1 \\rho K_1^\\dagger"]
    #[doc = " \\f]"]
    #[doc = " where q = \\p targetQubit and \\f$K_0\\f$ and \\f$K_1\\f$ are Kraus operators"]
    #[doc = " \\f["]
    #[doc = "K_0 = \\begin{pmatrix} 1 & 0 \\\\ 0 & \\sqrt{1-\\text{prob}} \\end{pmatrix}, \\;\\;"]
    #[doc = "K_1 = \\begin{pmatrix} 0 & \\sqrt{\\text{prob}} \\\\ 0 & 0 \\end{pmatrix}."]
    #[doc = " \\f]"]
    #[doc = " \\p prob cannot exceed 1, at which total damping/decay occurs. Note that unlike"]
    #[doc = " mixDephasing() and mixDepolarising(), this function can increase the purity of a"]
    #[doc = " mixed state (by, as \\p prob becomes 1, gaining certainty that the qubit is in"]
    #[doc = " the 0 state)."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixDephasing()"]
    #[doc = " - mixDepolarising()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixPauli()"]
    #[doc = " - mixDensityMatrix()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] targetQubit qubit upon which to induce amplitude damping"]
    #[doc = " @param[in] prob the probability of the damping"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p prob is not in [0, 1]"]
    #[doc = " @author Nicolas Vogt of HQS (local CPU)"]
    #[doc = " @author Ania Brown (GPU, patched local CPU)"]
    #[doc = " @author Tyson Jones (distributed, doc)"]
    pub fn mixDamping(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce two-qubit homogeneous depolarising noise."]
    #[doc = " With probability \\p prob, applies to \\p qubit1 and \\p qubit2 any operator of the set"]
    #[doc = " \\f$\\{ IX, IY, IZ, XI, YI, ZI, XX, XY, XZ, YX, YY, YZ, ZX, ZY, ZZ \\}\\f$."]
    #[doc = " Note this is the set of all two-qubit Pauli gates excluding \\f$II\\f$."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{prob}) \\, \\rho \\; + \\; \\frac{\\text{prob}}{15} \\; \\left("]
    #[doc = "      \\sum \\limits_{\\sigma_a \\in \\{X_a,Y_a,Z_a,I_a\\}}"]
    #[doc = "      \\sum \\limits_{\\sigma_b \\in \\{X_b,Y_b,Z_b,I_b\\}}"]
    #[doc = "      \\sigma_a \\sigma_b \\; \\rho \\; \\sigma_a \\sigma_b"]
    #[doc = " \\right)"]
    #[doc = " - \\frac{\\text{prob}}{15} I_a I_b \\; \\rho \\; I_a I_b"]
    #[doc = " \\f]"]
    #[doc = " or verbosely"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{15} \\; \\left("]
    #[doc = " \\begin{aligned}"]
    #[doc = "      &X_a \\, \\rho \\, X_a +"]
    #[doc = "      X_b \\, \\rho \\, X_b +"]
    #[doc = "      Y_a \\, \\rho \\, Y_a +"]
    #[doc = "      Y_b \\, \\rho \\, Y_b +"]
    #[doc = "      Z_a \\, \\rho \\, Z_a +"]
    #[doc = "      Z_b \\, \\rho \\, Z_b"]
    #[doc = "   \\\\"]
    #[doc = "    + &X_a X_b \\, \\rho \\, X_a X_b +"]
    #[doc = "      X_a Y_b \\, \\rho \\, X_a Y_b +"]
    #[doc = "      X_a Z_b \\, \\rho \\, X_a Z_b +"]
    #[doc = "      Y_a X_b \\, \\rho \\, Y_a X_b"]
    #[doc = " \\\\"]
    #[doc = "   + &Y_a Y_b \\, \\rho \\, Y_a Y_b +"]
    #[doc = "      Y_a Z_b \\, \\rho \\, Y_a Z_b +"]
    #[doc = "      Z_a X_b \\, \\rho \\, Z_a X_b +"]
    #[doc = "      Z_a Y_b \\, \\rho \\, Z_a Y_b +"]
    #[doc = "      Z_a Z_b \\, \\rho \\, Z_a Z_b"]
    #[doc = " \\end{aligned}"]
    #[doc = " \\right)"]
    #[doc = " \\f]"]
    #[doc = " where a = \\p qubit1, b = \\p qubit2."]
    #[doc = ""]
    #[doc = " \\p prob cannot exceed 15/16, at which maximal mixing occurs."]
    #[doc = ""]
    #[doc = " The produced state is equivalently expressed as"]
    #[doc = " \\f["]
    #[doc = "      \\left( 1 - \\frac{16}{15} \\text{prob} \\right) \\rho + \\left( \\frac{16}{15} \\text{prob} \\right) \\frac{\\vec{\\bf{1}}}{2}"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ \\frac{\\vec{\\bf{1}}}{2} \\f$ is the maximally mixed state of the two"]
    #[doc = " target qubits."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixDepolarising()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] qubit1 qubit upon which to induce depolarising noise"]
    #[doc = " @param[in] qubit2 qubit upon which to induce depolarising noise"]
    #[doc = " @param[in] prob the probability of the depolarising error occuring"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if either \\p qubit1 or \\p qubit2 is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p qubit1 = \\p qubit2"]
    #[doc = " - if \\p prob is not in [0, 15/16]"]
    #[doc = " @author Tyson Jones (GPU, doc)"]
    #[doc = " @author Ania Brown (CPU, distributed)"]
    pub fn mixTwoQubitDepolarising(
        qureg: Qureg,
        qubit1: ::std::os::raw::c_int,
        qubit2: ::std::os::raw::c_int,
        prob: f64,
    );
}
extern "C" {
    #[doc = " Mixes a density matrix \\p qureg to induce general single-qubit Pauli noise."]
    #[doc = " With probabilities \\p probX, \\p probY and \\p probZ, applies Pauli X, Y, and Z"]
    #[doc = " respectively to \\p targetQubit."]
    #[doc = ""]
    #[doc = " This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state"]
    #[doc = " \\f["]
    #[doc = " (1 - \\text{probX} - \\text{probY} - \\text{probZ}) \\, \\rho + \\;\\;\\;"]
    #[doc = "      (\\text{probX})\\; X_q \\, \\rho \\, X_q + \\;\\;\\;"]
    #[doc = "      (\\text{probY})\\; Y_q \\, \\rho \\, Y_q + \\;\\;\\;"]
    #[doc = "      (\\text{probZ})\\; Z_q \\, \\rho \\, Z_q"]
    #[doc = " \\f]"]
    #[doc = " where q = \\p targetQubit."]
    #[doc = " Each of \\p probX, \\p probY and \\p probZ cannot exceed the chance of no error:"]
    #[doc = " 1 - \\p probX - \\p probY - \\p probZ"]
    #[doc = ""]
    #[doc = " This function operates by first converting the given Pauli probabilities into"]
    #[doc = " a single-qubit Kraus map (four 2x2 operators)."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixDephasing()"]
    #[doc = " - mixDepolarising()"]
    #[doc = " - mixDamping()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixDensityMatrix()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg a density matrix"]
    #[doc = " @param[in] targetQubit qubit to decohere"]
    #[doc = " @param[in] probX the probability of inducing an X error"]
    #[doc = " @param[in] probY the probability of inducing an Y error"]
    #[doc = " @param[in] probZ the probability of inducing an Z error"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if any of \\p probX, \\p probY or \\p probZ are not in [0, 1]"]
    #[doc = " - if any of p in {\\p probX, \\p probY or \\p probZ} don't satisfy p <= (1 - \\p probX - \\p probY - \\p probZ)"]
    #[doc = " @author Balint Koczor"]
    #[doc = " @author Tyson Jones (refactored, doc)"]
    pub fn mixPauli(
        qureg: Qureg,
        targetQubit: ::std::os::raw::c_int,
        probX: f64,
        probY: f64,
        probZ: f64,
    );
}
extern "C" {
    #[doc = " Modifies combineQureg to become (1-\\p prob)\\p combineProb + \\p prob \\p otherQureg."]
    #[doc = " Both registers must be equal-dimension density matrices, and prob must be in [0, 1]."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - mixDephasing()"]
    #[doc = " - mixDepolarising()"]
    #[doc = " - mixDamping()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixPauli()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] combineQureg a density matrix to be modified"]
    #[doc = " @param[in] prob the probability of \\p otherQureg in the modified \\p combineQureg"]
    #[doc = " @param[in] otherQureg a density matrix to be mixed into \\p combineQureg"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p combineQureg or \\p otherQureg are not density matrices"]
    #[doc = " - if the dimensions of \\p combineQureg and \\p otherQureg do not match"]
    #[doc = " - if \\p prob is not in [0, 1]"]
    #[doc = " @author Tyson Jones"]
    pub fn mixDensityMatrix(combineQureg: Qureg, prob: f64, otherQureg: Qureg);
}
extern "C" {
    #[doc = " Calculates the purity of a density matrix, by the trace of the density matrix squared."]
    #[doc = " Returns \\f$\\text{Tr}(\\rho^2)\\f$."]
    #[doc = " For a pure state, this =1."]
    #[doc = " For a mixed state, the purity is less than 1 and is lower bounded by 1/2^n, where"]
    #[doc = " n is the number of qubits. The minimum purity is achieved for the maximally mixed state identity/2^n."]
    #[doc = ""]
    #[doc = " This function does not accept state-vectors, which clearly have purity 1."]
    #[doc = ""]
    #[doc = " Note this function will give incorrect results for non-Hermitian Quregs (i.e."]
    #[doc = " invalid density matrices), which will disagree with \\f$\\text{Tr}(\\rho^2)\\f$."]
    #[doc = " Instead, this function returns \\f$\\sum_{ij} |\\rho_{ij}|^2 \\f$."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcFidelity()"]
    #[doc = " - calcHilbertSchmidtDistance()"]
    #[doc = " - calcTotalProb()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg a density matrix of which to measure the purity"]
    #[doc = " @return the purity"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p combineQureg or \\p otherQureg are not density matrices"]
    #[doc = " - if the dimensions of \\p combineQureg and \\p otherQureg do not match"]
    #[doc = " - if \\p prob is not in [0, 1]"]
    #[doc = " @author Tyson Jones"]
    pub fn calcPurity(qureg: Qureg) -> f64;
}
extern "C" {
    #[doc = " Calculates the fidelity of \\p qureg (a state-vector or density matrix) against"]
    #[doc = " a reference pure state (necessarily a state-vector)."]
    #[doc = " If \\p qureg is a state-vector, this function computes"]
    #[doc = " \\f["]
    #[doc = "|\\langle \\text{qureg} | \\text{pureState} \\rangle|^2"]
    #[doc = " \\f]"]
    #[doc = " If \\p qureg is a density matrix, this function computes"]
    #[doc = " \\f["]
    #[doc = "\\langle \\text{pureState} | \\text{qureg} | \\text{pureState} \\rangle"]
    #[doc = " \\f]"]
    #[doc = " In either case, the returned fidelity lies in [0, 1] (assuming both input"]
    #[doc = " states have valid normalisation). If any of the input \\p Quregs are not"]
    #[doc = " normalised, this function will return the real component of the correct"]
    #[doc = " linear algebra calculation."]
    #[doc = ""]
    #[doc = " The number of qubits represented in \\p qureg and \\p pureState must match."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcHilbertSchmidtDistance()"]
    #[doc = " - calcPurity()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg a density matrix or state vector"]
    #[doc = " @param[in] pureState a state vector"]
    #[doc = " @return the fidelity between the input registers"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if the second argument (\\p pureState) is not a state-vector"]
    #[doc = " - if the number of qubits in \\p qureg and \\p pureState do not match"]
    #[doc = " @author Tyson Jones"]
    pub fn calcFidelity(qureg: Qureg, pureState: Qureg) -> f64;
}
extern "C" {
    #[doc = " Performs a SWAP gate between \\p qubit1 and \\p qubit2."]
    #[doc = " This effects"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & & 1 \\\\\\"]
    #[doc = " &  1 \\\\"]
    #[doc = " & & & 1"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the designated qubits, though is performed internally by three CNOT gates."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {qubit1};"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {qubit2};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 2) -- (2, 2);"]
    #[doc = "\\draw (0, 2) -- (0, 0);"]
    #[doc = "\\draw (-2,0) -- (2, 0);"]
    #[doc = ""]
    #[doc = "\\draw (-.35,-.35) -- (.35,.35);"]
    #[doc = "\\draw (-.35,.35) -- (.35,-.35);"]
    #[doc = ""]
    #[doc = "\\draw (-.35,-.35 + 2) -- (.35,.35 + 2);"]
    #[doc = "\\draw (-.35,.35 + 2) -- (.35,-.35 + 2);"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - sqrtSwapGate()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] qubit1 qubit to swap"]
    #[doc = " @param[in] qubit2 other qubit to swap"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p qubit1 or \\p qubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p qubit1 and \\p qubit2 are equal"]
    #[doc = " @author Tyson Jones"]
    pub fn swapGate(qureg: Qureg, qubit1: ::std::os::raw::c_int, qubit2: ::std::os::raw::c_int);
}
extern "C" {
    #[doc = " Apply a multi-controlled multi-target Z rotation, also known as a controlled phase gadget."]
    #[doc = " This is the unitary"]
    #[doc = " \\f["]
    #[doc = "    |1\\rangle\\langle 1|^{\\otimes\\, \\text{numControls}} \\; \\otimes \\,"]
    #[doc = "     \\exp \\left( - i \\, \\frac{\\theta}{2} \\; \\bigotimes_{j}^{\\text{numTargets}} Z_j\\right)"]
    #[doc = "     \\;\\;+\\;\\; \\sum\\limits_{k=0}^{2^{\\,\\text{numControls}} - 2} |k\\rangle\\langle k| \\otimes \\text{I}"]
    #[doc = " \\f]"]
    #[doc = " where the Pauli Z gates operate upon the qubits in `targetQubits`, and cause"]
    #[doc = " rotations of \\f$\\theta =\\f$ \\p angle."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-4, 1) {targets};"]
    #[doc = "\\node[draw=none] at (-4, 5) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 8) {$\\vdots$};"]
    #[doc = "\\draw (0, 7) -- (0, 6);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5, 6) -- (2.5, 6);"]
    #[doc = "\\draw[fill=black] (0, 6) circle (.2);"]
    #[doc = "\\draw (0, 6) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5, 4) -- (2.5, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5,0) -- (-1.5, 0);"]
    #[doc = "\\draw (1.5, 0) -- (2.5, 0);"]
    #[doc = "\\draw (-2.5,2) -- (-1.5, 2);"]
    #[doc = "\\draw (1.5, 2) -- (2.5, 2);"]
    #[doc = "\\draw (-1.5,-1)--(-1.5,3)--(1.5,3)--(1.5,-1);"]
    #[doc = "\\node[draw=none] at (0, 1) {$e^{-i\\frac{\\theta}{2}Z^{\\otimes}}$};"]
    #[doc = "\\node[draw=none] at (0, -1) {$\\vdots$};"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " > All qubits not appearing in \\p targetQubits and \\p controlQubits are assumed to receive the identity operator."]
    #[doc = ""]
    #[doc = " This has the effect of premultiplying all amplitudes (for which the control qubits are `1`)"]
    #[doc = " with \\f$\\exp(\\pm i \\theta/2)\\f$, where the sign is determined by the parity of"]
    #[doc = " the target qubits for that amplitude."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - multiControlledMultiRotatePauli()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - controlledRotateZ()"]
    #[doc = " - rotateZ()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits list of the indices of qubits to control upon"]
    #[doc = " @param[in] numControls length of length `controlQubits`"]
    #[doc = " @param[in] targetQubits a list of the indices of the target qubits"]
    #[doc = " @param[in] numTargets length of list `targetQubits`"]
    #[doc = " @param[in] angle the angle by which the multi-qubit state is rotated around the Z axis"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p controlQubits and \\p targetQubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p controlQubits or \\p targetQubits contain any repetitions"]
    #[doc = " - if any qubit in \\p controlQubits is also in \\p targetQubits (and vice versa)"]
    #[doc = " - if \\p numTargets <b>< 1</b>"]
    #[doc = " - if \\p numControls <b>< 1</b> (use multiRotateZ() for no controls)"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p controlQubits contains fewer elements than \\p numControls"]
    #[doc = " - if \\p targetQubits contains fewer elements than \\p numTargets"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledMultiRotateZ(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControls: ::std::os::raw::c_int,
        targetQubits: *mut ::std::os::raw::c_int,
        numTargets: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Apply a multi-controlled multi-target multi-Pauli rotation, also known as a"]
    #[doc = " controlled Pauli gadget."]
    #[doc = " This is the unitary"]
    #[doc = " \\f["]
    #[doc = "    |1\\rangle\\langle 1|^{\\otimes\\, \\text{numControls}} \\; \\otimes \\,"]
    #[doc = "     \\exp \\left( - i \\, \\frac{\\theta}{2} \\; \\bigotimes_{j}^{\\text{numTargets}} \\hat{\\sigma}_j\\right)"]
    #[doc = "     \\;\\;+\\;\\; \\sum\\limits_{k=0}^{2^{\\,\\text{numControls}} - 2} |k\\rangle\\langle k| \\otimes \\text{I}"]
    #[doc = " \\f]"]
    #[doc = " where \\f$\\hat{\\sigma}_j\\f$ are the Pauli operators (::pauliOpType) in `targetPaulis`, which operate"]
    #[doc = " upon the corresponding qubits in `targetQubits`."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-4, 1) {targets};"]
    #[doc = "\\node[draw=none] at (-4, 5) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 8) {$\\vdots$};"]
    #[doc = "\\draw (0, 7) -- (0, 6);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5, 6) -- (2.5, 6);"]
    #[doc = "\\draw[fill=black] (0, 6) circle (.2);"]
    #[doc = "\\draw (0, 6) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5, 4) -- (2.5, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2.5,0) -- (-1.5, 0);"]
    #[doc = "\\draw (1.5, 0) -- (2.5, 0);"]
    #[doc = "\\draw (-2.5,2) -- (-1.5, 2);"]
    #[doc = "\\draw (1.5, 2) -- (2.5, 2);"]
    #[doc = "\\draw (-1.5,-1)--(-1.5,3)--(1.5,3)--(1.5,-1);"]
    #[doc = "\\node[draw=none] at (0, 1) {$e^{-i\\frac{\\theta}{2} \\bigotimes\\limits_j \\hat{\\sigma}_j }$};"]
    #[doc = "\\node[draw=none] at (0, -1) {$\\vdots$};"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " > All qubits not appearing in \\p targetQubits and \\p controlQubits are assumed to receive the identity operator."]
    #[doc = ""]
    #[doc = " For example:"]
    #[doc = " ```"]
    #[doc = "     int numCtrls = 1;"]
    #[doc = "     int numTargs = 4;"]
    #[doc = "     int ctrls[] = {4};"]
    #[doc = "     int targs[] = {0,1,2,3};"]
    #[doc = ""]
    #[doc = "     pauliOpType paulis[] = {PAULI_X, PAULI_Y, PAULI_Z, PAULI_I};"]
    #[doc = ""]
    #[doc = "     multiControlledMultiRotatePauli("]
    #[doc = "         qureg, ctrls, numCtrls, targs, paulis, numTargs, 0.1);"]
    #[doc = " ```"]
    #[doc = " effects"]
    #[doc = " \\f["]
    #[doc = "    |1\\rangle\\langle 1 | \\otimes \\exp\\left( -i \\, (0.1/2) \\, X_0 \\, Y_1 \\, Z_2 \\right) \\, \\text{I}_3"]
    #[doc = "    \\;\\; + \\;\\; |0\\rangle\\langle 0| \\otimes \\text{I}^{\\otimes 4}"]
    #[doc = " \\f]"]
    #[doc = " on \\p qureg, where unspecified qubits (along with those targeted by `PAULI_I`) are"]
    #[doc = " assumed to receive the identity operator (excluded from exponentiation)."]
    #[doc = ""]
    #[doc = " > This means specifying `PAULI_I` does *not* induce a global phase factor \\f$\\exp(-i \\theta/2)\\f$."]
    #[doc = " > Hence, if all \\p targetPaulis are identity, then this function does nothing to \\p qureg."]
    #[doc = " > Specifying `PAULI_I` on a qubit is superfluous but allowed for convenience."]
    #[doc = ""]
    #[doc = " This function effects the controlled Pauli gadget by first (controlled)"]
    #[doc = " rotating the qubits which are targeted with either `X` or `Y` into alternate basis,"]
    #[doc = " performing multiControlledMultiRotateZ() on all target qubits, then restoring"]
    #[doc = " the original basis."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - multiControlledMultiRotateZ()"]
    #[doc = " - multiRotatePauli()"]
    #[doc = " - multiRotateZ()"]
    #[doc = " - rotateX()"]
    #[doc = " - rotateY()"]
    #[doc = " - rotateZ()"]
    #[doc = " - rotateAroundAxis()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits list of the indices of qubits to control upon"]
    #[doc = " @param[in] numControls length of length `controlQubits`"]
    #[doc = " @param[in] targetQubits a list of the indices of the target qubits"]
    #[doc = " @param[in] targetPaulis a list of the Pauli operators around which to rotate the target qubits"]
    #[doc = " @param[in] numTargets length of list `targetQubits`"]
    #[doc = " @param[in] angle the angle by which the multi-qubit state is rotated around the Z axis"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p controlQubits and \\p targetQubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p controlQubits or \\p targetQubits contain any repetitions"]
    #[doc = " - if any qubit in \\p controlQubits is also in \\p targetQubits (and vice versa)"]
    #[doc = " - if \\p numTargets <b>< 1</b>"]
    #[doc = " - if \\p numControls <b>< 1</b> (use multiRotateZ() for no controls)"]
    #[doc = " - if any element of \\p targetPaulis is not one of `PAULI_I`, `PAULI_X`, `PAULI_Y`, `PAULI_Z`"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p controlQubits contains fewer elements than \\p numControls"]
    #[doc = " - if \\p targetQubits contains fewer elements than \\p numTargets"]
    #[doc = " - if \\p targetPaulis contains fewer elements than \\p numTargets"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledMultiRotatePauli(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControls: ::std::os::raw::c_int,
        targetQubits: *mut ::std::os::raw::c_int,
        targetPaulis: *mut pauliOpType,
        numTargets: ::std::os::raw::c_int,
        angle: f64,
    );
}
extern "C" {
    #[doc = " Computes the expected value of a product of Pauli operators."]
    #[doc = " Letting \\f$ \\sigma = \\otimes_j \\hat{\\sigma}_j \\f$ be the operators indicated by \\p pauliCodes"]
    #[doc = " and acting on qubits \\p targetQubits, this function computes \\f$ \\langle \\psi | \\sigma | \\psi \\rangle \\f$"]
    #[doc = " if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(\\sigma \\rho) \\f$"]
    #[doc = " if \\p qureg = \\f$ \\rho \\f$ is a density matrix."]
    #[doc = ""]
    #[doc = " \\p pauliCodes is an array of length \\p numTargets which specifies which Pauli operators to"]
    #[doc = " enact on the corresponding qubits in \\p targetQubits, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,"]
    #[doc = " 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. The target qubits must be unique, and at most \\p qureg.numQubitsRepresented"]
    #[doc = " may be specified. For example, on a 7-qubit state-vector,"]
    #[doc = " ```"]
    #[doc = "     calcExpecPauliProd(qureg, {4,5,6}, {PAULI_X, PAULI_I, PAULI_Z}, 3, workspace);"]
    #[doc = " ```"]
    #[doc = " will compute \\f$ \\langle \\psi | I I I I X I Z | \\psi \\rangle \\f$ (where in this notation, the left-most operator"]
    #[doc = " applies to the least-significant qubit, i.e. that with index 0)."]
    #[doc = ""]
    #[doc = " \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions"]
    #[doc = " (number of represented qubits) as \\p qureg, and is used as working space. When this function returns, \\p qureg"]
    #[doc = " will be unchanged and \\p workspace will be set to \\f$ \\sigma | \\psi \\rangle \\f$ (if \\p qureg is a state-vector)"]
    #[doc = " or \\f$ \\sigma \\rho \\f$ (if \\p qureg is a density matrix). NOTE that this last quantity is NOT the result of applying"]
    #[doc = " the paulis as unitaries, \\f$ \\sigma^\\dagger \\rho \\sigma \\f$, but is instead the result of their direct"]
    #[doc = " multiplication with the density matrix. It is therefore itself not a valid density matrix."]
    #[doc = ""]
    #[doc = " This function works by cloning the \\p qureg state into \\p workspace, applying the specified"]
    #[doc = " Pauli operators to \\p workspace then computing its inner product with \\p qureg (for state-vectors)"]
    #[doc = " or its trace (for density matrices). It therefore should scale linearly in time with the number of"]
    #[doc = " specified non-identity Pauli operators, which is bounded by the number of represented qubits."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcExpecDiagonalOp()"]
    #[doc = " - calcExpecPauliSum()"]
    #[doc = " - calcExpecPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg the register of which to find the expected value, which is unchanged by this function"]
    #[doc = " @param[in] targetQubits a list of the indices of the target qubits"]
    #[doc = " @param[in] pauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)"]
    #[doc = "      to apply to the corresponding qubits in \\p targetQubits"]
    #[doc = " @param[in] numTargets number of target qubits, i.e. the length of \\p targetQubits and \\p pauliCodes"]
    #[doc = " @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified"]
    #[doc = "      to be the result of multiplying the state with the pauli operators"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p numTargets is outside [1, \\p qureg.numQubitsRepresented])"]
    #[doc = " - if any qubit in \\p targetQubits is outside [0, \\p qureg.numQubitsRepresented))"]
    #[doc = " - if any qubit in \\p targetQubits is repeated"]
    #[doc = " - if any code in \\p pauliCodes is not in {0,1,2,3}"]
    #[doc = " - if \\p workspace is not of the same type and dimensions as \\p qureg"]
    #[doc = " @author Tyson Jones"]
    pub fn calcExpecPauliProd(
        qureg: Qureg,
        targetQubits: *mut ::std::os::raw::c_int,
        pauliCodes: *mut pauliOpType,
        numTargets: ::std::os::raw::c_int,
        workspace: Qureg,
    ) -> f64;
}
extern "C" {
    #[doc = " Computes the expected value of a sum of products of Pauli operators."]
    #[doc = " Let \\f$ H = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$ be"]
    #[doc = " the operators indicated by \\p allPauliCodes (where \\f$ c_i \\in \\f$ \\p termCoeffs"]
    #[doc = " and \\f$ N = \\f$ \\p qureg.numQubitsRepresented)."]
    #[doc = " This function computes \\f$ \\langle \\psi | H | \\psi \\rangle \\f$"]
    #[doc = " if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(H \\rho) =\\text{Trace}(\\rho H) \\f$"]
    #[doc = " if \\p qureg = \\f$ \\rho \\f$ is a density matrix."]
    #[doc = ""]
    #[doc = " \\p allPauliCodes is an array of length \\p numSumTerms*\\p qureg.numQubitsRepresented"]
    #[doc = " which specifies which Pauli operators to apply, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,"]
    #[doc = " 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. For each sum term, a Pauli operator must be specified for"]
    #[doc = " EVERY qubit in \\p qureg; each set of \\p numSumTerms operators will be grouped into a product."]
    #[doc = " \\p termCoeffs is an arrray of length \\p numSumTerms containing the term coefficients."]
    #[doc = " For example, on a 3-qubit state-vector,"]
    #[doc = " ```"]
    #[doc = "     int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};"]
    #[doc = "     qreal coeffs[2] = {1.5, -3.6};"]
    #[doc = "     calcExpecPauliSum(qureg, paulis, coeffs, 2, workspace);"]
    #[doc = " ```"]
    #[doc = " will compute \\f$ \\langle \\psi | (1.5 X I I - 3.6 X Y Z) | \\psi \\rangle \\f$ (where in this notation, the left-most operator"]
    #[doc = " applies to the least-significant qubit, i.e. that with index 0)."]
    #[doc = ""]
    #[doc = " \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions"]
    #[doc = " (number of represented qubits) as \\p qureg, and is used as working space. When this function returns, \\p qureg"]
    #[doc = " will be unchanged and \\p workspace will be set to \\p qureg pre-multiplied with the final Pauli product."]
    #[doc = " NOTE that if \\p qureg is a density matrix, \\p workspace will become \\f$ \\hat{\\sigma} \\rho \\f$"]
    #[doc = " which is itself not a density matrix (it is distinct from \\f$ \\hat{\\sigma} \\rho \\hat{\\sigma}^\\dagger \\f$)."]
    #[doc = ""]
    #[doc = " This function works by cloning the \\p qureg state into \\p workspace, applying each of the specified"]
    #[doc = " Pauli products to \\p workspace (one Pauli operation at a time), then computing its inner product with \\p qureg (for state-vectors)"]
    #[doc = " or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions."]
    #[doc = " It therefore should scale linearly in time with the total number of non-identity specified Pauli operators."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcExpecDiagonalOp()"]
    #[doc = " - calcExpecPauliProd()"]
    #[doc = " - calcExpecPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg the register of which to find the expected value, which is unchanged by this function"]
    #[doc = " @param[in] allPauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)"]
    #[doc = "      of all Paulis involved in the products of terms. A Pauli must be specified for each qubit"]
    #[doc = "      in the register, in every term of the sum."]
    #[doc = " @param[in] termCoeffs The coefficients of each term in the sum of Pauli products"]
    #[doc = " @param[in] numSumTerms The total number of Pauli products specified"]
    #[doc = " @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified"]
    #[doc = "      to be the result of multiplying the state with the final specified Pauli product"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any code in \\p allPauliCodes is not in {0,1,2,3}"]
    #[doc = " - if \\p numSumTerms <= 0,"]
    #[doc = " - if \\p workspace is not of the same type and dimensions as \\p qureg"]
    #[doc = " @author Tyson Jones"]
    pub fn calcExpecPauliSum(
        qureg: Qureg,
        allPauliCodes: *mut pauliOpType,
        termCoeffs: *mut f64,
        numSumTerms: ::std::os::raw::c_int,
        workspace: Qureg,
    ) -> f64;
}
extern "C" {
    #[doc = " Computes the expected value of \\p qureg under Hermitian operator \\p hamil."]
    #[doc = " Represent \\p hamil as \\f$ H = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$"]
    #[doc = "  (where \\f$ c_i \\in \\f$ \\p hamil.termCoeffs and \\f$ N = \\f$ \\p hamil.numQubits)."]
    #[doc = " This function computes \\f$ \\langle \\psi | H | \\psi \\rangle \\f$"]
    #[doc = " if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(H \\rho) =\\text{Trace}(\\rho H) \\f$"]
    #[doc = " if \\p qureg = \\f$ \\rho \\f$ is a density matrix."]
    #[doc = ""]
    #[doc = " This function is merely an encapsulation of calcExpecPauliSum() - refer to the doc"]
    #[doc = " there for an elaboration."]
    #[doc = ""]
    #[doc = " \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions"]
    #[doc = " (number of represented qubits) as \\p qureg and \\p hamil, and is used as working space."]
    #[doc = " When this function returns, \\p qureg  will be unchanged and \\p workspace will be set to"]
    #[doc = " \\p qureg pre-multiplied with the final Pauli product in \\p hamil."]
    #[doc = " NOTE that if \\p qureg is a density matrix, \\p workspace will become \\f$ \\hat{\\sigma} \\rho \\f$"]
    #[doc = " which is itself not a density matrix (it is distinct from \\f$ \\hat{\\sigma} \\rho \\hat{\\sigma}^\\dagger \\f$)."]
    #[doc = ""]
    #[doc = " This function works by cloning the \\p qureg state into \\p workspace, applying each of the specified"]
    #[doc = " Pauli products in \\p hamil to \\p workspace (one Pauli operation at a time), then computing its inner product with \\p qureg (for state-vectors)"]
    #[doc = " or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions."]
    #[doc = " It therefore should scale linearly in time with the total number of non-identity specified Pauli operators."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - calcExpecDiagonalOp()"]
    #[doc = " - calcExpecPauliSum()"]
    #[doc = " - calcExpecPauliProd()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] qureg the register of which to find the expected value, which is unchanged by this function"]
    #[doc = " @param[in] hamil a \\p PauliHamil created with createPauliHamil() or createPauliHamilFromFile()"]
    #[doc = " @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified"]
    #[doc = "      to be the result of multiplying the state with the final specified Pauli product"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any code in \\p hamil.pauliCodes is not a valid Pauli code"]
    #[doc = " - if \\p hamil.numSumTerms <= 0"]
    #[doc = " - if \\p workspace is not of the same type and dimensions as \\p qureg and \\p hamil"]
    #[doc = " @author Tyson Jones"]
    pub fn calcExpecPauliHamil(qureg: Qureg, hamil: PauliHamil, workspace: Qureg) -> f64;
}
extern "C" {
    #[doc = " Apply a general two-qubit unitary (including a global phase factor)."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target2};"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {target1};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that"]
    #[doc = " a row in \\p u is dotted with the vector"]
    #[doc = " \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$"]
    #[doc = ""]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = "     twoQubitUnitary(qureg, a, b, u);"]
    #[doc = " ```"]
    #[doc = " will invoke multiplication"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " u_{00} & u_{01} & u_{02} & u_{03} \\\\"]
    #[doc = " u_{10} & u_{11} & u_{12} & u_{13} \\\\"]
    #[doc = " u_{20} & u_{21} & u_{22} & u_{23} \\\\"]
    #[doc = " u_{30} & u_{31} & u_{32} & u_{33}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " |ba\\rangle = |00\\rangle \\\\"]
    #[doc = " |ba\\rangle = |01\\rangle \\\\"]
    #[doc = " |ba\\rangle = |10\\rangle \\\\"]
    #[doc = " |ba\\rangle = |11\\rangle"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " The passed ::ComplexMatrix4 must be unitary, otherwise an error is thrown."]
    #[doc = " > Use applyMatrix4() to left-multiply a non-unitary ::ComplexMatrix4."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q/4 nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix4"]
    #[doc = " - controlledTwoQubitUnitary()"]
    #[doc = " - multiControlledTwoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - applyMatrix4()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u"]
    #[doc = " @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targetQubit1 equals \\p targetQubit2"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " - if each node cannot fit 4 amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn twoQubitUnitary(
        qureg: Qureg,
        targetQubit1: ::std::os::raw::c_int,
        targetQubit2: ::std::os::raw::c_int,
        u: ComplexMatrix4,
    );
}
extern "C" {
    #[doc = " Apply a general controlled two-qubit unitary (including a global phase factor)."]
    #[doc = " The given unitary is applied to the target amplitudes where the control qubit has value 1."]
    #[doc = " This effects the many-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\"]
    #[doc = " & & 1 \\\\"]
    #[doc = " & & & 1 \\\\"]
    #[doc = " & & & & u_{00} & u_{01} & u_{02} & u_{03} \\\\"]
    #[doc = " & & & & u_{10} & u_{11} & u_{12} & u_{13} \\\\"]
    #[doc = " & & & & u_{20} & u_{21} & u_{22} & u_{23} \\\\"]
    #[doc = " & & & & u_{30} & u_{31} & u_{32} & u_{33}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = " \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that"]
    #[doc = " a row in \\p u is dotted with the vector"]
    #[doc = " \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$"]
    #[doc = ""]
    #[doc = " The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target1};"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {target2};"]
    #[doc = "\\node[draw=none] at (-3.5, 4) {control};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q/4 nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix4"]
    #[doc = " - multiControlledTwoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - unitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubit the control qubit which must be in state 1 to effect the given unitary"]
    #[doc = " @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u"]
    #[doc = " @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p controlQubit, \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if any of \\p controlQubit, \\p targetQubit1 and \\p targetQubit2 are equal"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = "  - if each node cannot fit 4 amplitudes in distributed mode."]
    #[doc = " @author Tyson Jones"]
    pub fn controlledTwoQubitUnitary(
        qureg: Qureg,
        controlQubit: ::std::os::raw::c_int,
        targetQubit1: ::std::os::raw::c_int,
        targetQubit2: ::std::os::raw::c_int,
        u: ComplexMatrix4,
    );
}
extern "C" {
    #[doc = " Apply a general multi-controlled two-qubit unitary (including a global phase factor)."]
    #[doc = " Any number of control qubits can be specified, and if all have value 1,"]
    #[doc = " the given unitary is applied to the target qubit."]
    #[doc = " This effects the many-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & u_{00} & u_{01} & u_{02} & u_{03} \\\\"]
    #[doc = " & & & u_{10} & u_{11} & u_{12} & u_{13} \\\\"]
    #[doc = " & & & u_{20} & u_{21} & u_{22} & u_{23} \\\\"]
    #[doc = " & & & u_{30} & u_{31} & u_{32} & u_{33}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = " \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that"]
    #[doc = " a row in \\p u is dotted with the vector"]
    #[doc = " \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$"]
    #[doc = ""]
    #[doc = " The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 0) {target1};"]
    #[doc = "\\node[draw=none] at (-3.5, 2) {target2};"]
    #[doc = "\\node[draw=none] at (-3.5, 5) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 8) {$\\vdots$};"]
    #[doc = "\\draw (0, 7) -- (0, 6);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 6) -- (2, 6);"]
    #[doc = "\\draw[fill=black] (0, 6) circle (.2);"]
    #[doc = "\\draw (0, 6) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q/4 nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix4"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - controlledTwoQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - unitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] controlQubits the control qubits which all must be in state 1 to effect the given unitary"]
    #[doc = " @param[in] numControlQubits the number of control qubits"]
    #[doc = " @param[in] targetQubit1 first target qubit, treated as least significant in \\p u"]
    #[doc = " @param[in] targetQubit2 second target qubit, treated as most significant in \\p u"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targetQubit1 equals \\p targetQubit2"]
    #[doc = " - if any qubit in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p controlQubits are not unique"]
    #[doc = " - if either \\p targetQubit1 and \\p targetQubit2 are in \\p controlQubits"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " - if each node cannot fit 4 amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledTwoQubitUnitary(
        qureg: Qureg,
        controlQubits: *mut ::std::os::raw::c_int,
        numControlQubits: ::std::os::raw::c_int,
        targetQubit1: ::std::os::raw::c_int,
        targetQubit2: ::std::os::raw::c_int,
        u: ComplexMatrix4,
    );
}
extern "C" {
    #[doc = " Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubits."]
    #[doc = ""]
    #[doc = " The first target qubit in \\p targs is treated as \\b least significant in \\p u."]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = "     multiQubitUnitary(qureg, (int []) {a, b, c}, 3, u);"]
    #[doc = " ```"]
    #[doc = " will invoke multiplication"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " u_{00} & u_{01} & u_{02} & u_{03} & u_{04} & u_{05} & u_{06} & u_{07} \\\\"]
    #[doc = " u_{10} & u_{11} & u_{12} & u_{13} & u_{14} & u_{15} & u_{16} & u_{17} \\\\"]
    #[doc = " u_{20} & u_{21} & u_{22} & u_{23} & u_{24} & u_{25} & u_{26} & u_{27} \\\\"]
    #[doc = " u_{30} & u_{31} & u_{32} & u_{33} & u_{34} & u_{35} & u_{36} & u_{37} \\\\"]
    #[doc = " u_{40} & u_{41} & u_{42} & u_{43} & u_{44} & u_{45} & u_{46} & u_{47} \\\\"]
    #[doc = " u_{50} & u_{51} & u_{52} & u_{53} & u_{54} & u_{55} & u_{56} & u_{57} \\\\"]
    #[doc = " u_{60} & u_{61} & u_{62} & u_{63} & u_{64} & u_{65} & u_{66} & u_{67} \\\\"]
    #[doc = " u_{70} & u_{71} & u_{72} & u_{73} & u_{74} & u_{75} & u_{76} & u_{77} \\\\"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " |cba\\rangle = |000\\rangle \\\\"]
    #[doc = " |cba\\rangle = |001\\rangle \\\\"]
    #[doc = " |cba\\rangle = |010\\rangle \\\\"]
    #[doc = " |cba\\rangle = |011\\rangle \\\\"]
    #[doc = " |cba\\rangle = |100\\rangle \\\\"]
    #[doc = " |cba\\rangle = |101\\rangle \\\\"]
    #[doc = " |cba\\rangle = |110\\rangle \\\\"]
    #[doc = " |cba\\rangle = |111\\rangle"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " The passed ComplexMatrix must be unitary and be a compatible size with the specified number of"]
    #[doc = " target qubits, otherwise an error is thrown."]
    #[doc = " > To left-multiply a non-unitary ::ComplexMatrixN, use applyMatrixN()."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 1) {targets};"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\node[draw=none] at (0, -1) {$\\vdots$};"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,"]
    #[doc = " and store these in the runtime stack."]
    #[doc = " Using t threads, the total memory overhead of this function is t*2^\\p numTargs."]
    #[doc = " For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault"]
    #[doc = " (e.g. on a 1 MiB stack)."]
    #[doc = ""]
    #[doc = " Note too that in distributed mode, this routine requires that each node contains"]
    #[doc = " at least 2^\\p numTargs amplitudes in the register. This means an q-qubit register (state vector or density matrix)"]
    #[doc = " can be distributed by at most 2^q / 2^\\p numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = " - controlledMultiQubitUnitary()"]
    #[doc = " - multiControlledMultiQubitUnitary()"]
    #[doc = " - applyMatrixN()"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = " - unitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targs a list of the target qubits, ordered least significant to most in \\p u"]
    #[doc = " @param[in] numTargs the number of target qubits"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targs are not unique"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " - if \\p u is not of a compatible size with \\p numTargs"]
    #[doc = " - if a node cannot fit the required number of target amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn multiQubitUnitary(
        qureg: Qureg,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
        u: ComplexMatrixN,
    );
}
extern "C" {
    #[doc = " Apply a general controlled multi-qubit unitary (including a global phase factor)."]
    #[doc = " One control and any number of target qubits can be specified."]
    #[doc = " This effects the many-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & 1 \\\\"]
    #[doc = " & & & 1 \\\\"]
    #[doc = " & & & & u_{00} & u_{01} & \\dots  \\\\"]
    #[doc = " & & & & u_{10} & u_{11} & \\dots \\\\"]
    #[doc = " & & & & \\vdots & \\vdots & \\ddots"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = " The target qubits in \\p targs are treated as ordered least significant"]
    #[doc = " to most significant in \\p u."]
    #[doc = ""]
    #[doc = " The passed ComplexMatrix must be unitary and be a compatible size with the specified number of"]
    #[doc = " target qubits, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 1) {targets};"]
    #[doc = "\\node[draw=none] at (-3.5, 4) {control};"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\node[draw=none] at (0, -1) {$\\vdots$};"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,"]
    #[doc = " and store these in the runtime stack."]
    #[doc = " Using t threads, the total memory overhead of this function is t*2^\\p numTargs."]
    #[doc = " For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault"]
    #[doc = " (e.g. on a 1 MiB stack)."]
    #[doc = ""]
    #[doc = " Note too that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q / 2^\\p numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = " - multiControlledMultiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] ctrl the control qubit"]
    #[doc = " @param[in] targs a list of the target qubits, ordered least to most significant"]
    #[doc = " @param[in] numTargs the number of target qubits"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p ctrl or any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targs are not unique"]
    #[doc = " - if \\p targs contains \\p ctrl"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " - if a node cannot fit the required number of target amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn controlledMultiQubitUnitary(
        qureg: Qureg,
        ctrl: ::std::os::raw::c_int,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
        u: ComplexMatrixN,
    );
}
extern "C" {
    #[doc = " Apply a general multi-controlled multi-qubit unitary (including a global phase factor)."]
    #[doc = " Any number of control and target qubits can be specified."]
    #[doc = " This effects the many-qubit unitary"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & u_{00} & u_{01} & \\dots  \\\\"]
    #[doc = " & & & u_{10} & u_{11} & \\dots \\\\"]
    #[doc = " & & & \\vdots & \\vdots & \\ddots"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = " The target qubits in \\p targs are treated as ordered least significant"]
    #[doc = " to most significant in \\p u."]
    #[doc = ""]
    #[doc = " The passed ::ComplexMatrixN must be unitary and be a compatible size with the specified number of"]
    #[doc = " target qubits, otherwise an error is thrown."]
    #[doc = " > To left-multiply a non-unitary ::ComplexMatrixN, including control qubits,"]
    #[doc = " > use applyMultiControlledMatrixN()"]
    #[doc = ""]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\node[draw=none] at (-3.5, 1) {targets};"]
    #[doc = "\\node[draw=none] at (-3.5, 5) {controls};"]
    #[doc = ""]
    #[doc = "\\node[draw=none] at (0, 8) {$\\vdots$};"]
    #[doc = "\\draw (0, 7) -- (0, 6);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 6) -- (2, 6);"]
    #[doc = "\\draw[fill=black] (0, 6) circle (.2);"]
    #[doc = "\\draw (0, 6) -- (0, 4);"]
    #[doc = ""]
    #[doc = "\\draw (-2, 4) -- (2, 4);"]
    #[doc = "\\draw[fill=black] (0, 4) circle (.2);"]
    #[doc = "\\draw(0, 4) -- (0, 3);"]
    #[doc = ""]
    #[doc = "\\draw (-2,0) -- (-1, 0);"]
    #[doc = "\\draw (1, 0) -- (2, 0);"]
    #[doc = "\\draw (-2,2) -- (-1, 2);"]
    #[doc = "\\draw (1, 2) -- (2, 2);"]
    #[doc = "\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);"]
    #[doc = "\\node[draw=none] at (0, 1) {U};"]
    #[doc = "\\node[draw=none] at (0, -1) {$\\vdots$};"]
    #[doc = ""]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = ""]
    #[doc = " Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,"]
    #[doc = " and store these in the runtime stack."]
    #[doc = " Using t threads, the total memory overhead of this function is t*2^\\p numTargs."]
    #[doc = " For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault"]
    #[doc = " (e.g. on a 1 MiB stack)."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q / 2^\\p numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = " - applyMultiControlledMatrixN()"]
    #[doc = " - multiControlledMultiQubitNot()"]
    #[doc = " - controlledMultiQubitUnitary()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup unitary"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] ctrls a list of the control qubits"]
    #[doc = " @param[in] numCtrls the number of control qubits"]
    #[doc = " @param[in] targs a list of the target qubits, ordered least to most significant"]
    #[doc = " @param[in] numTargs the number of target qubits"]
    #[doc = " @param[in] u unitary matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p ctrls and \\p targs is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p ctrls or \\p targs contain any repetitions"]
    #[doc = " - if any qubit in \\p ctrls is also in \\p targs (and vice versa)"]
    #[doc = " - if \\p numTargs <b>< 1</b>"]
    #[doc = " - if \\p numCtrls <b>< 1</b> (use multiQubitUnitary() for no controls)"]
    #[doc = " - if matrix \\p u is not unitary"]
    #[doc = " - if a node cannot fit the required number of target amplitudes in distributed mode"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p ctrls contains fewer elements than \\p numCtrls"]
    #[doc = " - if \\p targs contains fewer elements than \\p numTargs"]
    #[doc = " @author Tyson Jones"]
    pub fn multiControlledMultiQubitUnitary(
        qureg: Qureg,
        ctrls: *mut ::std::os::raw::c_int,
        numCtrls: ::std::os::raw::c_int,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
        u: ComplexMatrixN,
    );
}
extern "C" {
    #[doc = " Apply a general single-qubit Kraus map to a density matrix, as specified by at most"]
    #[doc = " four Kraus operators, \\f$K_i\\f$ (\\p ops). A Kraus map is also referred to as"]
    #[doc = " a \"operator-sum representation\" of a quantum channel, and enables the simulation of"]
    #[doc = " general single-qubit noise process,"]
    #[doc = " by effecting"]
    #[doc = " \\f["]
    #[doc = "\\rho \\to \\sum\\limits_i^{\\text{numOps}} K_i \\rho K_i^\\dagger"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " The Kraus map must be completely positive and trace preserving, which constrains each"]
    #[doc = " \\f$ K_i \\f$ in \\p ops by"]
    #[doc = " \\f["]
    #[doc = "\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ I \\f$ is the identity matrix."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes."]
    #[doc = " This means an q-qubit register can be distributed by at most 2^(q-2) numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix2"]
    #[doc = " - mixTwoQubitKrausMap()"]
    #[doc = " - mixMultiQubitKrausMap()"]
    #[doc = " - mixDephasing()"]
    #[doc = " - mixDepolarising()"]
    #[doc = " - mixDamping()"]
    #[doc = " - mixPauli()"]
    #[doc = " - mixDensityMatrix()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg the density matrix to which to apply the map"]
    #[doc = " @param[in] target the target qubit of the map"]
    #[doc = " @param[in] ops an array of at most 4 Kraus operators"]
    #[doc = " @param[in] numOps the number of operators in \\p ops which must be >0 and <= 4."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if \\p target is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p numOps is outside [1, 4]"]
    #[doc = " - if \\p ops do not create a completely positive, trace preserving map"]
    #[doc = " - if a node cannot fit 4 amplitudes in distributed mode"]
    #[doc = " @author Balint Koczor"]
    #[doc = " @author Tyson Jones (refactored, doc)"]
    pub fn mixKrausMap(
        qureg: Qureg,
        target: ::std::os::raw::c_int,
        ops: *mut ComplexMatrix2,
        numOps: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply a general two-qubit Kraus map to a density matrix, as specified by at most"]
    #[doc = " sixteen Kraus operators. A Kraus map is also referred to as a \"operator-sum representation\""]
    #[doc = " of a quantum channel. This allows one to simulate a general two-qubit noise process."]
    #[doc = ""]
    #[doc = " The Kraus map must be completely positive and trace preserving, which constrains each"]
    #[doc = " \\f$ K_i \\f$ in \\p ops by"]
    #[doc = " \\f["]
    #[doc = "\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ I \\f$ is the identity matrix."]
    #[doc = ""]
    #[doc = " \\p targetQubit1 is treated as the \\p least significant qubit in each op in \\p ops."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 16 amplitudes."]
    #[doc = " This means an q-qubit register can be distributed by at most 2^(q-4) numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix4"]
    #[doc = " - mixMultiQubitKrausMap()"]
    #[doc = " - mixKrausMap()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg the density matrix to which to apply the map"]
    #[doc = " @param[in] target1 the least significant target qubit in \\p ops"]
    #[doc = " @param[in] target2 the most significant target qubit in \\p ops"]
    #[doc = " @param[in] ops an array of at most 16 Kraus operators"]
    #[doc = " @param[in] numOps the number of operators in \\p ops which must be >0 and <= 16."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if either \\p target1 or \\p target2 is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p target1 = \\p target2"]
    #[doc = " - if \\p numOps is outside [1, 16]"]
    #[doc = " - if \\p ops do not create a completely positive, trace preserving map"]
    #[doc = " - if a node cannot fit 16 amplitudes in distributed mode"]
    #[doc = " @author Balint Koczor"]
    #[doc = " @author Tyson Jones (refactored, doc)"]
    pub fn mixTwoQubitKrausMap(
        qureg: Qureg,
        target1: ::std::os::raw::c_int,
        target2: ::std::os::raw::c_int,
        ops: *mut ComplexMatrix4,
        numOps: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply a general N-qubit Kraus map to a density matrix, as specified by at most (2N)^2"]
    #[doc = " Kraus operators. This allows one to simulate a general noise process."]
    #[doc = ""]
    #[doc = " The Kraus map must be completely positive and trace preserving, which constrains each"]
    #[doc = " \\f$ K_i \\f$ in \\p ops by"]
    #[doc = " \\f["]
    #[doc = "\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ I \\f$ is the identity matrix."]
    #[doc = ""]
    #[doc = " The first qubit in \\p targets is treated as the \\p least significant qubit in each op in \\p ops."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least (2N)^2 amplitudes."]
    #[doc = " This means an q-qubit register can be distributed by at most 2^(q-2)/N^2 nodes."]
    #[doc = ""]
    #[doc = " Note too that this routine internally creates a 'superoperator'; a complex matrix of dimensions"]
    #[doc = " 2^(2*numTargets) by 2^(2*numTargets). Therefore, invoking this function incurs,"]
    #[doc = " for numTargs={1,2,3,4,5, ...}, an additional memory overhead of (at double-precision)"]
    #[doc = " {0.25 KiB, 4 KiB, 64 KiB, 1 MiB, 16 MiB, ...} (respectively)."]
    #[doc = " At quad precision (usually 10 B per number, but possibly 16 B due to alignment),"]
    #[doc = " this costs at most double the amount of memory."]
    #[doc = " For numTargets < 4, this superoperator will be created in the runtime"]
    #[doc = " stack. For numTargs >= 4, the superoperator will be allocated in the heap and"]
    #[doc = " therefore this routine may suffer an anomalous slowdown."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = " - initComplexMatrixN()"]
    #[doc = " - mixKrausMap()"]
    #[doc = " - mixTwoQubitKrausMap()"]
    #[doc = ""]
    #[doc = " @ingroup decoherence"]
    #[doc = " @param[in,out] qureg the density matrix to which to apply the map"]
    #[doc = " @param[in] targets a list of target qubit indices, the first of which is treated as least significant in each op in \\p ops"]
    #[doc = " @param[in] numTargets the length of \\p targets"]
    #[doc = " @param[in] ops an array of at most (2N)^2 Kraus operators"]
    #[doc = " @param[in] numOps the number of operators in \\p ops which must be >0 and <= (2N)^2."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg is not a density matrix"]
    #[doc = " - if any target in \\p targets is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if any qubit in \\p targets is repeated"]
    #[doc = " - if \\p numOps is outside [1, (2 \\p numTargets)^2]"]
    #[doc = " - if any ComplexMatrixN in \\p ops does not have op.numQubits == \\p numTargets"]
    #[doc = " - if \\p ops do not create a completely positive, trace preserving map"]
    #[doc = " - if a node cannot fit (2N)^2 amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    #[doc = " @author Balint Koczor"]
    pub fn mixMultiQubitKrausMap(
        qureg: Qureg,
        targets: *mut ::std::os::raw::c_int,
        numTargets: ::std::os::raw::c_int,
        ops: *mut ComplexMatrixN,
        numOps: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Computes the Hilbert Schmidt distance between two density matrices \\p a and \\p b,"]
    #[doc = " defined as the Frobenius norm of the difference between them."]
    #[doc = " That is, we define the Hilbert Schmidt distance"]
    #[doc = " \\f["]
    #[doc = "D(a, b) = \\| a - b \\|_F = \\sqrt{  \\text{Tr}[ (a-b)(a-b)^\\dagger ]   }"]
    #[doc = " \\f]"]
    #[doc = " This is equivalent to the square-root of the sum of the absolute value squared of the"]
    #[doc = " element-differences of the matrices, i.e."]
    #[doc = " \\f["]
    #[doc = "D(a, b) = \\sqrt{ \\sum\\limits_i \\sum\\limits_j | a_{ij} - b_{ij} |^2 }"]
    #[doc = " \\f]"]
    #[doc = " We caution this may differ by some definitions of the Hilbert Schmidt distance"]
    #[doc = " by a square-root."]
    #[doc = ""]
    #[doc = " This function correctly returns the result of the above formulations even when"]
    #[doc = " \\p a and \\p b are incorrectly normalised (i.e. are general matrices)."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcDensityInnerProduct()"]
    #[doc = " - calcFidelity()"]
    #[doc = " - calcPurity()"]
    #[doc = ""]
    #[doc = " @ingroup calc"]
    #[doc = " @param[in] a a density matrix"]
    #[doc = " @param[in] b an equally-sized density matrix"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if either \\p a or \\p b are not density matrices"]
    #[doc = " - if \\p a and \\p have mismatching dimensions"]
    #[doc = " @author Balint Koczor"]
    #[doc = " @author Tyson Jones (refactored, doc)"]
    pub fn calcHilbertSchmidtDistance(a: Qureg, b: Qureg) -> f64;
}
extern "C" {
    #[doc = " Modifies qureg \\p out to the result of (\\p facOut \\p out + \\p fac1 \\p qureg1 + \\p fac2 \\p qureg2),"]
    #[doc = " imposing no constraints on normalisation. Works for both state-vectors and density matrices."]
    #[doc = " Note that afterward, \\p out may not longer be normalised and ergo no longer a valid"]
    #[doc = " state-vector or density matrix. Users must therefore be careful passing \\p out to"]
    #[doc = " other QuEST functions which assume normalisation in order to function correctly."]
    #[doc = ""]
    #[doc = " \\p qureg1, \\p qureg2 and \\p out must be all state-vectors, or all density matrices,"]
    #[doc = " of equal dimensions. \\p out can be one (or both) of \\p qureg1 and \\p qureg2."]
    #[doc = ""]
    #[doc = " @ingroup init"]
    #[doc = " @param[in] fac1 the complex number by which to scale \\p qureg1 in the output state"]
    #[doc = " @param[in] qureg1 the first qureg to add to \\p out, which is itself unmodified"]
    #[doc = " @param[in] fac2 the complex number by which to scale \\p qureg2 in the output state"]
    #[doc = " @param[in] qureg2 the second qureg to add to \\p out, which is itself unmodified"]
    #[doc = " @param[in] facOut the complex factor by which to multiply the current elements of \\p out."]
    #[doc = "      \\p out is completely overwritten if \\p facOut is set to (Complex) {.real=0,.imag=0}"]
    #[doc = " @param[in,out] out the qureg to be modified, to be scaled by \\p facOut then have \\p fac1 \\p qureg1 and"]
    #[doc = "      \\p fac2 \\p qureg2 added to it."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg1, \\p qureg2 and \\p aren't all state-vectors or all density matrices"]
    #[doc = " - if the dimensions of \\p qureg1, \\p qureg2 and \\p aren't equal"]
    #[doc = " @author Tyson Jones"]
    pub fn setWeightedQureg(
        fac1: Complex,
        qureg1: Qureg,
        fac2: Complex,
        qureg2: Qureg,
        facOut: Complex,
        out: Qureg,
    );
}
extern "C" {
    #[doc = " Modifies \\p outQureg to be the result of applying the weighted sum of Pauli products (a Hermitian but not"]
    #[doc = " necessarily unitary operator) to \\p inQureg. Note that afterward, \\p outQureg may no longer be normalised and ergo not a"]
    #[doc = " state-vector or density matrix. Users must therefore be careful passing \\p outQureg to"]
    #[doc = " other QuEST functions which assume normalisation in order to function correctly."]
    #[doc = ""]
    #[doc = " Letting \\f$ \\alpha = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$ be"]
    #[doc = " the operators indicated by \\p allPauliCodes (where \\f$ c_i \\in \\f$ \\p termCoeffs and \\f$ N = \\f$ \\p qureg.numQubitsRepresented),"]
    #[doc = " this function effects \\f$ \\alpha | \\psi \\rangle \\f$ on state-vector \\f$ |\\psi\\rangle \\f$"]
    #[doc = " and \\f$\\alpha \\rho\\f$ (left matrix multiplication) on density matrix \\f$ \\rho \\f$."]
    #[doc = ""]
    #[doc = " \\p allPauliCodes is an array of length \\p numSumTerms*\\p qureg.numQubitsRepresented"]
    #[doc = "  which specifies which Pauli operators to apply, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,"]
    #[doc = " 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. For each sum term, a Pauli operator must be specified for"]
    #[doc = " EVERY qubit in \\p qureg; each set of \\p numSumTerms operators will be grouped into a product."]
    #[doc = " \\p termCoeffs is an arrray of length \\p numSumTerms containing the term coefficients."]
    #[doc = " For example, on a 3-qubit state-vector,"]
    #[doc = " ```"]
    #[doc = "     int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};"]
    #[doc = "     qreal coeffs[2] = {1.5, -3.6};"]
    #[doc = "     applyPauliSum(inQureg, paulis, coeffs, 2, outQureg);"]
    #[doc = " ```"]
    #[doc = " will apply Hermitian operation \\f$ (1.5 X I I - 3.6 X Y Z) \\f$"]
    #[doc = " (where in this notation, the left-most operator applies to the least-significant qubit, i.e. that with index 0)."]
    #[doc = ""]
    #[doc = " In theory, \\p inQureg is unchanged though its state is temporarily"]
    #[doc = " modified and is reverted by re-applying Paulis (XX=YY=ZZ=I), so may see a change by small numerical errors."]
    #[doc = " The initial state in \\p outQureg is not used."]
    #[doc = ""]
    #[doc = " \\p inQureg and \\p outQureg must both be state-vectors, or both density matrices,"]
    #[doc = " of equal dimensions. \\p inQureg cannot be \\p outQureg."]
    #[doc = ""]
    #[doc = " This function works by applying each Pauli product to \\p inQureg in turn,"]
    #[doc = " and adding the resulting state (weighted by a coefficient in \\p termCoeffs)"]
    #[doc = " to the initially-blanked \\p outQureg. Ergo it should scale with the total number"]
    #[doc = " of Pauli operators specified (excluding identities), and the qureg dimension."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - calcExpecPauliSum()"]
    #[doc = " - applyPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in] inQureg the register containing the state which \\p outQureg will be set to, under"]
    #[doc = "      the action of the Hermitiain operator specified by the Pauli codes. \\p inQureg should be"]
    #[doc = "      unchanged, though may vary slightly due to numerical error."]
    #[doc = " @param[in] allPauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)"]
    #[doc = "      of all Paulis involved in the products of terms. A Pauli must be specified for each qubit"]
    #[doc = "      in the register, in every term of the sum."]
    #[doc = " @param[in] termCoeffs The coefficients of each term in the sum of Pauli products"]
    #[doc = " @param[in] numSumTerms The total number of Pauli products specified"]
    #[doc = " @param[out] outQureg the qureg to modify to be the result of applyling the weighted Pauli sum operator"]
    #[doc = "      to the state in \\p inQureg"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any code in \\p allPauliCodes is not in {0,1,2,3}"]
    #[doc = " - if numSumTerms <= 0"]
    #[doc = " - if \\p inQureg is not of the same type and dimensions as \\p outQureg"]
    #[doc = " @author Tyson Jones"]
    pub fn applyPauliSum(
        inQureg: Qureg,
        allPauliCodes: *mut pauliOpType,
        termCoeffs: *mut f64,
        numSumTerms: ::std::os::raw::c_int,
        outQureg: Qureg,
    );
}
extern "C" {
    #[doc = " Modifies \\p outQureg to be the result of applying \\p PauliHamil (a Hermitian but not"]
    #[doc = " necessarily unitary operator) to \\p inQureg. Note that afterward, \\p outQureg may no longer be normalised and ergo not a"]
    #[doc = " state-vector or density matrix. Users must therefore be careful passing \\p outQureg to"]
    #[doc = " other QuEST functions which assume normalisation in order to function correctly."]
    #[doc = ""]
    #[doc = " This is merely an encapsulation of applyPauliSum(), which can refer to for elaborated doc."]
    #[doc = ""]
    #[doc = " Letting \\p hamil be expressed as \\f$ \\alpha = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$"]
    #[doc = " (where \\f$ c_i \\in \\f$ \\p hamil.termCoeffs and \\f$ N = \\f$ \\p hamil.numQubits),"]
    #[doc = " this function effects \\f$ \\alpha | \\psi \\rangle \\f$ on state-vector \\f$ |\\psi\\rangle \\f$"]
    #[doc = " and \\f$\\alpha \\rho\\f$ (left matrix multiplication) on density matrix \\f$ \\rho \\f$."]
    #[doc = ""]
    #[doc = " In theory, \\p inQureg is unchanged though its state is temporarily"]
    #[doc = " modified and is reverted by re-applying Paulis (XX=YY=ZZ=I), so may see a change by small numerical errors."]
    #[doc = " The initial state in \\p outQureg is not used."]
    #[doc = ""]
    #[doc = " \\p inQureg and \\p outQureg must both be state-vectors, or both density matrices,"]
    #[doc = " of equal dimensions to \\p hamil."]
    #[doc = " \\p inQureg cannot be \\p outQureg."]
    #[doc = ""]
    #[doc = " This function works by applying each Pauli product in \\p hamil to \\p inQureg in turn,"]
    #[doc = " and adding the resulting state (weighted by a coefficient in \\p termCoeffs)"]
    #[doc = " to the initially-blanked \\p outQureg. Ergo it should scale with the total number"]
    #[doc = " of Pauli operators specified (excluding identities), and the qureg dimension."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createPauliHamil()"]
    #[doc = " - createPauliHamilFromFile()"]
    #[doc = " - calcExpecPauliHamil()"]
    #[doc = " - applyTrotterCircuit()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in] inQureg the register containing the state which \\p outQureg will be set to, under"]
    #[doc = "      the action of \\p hamil. \\p inQureg should be unchanged, though may vary slightly due to numerical error."]
    #[doc = " @param[in] hamil a weighted sum of products of pauli operators"]
    #[doc = " @param[out] outQureg the qureg to modify to be the result of applyling \\p hamil to the state in \\p inQureg"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any code in \\p hamil.pauliCodes is not a valid Pauli code"]
    #[doc = " - if \\p numSumTerms <= 0"]
    #[doc = " - if \\p inQureg is not of the same type and dimensions as \\p outQureg and \\p hamil"]
    #[doc = " @author Tyson Jones"]
    pub fn applyPauliHamil(inQureg: Qureg, hamil: PauliHamil, outQureg: Qureg);
}
extern "C" {
    #[doc = " Applies a trotterisation of unitary evolution \\f$ \\exp(-i \\, \\text{hamil} \\, \\text{time}) \\f$"]
    #[doc = " to \\p qureg. This is a sequence of unitary operators, effected by multiRotatePauli(),"]
    #[doc = " which together approximate the action of full unitary-time evolution under the given Hamiltonian."]
    #[doc = ""]
    #[doc = " Notate \\f$ \\text{hamil} = \\sum_j^N c_j \\, \\hat \\sigma_j \\f$ where \\f$c_j\\f$ is a real"]
    #[doc = " coefficient in \\p hamil, \\f$\\hat \\sigma_j\\f$ is the corresponding product of Pauli operators,"]
    #[doc = " of which there are a total \\f$N\\f$."]
    #[doc = " Then, \\p order=1 performs first-order Trotterisation, whereby"]
    #[doc = " \\f["]
    #[doc = "   \\exp(-i \\, \\text{hamil} \\, \\text{time})"]
    #[doc = "      \\approx"]
    #[doc = "    \\prod\\limits^{\\text{reps}} \\prod\\limits_{j=1}^{N} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / \\text{reps})"]
    #[doc = " \\f]"]
    #[doc = " \\p order=2 performs the lowest order \"symmetrized\" Suzuki decomposition, whereby"]
    #[doc = " \\f["]
    #[doc = "   \\exp(-i \\, \\text{hamil} \\, \\text{time})"]
    #[doc = "      \\approx"]
    #[doc = "    \\prod\\limits^{\\text{reps}} \\left["]
    #[doc = "         \\prod\\limits_{j=1}^{N} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / (2 \\, \\text{reps}))"]
    #[doc = "          \\prod\\limits_{j=N}^{1} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / (2 \\, \\text{reps}))"]
    #[doc = "     \\right]"]
    #[doc = " \\f]"]
    #[doc = " Greater even values of \\p order specify higher-order symmetrized decompositions"]
    #[doc = " \\f$ S[\\text{time}, \\text{order}, \\text{reps}] \\f$ which satisfy"]
    #[doc = " \\f["]
    #[doc = "      S[\\text{time}, \\text{order}, 1] ="]
    #[doc = "          \\left( \\prod\\limits^2 S[p \\, \\text{time}, \\text{order}-2, 1] \\right)"]
    #[doc = "          S[ (1-4p)\\,\\text{time}, \\text{order}-2, 1]"]
    #[doc = "          \\left( \\prod\\limits^2 S[p \\, \\text{time}, \\text{order}-2, 1] \\right)"]
    #[doc = " \\f]"]
    #[doc = " and"]
    #[doc = " \\f["]
    #[doc = "      S[\\text{time}, \\text{order}, \\text{reps}] ="]
    #[doc = "          \\prod\\limits^{\\text{reps}} S[\\text{time}/\\text{reps}, \\text{order}, 1]"]
    #[doc = " \\f]"]
    #[doc = " where \\f$ p = \\left( 4 - 4^{1/(\\text{order}-1)} \\right)^{-1} \\f$."]
    #[doc = ""]
    #[doc = " These formulations are taken from 'Finding Exponential Product Formulas"]
    #[doc = " of Higher Orders', Naomichi Hatano and Masuo Suzuki (2005) (<a href=\"https://arxiv.org/abs/math-ph/0506007\">arXiv</a>)."]
    #[doc = ""]
    #[doc = " Note that the applied Trotter circuit is captured by QASM, if QASM logging is enabled"]
    #[doc = " on \\p qureg. \\n"]
    #[doc = " For example:"]
    #[doc = " ```"]
    #[doc = " startRecordingQASM(qureg);"]
    #[doc = " applyTrotterCircuit(qureg, hamil, 1, 2, 1);"]
    #[doc = " printRecordedQASM(qureg);"]
    #[doc = " ```"]
    #[doc = " may show"]
    #[doc = " ```"]
    #[doc = " // Beginning of Trotter circuit (time 1, order 2, 1 repetitions)."]
    #[doc = " // Here, a multiRotatePauli with angle 0.5 and paulis X Y I  was applied."]
    #[doc = " // Here, a multiRotatePauli with angle -0.5 and paulis I Z X  was applied."]
    #[doc = " // Here, a multiRotatePauli with angle -0.5 and paulis I Z X  was applied."]
    #[doc = " // Here, a multiRotatePauli with angle 0.5 and paulis X Y I  was applied."]
    #[doc = " // End of Trotter circuit"]
    #[doc = " ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createPauliHamil()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the register to modify under the approximate unitary-time evolution"]
    #[doc = " @param[in] hamil the hamiltonian under which to approxiamte unitary-time evolution"]
    #[doc = " @param[in] time the target evolution time, which is permitted to be both positive and negative."]
    #[doc = " @param[in] order the order of Trotter-Suzuki decomposition to use. Higher orders (necessarily even)"]
    #[doc = "      are more accurate but prescribe an exponentially increasing number of gates."]
    #[doc = " @param[in] reps the number of repetitions of the decomposition of the given order. This"]
    #[doc = "      improves the accuracy but prescribes a linearly increasing number of gates."]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qureg.numQubitsRepresented != \\p hamil.numQubits"]
    #[doc = " - if \\p hamil contains invalid parameters or Pauli codes,"]
    #[doc = " - if \\p order is not in {1, 2, 4, 6, ...}"]
    #[doc = " - or if \\p reps <= 0"]
    #[doc = " @author Tyson Jones"]
    pub fn applyTrotterCircuit(
        qureg: Qureg,
        hamil: PauliHamil,
        time: f64,
        order: ::std::os::raw::c_int,
        reps: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Apply a general 2-by-2 matrix, which may be non-unitary. The matrix is"]
    #[doc = " left-multiplied onto the state, for both state-vectors and density matrices."]
    #[doc = ""]
    #[doc = " Note this differs from the action of unitary() on a density matrix."]
    #[doc = ""]
    #[doc = " This function may leave \\p qureg is an unnormalised state."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix2"]
    #[doc = " - unitary()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit qubit to operate \\p u upon"]
    #[doc = " @param[in] u matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMatrix2(qureg: Qureg, targetQubit: ::std::os::raw::c_int, u: ComplexMatrix2);
}
extern "C" {
    #[doc = " Apply a general 4-by-4 matrix, which may be non-unitary. The matrix is"]
    #[doc = " left-multiplied onto the state, for both state-vectors and density matrices."]
    #[doc = ""]
    #[doc = " Note this differs from the action of twoQubitUnitary() on a density matrix."]
    #[doc = ""]
    #[doc = " \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that"]
    #[doc = " a row in \\p u is dotted with the vector"]
    #[doc = " \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$"]
    #[doc = ""]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = "     applyMatrix4(qureg, a, b, u);"]
    #[doc = " ```"]
    #[doc = " will invoke multiplication"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " u_{00} & u_{01} & u_{02} & u_{03} \\\\"]
    #[doc = " u_{10} & u_{11} & u_{12} & u_{13} \\\\"]
    #[doc = " u_{20} & u_{21} & u_{22} & u_{23} \\\\"]
    #[doc = " u_{30} & u_{31} & u_{32} & u_{33}"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " |ba\\rangle = |00\\rangle \\\\"]
    #[doc = " |ba\\rangle = |01\\rangle \\\\"]
    #[doc = " |ba\\rangle = |10\\rangle \\\\"]
    #[doc = " |ba\\rangle = |11\\rangle"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " This function may leave \\p qureg is an unnormalised state."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q/4 nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - ::ComplexMatrix4"]
    #[doc = " - twoQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u"]
    #[doc = " @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u"]
    #[doc = " @param[in] u matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targetQubit1 equals \\p targetQubit2"]
    #[doc = " - if each node cannot fit 4 amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMatrix4(
        qureg: Qureg,
        targetQubit1: ::std::os::raw::c_int,
        targetQubit2: ::std::os::raw::c_int,
        u: ComplexMatrix4,
    );
}
extern "C" {
    #[doc = " Apply a general N-by-N matrix, which may be non-unitary, on any number of target qubits."]
    #[doc = " The matrix is left-multiplied onto the state, for both state-vectors and density matrices."]
    #[doc = " Note this differs from the action of multiQubitUnitary() on a density matrix."]
    #[doc = ""]
    #[doc = " The first target qubit in \\p targs is treated as \\b least significant in \\p u."]
    #[doc = " For example,"]
    #[doc = " ```"]
    #[doc = "     applyMatrixN(qureg, (int []) {a, b, c}, 3, u);"]
    #[doc = " ```"]
    #[doc = " will invoke multiplication"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " u_{00} & u_{01} & u_{02} & u_{03} & u_{04} & u_{05} & u_{06} & u_{07} \\\\"]
    #[doc = " u_{10} & u_{11} & u_{12} & u_{13} & u_{14} & u_{15} & u_{16} & u_{17} \\\\"]
    #[doc = " u_{20} & u_{21} & u_{22} & u_{23} & u_{24} & u_{25} & u_{26} & u_{27} \\\\"]
    #[doc = " u_{30} & u_{31} & u_{32} & u_{33} & u_{34} & u_{35} & u_{36} & u_{37} \\\\"]
    #[doc = " u_{40} & u_{41} & u_{42} & u_{43} & u_{44} & u_{45} & u_{46} & u_{47} \\\\"]
    #[doc = " u_{50} & u_{51} & u_{52} & u_{53} & u_{54} & u_{55} & u_{56} & u_{57} \\\\"]
    #[doc = " u_{60} & u_{61} & u_{62} & u_{63} & u_{64} & u_{65} & u_{66} & u_{67} \\\\"]
    #[doc = " u_{70} & u_{71} & u_{72} & u_{73} & u_{74} & u_{75} & u_{76} & u_{77} \\\\"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " |cba\\rangle = |000\\rangle \\\\"]
    #[doc = " |cba\\rangle = |001\\rangle \\\\"]
    #[doc = " |cba\\rangle = |010\\rangle \\\\"]
    #[doc = " |cba\\rangle = |011\\rangle \\\\"]
    #[doc = " |cba\\rangle = |100\\rangle \\\\"]
    #[doc = " |cba\\rangle = |101\\rangle \\\\"]
    #[doc = " |cba\\rangle = |110\\rangle \\\\"]
    #[doc = " |cba\\rangle = |111\\rangle"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = ""]
    #[doc = " This function may leave \\p qureg is an unnormalised state."]
    #[doc = ""]
    #[doc = " The passed ComplexMatrix must be a compatible size with the specified number of"]
    #[doc = " target qubits, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = " Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,"]
    #[doc = " and store these in the runtime stack."]
    #[doc = " Using t threads, the total memory overhead of this function is t*2^\\p numTargs."]
    #[doc = " For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault"]
    #[doc = " (e.g. on a 1 MiB stack)."]
    #[doc = ""]
    #[doc = " Note too that in distributed mode, this routine requires that each node contains"]
    #[doc = " at least 2^\\p numTargs amplitudes in the register. This means an q-qubit register (state vector or density matrix)"]
    #[doc = " can be distributed by at most 2^q / 2^\\p numTargs nodes."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - createComplexMatrixN()"]
    #[doc = " - getStaticComplexMatrixN()"]
    #[doc = " - applyMultiControlledMatrixN()"]
    #[doc = " - multiQubitUnitary()"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] targs a list of the target qubits, ordered least significant to most in \\p u"]
    #[doc = " @param[in] numTargs the number of target qubits"]
    #[doc = " @param[in] u matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p targs are not unique"]
    #[doc = " - if \\p u is not of a compatible size with \\p numTargs"]
    #[doc = " - if a node cannot fit the required number of target amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMatrixN(
        qureg: Qureg,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
        u: ComplexMatrixN,
    );
}
extern "C" {
    #[doc = " Apply a general N-by-N matrix, which may be non-unitary, with additional controlled qubits."]
    #[doc = " The matrix is left-multiplied onto the state, for both state-vectors and density matrices."]
    #[doc = " Hence, this function differs from multiControlledMultiQubitUnitary() by more than just permitting a non-unitary"]
    #[doc = " matrix."]
    #[doc = ""]
    #[doc = " This function may leave \\p qureg is an unnormalised state."]
    #[doc = ""]
    #[doc = " Any number of control and target qubits can be specified."]
    #[doc = " This effects the many-qubit matrix"]
    #[doc = " \\f["]
    #[doc = " \\begin{pmatrix}"]
    #[doc = " 1 \\\\"]
    #[doc = " & 1 \\\\\\"]
    #[doc = " & & \\ddots \\\\"]
    #[doc = " & & & u_{00} & u_{01} & \\dots  \\\\"]
    #[doc = " & & & u_{10} & u_{11} & \\dots \\\\"]
    #[doc = " & & & \\vdots & \\vdots & \\ddots"]
    #[doc = " \\end{pmatrix}"]
    #[doc = " \\f]"]
    #[doc = " on the control and target qubits."]
    #[doc = ""]
    #[doc = " The target qubits in \\p targs are treated as ordered least significant"]
    #[doc = " to most significant in \\p u."]
    #[doc = ""]
    #[doc = " The passed ComplexMatrix must be a compatible size with the specified number of"]
    #[doc = " target qubits, otherwise an error is thrown."]
    #[doc = ""]
    #[doc = " Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,"]
    #[doc = " and store these in the runtime stack."]
    #[doc = " Using t threads, the total memory overhead of this function is t*2^\\p numTargs."]
    #[doc = " For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault"]
    #[doc = " (e.g. on a 1 MiB stack)."]
    #[doc = ""]
    #[doc = " Note that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes."]
    #[doc = " This means an q-qubit register (state vector or density matrix) can be distributed"]
    #[doc = " by at most 2^q / 2^\\p numTargs nodes."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg object representing the set of all qubits"]
    #[doc = " @param[in] ctrls a list of the control qubits"]
    #[doc = " @param[in] numCtrls the number of control qubits"]
    #[doc = " @param[in] targs a list of the target qubits, ordered least to most significant"]
    #[doc = " @param[in] numTargs the number of target qubits"]
    #[doc = " @param[in] u matrix to apply"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any index in \\p ctrls and \\p targs is outside of [0, \\p qureg.numQubitsRepresented)"]
    #[doc = " - if \\p ctrls and \\p targs are not unique"]
    #[doc = " - if matrix \\p u is not a compatible size with \\p numTargs"]
    #[doc = " - if a node cannot fit the required number of target amplitudes in distributed mode"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMultiControlledMatrixN(
        qureg: Qureg,
        ctrls: *mut ::std::os::raw::c_int,
        numCtrls: ::std::os::raw::c_int,
        targs: *mut ::std::os::raw::c_int,
        numTargs: ::std::os::raw::c_int,
        u: ComplexMatrixN,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by the passed"]
    #[doc = " exponential polynomial \"phase function\". This effects a diagonal unitary of unit complex scalars,"]
    #[doc = " targeting the nominated \\p qubits."]
    #[doc = ""]
    #[doc = " - Arguments \\p coeffs and \\p exponents together specify a real exponential polynomial \\f$f(r)\\f$"]
    #[doc = "   with \\p numTerms terms, of the form"]
    #[doc = "   \\f["]
    #[doc = "    f(r) = \\sum\\limits_{i}^{\\text{numTerms}} \\text{coeffs}[i] \\; r^{\\, \\text{exponents}[i]}\\,,"]
    #[doc = "   \\f]"]
    #[doc = "   where both \\p coeffs and \\p exponents can be negative, positive and fractional."]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "      qreal coeffs[] = {1, -3.14};"]
    #[doc = "      qreal exponents[] = {2, -5.5};"]
    #[doc = "      int numTerms = 2;"]
    #[doc = "   ```"]
    #[doc = "   constitutes the function"]
    #[doc = "   \\f["]
    #[doc = "       f(r) =  1 \\, r^2 - 3.14 \\, r^{-5.5}."]
    #[doc = "   \\f]"]
    #[doc = "   Note you cannot use fractional exponents with \\p encoding <b>=</b> ::TWOS_COMPLEMENT,"]
    #[doc = "   since the negative indices would generate (illegal) complex phases, and must"]
    #[doc = "   be overriden with applyPhaseFuncOverrides(). \\n"]
    #[doc = " > If your function \\f$f(r)\\f$ diverges at one or more \\f$r\\f$ values, you must instead"]
    #[doc = " > use applyPhaseFuncOverrides() and specify explicit phase changes for these values."]
    #[doc = " > Otherwise, the corresponding amplitudes of the state-vector will become indeterminate (like `NaN`)."]
    #[doc = " > Note that use of any negative exponent will result in divergences at \\f$r=0\\f$."]
    #[doc = ""]
    #[doc = " - The function \\f$f(r)\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$"]
    #[doc = "   of computational basis state with index \\f$r\\f$, such that"]
    #[doc = "   \\f["]
    #[doc = "    \\alpha \\, |r\\rangle \\rightarrow \\, \\exp(i f(r)) \\; \\alpha \\, |r\\rangle."]
    #[doc = "   \\f]"]
    #[doc = "   The index \\f$r\\f$ associated with each computational basis state is determined by"]
    #[doc = "   the binary value of the specified \\p qubits (ordered least to most significant),"]
    #[doc = "   interpreted under the given ::bitEncoding \\p encoding. \\n\\n"]
    #[doc = "   For example, under \\p encoding <b>=</b> \\p UNSIGNED and \\p qubits <b>= {0,1}</b>,"]
    #[doc = "   \\f["]
    #[doc = "   \\begin{aligned}"]
    #[doc = "     |0\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|0\\mathbf{00}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|0\\mathbf{01}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{10}\\rangle & \\rightarrow \\, e^{i f(2)}\\,|0\\mathbf{10}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|0\\mathbf{11}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|1\\mathbf{00}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|1\\mathbf{01}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{10}\\rangle & \\rightarrow \\, e^{i f(2)}\\,|1\\mathbf{10}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|1\\mathbf{11}\\rangle"]
    #[doc = "   \\end{aligned}"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix \\f$\\rho\\f$, this function modifies \\p qureg to"]
    #[doc = "   \\f["]
    #[doc = "      \\rho \\rightarrow \\hat{D} \\, \\rho \\, \\hat{D}^\\dagger"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$\\hat{D}\\f$ is the diagonal unitary operator"]
    #[doc = "   \\f["]
    #[doc = "      \\hat{D} = \\text{diag} \\, \\{ \\; e^{i f(r_0)}, \\; e^{i f(r_1)}, \\;  \\dots \\; \\}."]
    #[doc = "   \\f]"]
    #[doc = "   This means element \\f$\\rho_{jk}\\f$ is modified to"]
    #[doc = "   \\f["]
    #[doc = "      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\; e^{i (f(r_j) - f(r_k))} \\; \\alpha \\, |j\\rangle\\langle k|"]
    #[doc = "   \\f]\\n"]
    #[doc = ""]
    #[doc = " - The interpreted phase function can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyPhaseFunc(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyPhaseFunc() multiplied a complex scalar of the form"]
    #[doc = "   //     exp(i (1 x^3))"]
    #[doc = "   //   upon every substate |x>, informed by qubits (under an unsigned binary encoding)"]
    #[doc = "   //     {4, 1, 2, 0}"]
    #[doc = "   ```"]
    #[doc = ""]
    #[doc = " > This function may become numerically imprecise for quickly growing phase functions"]
    #[doc = " > which admit very large phases, for example of 10^10."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyPhaseFuncOverrides() to override the phase function for specific states."]
    #[doc = " - applyMultiVarPhaseFunc() for multi-variable exponential polynomial phase functions."]
    #[doc = " - applyNamedPhaseFunc() for a set of specific phase functions."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density matrix to be modified"]
    #[doc = " @param[in] qubits a list of the indices of the qubits which will inform \\f$r\\f$ for each amplitude in \\p qureg"]
    #[doc = " @param[in] numQubits the length of list \\p qubits"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r\\f$ from the bits of \\p qubits in each basis state of \\p qureg"]
    #[doc = " @param[in] coeffs the coefficients of the exponential polynomial phase function \\f$f(r)\\f$"]
    #[doc = " @param[in] exponents the exponents of the exponential polynomial phase function \\f$f(r)\\f$"]
    #[doc = " @param[in] numTerms the length of list \\p coeffs, which must be the same as that of \\p exponents"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique"]
    #[doc = " - if \\p numQubits < 0 or \\p numQubits >= `qureg.numQubitsRepresented`"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if \\p encoding is not compatible with \\p numQubits (e.g. \\p TWOS_COMPLEMENT with only 1 qubit)"]
    #[doc = " - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT (you must instead use applyPhaseFuncOverrides() and override all negative indices)"]
    #[doc = " - if \\p exponents contains a negative power (you must instead use applyPhaseFuncOverrides() and override the zero index)"]
    #[doc = " - if \\p numTerms <= 0"]
    #[doc = " @author Tyson Jones"]
    pub fn applyPhaseFunc(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubits: ::std::os::raw::c_int,
        encoding: bitEncoding,
        coeffs: *mut f64,
        exponents: *mut f64,
        numTerms: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by the passed"]
    #[doc = " exponential polynomial \"phase function\", and an explicit set of 'overriding' values at specific"]
    #[doc = " state indices."]
    #[doc = ""]
    #[doc = " See applyPhaseFunc() first for a full description."]
    #[doc = ""]
    #[doc = " - As in applyPhaseFunc(), the arguments \\p coeffs and \\p exponents specify a phase"]
    #[doc = "   function \\f$f(r)\\f$, where \\f$r\\f$ is determined by \\p qubits and \\p encoding for"]
    #[doc = "   each basis state of \\p qureg.\\n\\n"]
    #[doc = " - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies"]
    #[doc = "   the values of \\f$r\\f$ for which to explicitly set the induced phase change.\\n"]
    #[doc = "   The overriding phase changes are specified in the corresponding elements of \\p overridePhases.\\n\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "      int qubits[] = {0,1};"]
    #[doc = "      enum bitEncoding encoding = UNSIGNED;"]
    #[doc = ""]
    #[doc = "      long long int overrideInds[] = {2};"]
    #[doc = "      qreal overridePhases[] = {M_PI};"]
    #[doc = ""]
    #[doc = "      applyPhaseFuncOverrides(...);"]
    #[doc = "   ```"]
    #[doc = "   would effect the same diagonal unitary of applyPhaseFunc(), <em>except</em> that all"]
    #[doc = "   instance of \\f$f(r=2)\\f$ are overriden with phase \\f$\\pi\\f$. \\n I.e."]
    #[doc = "   \\f["]
    #[doc = "   \\begin{aligned}"]
    #[doc = "     |0\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|0\\mathbf{00}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|0\\mathbf{01}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{10}\\rangle & \\rightarrow \\, e^{i \\pi} \\hspace{12pt} |0\\mathbf{10}\\rangle \\\\"]
    #[doc = "     |0\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|0\\mathbf{11}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|1\\mathbf{00}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|1\\mathbf{01}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{10}\\rangle & \\rightarrow \\, e^{i \\pi} \\hspace{12pt} |1\\mathbf{10}\\rangle \\\\"]
    #[doc = "     |1\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|1\\mathbf{11}\\rangle"]
    #[doc = "   \\end{aligned}"]
    #[doc = "   \\f]"]
    #[doc = "   Note that if \\p encoding <b>=</b> ::TWOS_COMPLEMENT, \\a and \\f$f(r)\\f$ features a"]
    #[doc = "   fractional exponent, then every negative phase index must be overriden. This"]
    #[doc = "   is checked and enforced by QuEST's validation, \\a unless there are more than"]
    #[doc = "   16 targeted qubits, in which case valid input is assumed (due to an otherwise"]
    #[doc = "   prohibitive performance overhead)."]
    #[doc = "   \\n"]
    #[doc = " > Overriding phases are checked at each computational basis state of \\p qureg <em>before</em>"]
    #[doc = " > evaluating the phase function \\f$f(r)\\f$, and hence are useful for avoiding"]
    #[doc = " > singularities or errors at diverging values of \\f$r\\f$."]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix \\f$\\rho\\f$, the overrides determine the diagonal unitary matrix"]
    #[doc = "   \\f$\\hat{D}\\f$, which is then applied to \\p qureg as"]
    #[doc = "   \\f["]
    #[doc = "      \\rho \\; \\rightarrow \\; \\hat{D} \\, \\rho \\hat{D}^\\dagger."]
    #[doc = "   \\f]"]
    #[doc = "   This means that with overrides \\f$f(r_j) \\rightarrow \\theta\\f$ and \\f$f(r_k) \\rightarrow \\phi\\f$,"]
    #[doc = "   element \\f$\\rho_{jk}\\f$ is modified to"]
    #[doc = "   \\f["]
    #[doc = "      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;"]
    #[doc = "          \\exp(\\, i \\, (\\theta - \\phi) \\, ) \\; \\alpha \\, |j\\rangle\\langle k|."]
    #[doc = "   \\f]\\n"]
    #[doc = ""]
    #[doc = " - The interpreted phase function and list of overrides can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyPhaseFunc(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyPhaseFunc() multiplied a complex scalar of the form"]
    #[doc = "   //     exp(i (0.3 x^(-5) + 4 x^1 + 1 x^3))"]
    #[doc = "   //   upon every substate |x>, informed by qubits (under a two's complement binary encoding)"]
    #[doc = "   //     {4, 1, 2, 0}"]
    #[doc = "   //   though with overrides"]
    #[doc = "   //     |0> -> exp(i 3.14159)"]
    #[doc = "   //     |1> -> exp(i (-3.14159))"]
    #[doc = "   //     |2> -> exp(i 0)"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyPhaseFunc() for full doc on how \\f$f(r)\\f$ is evaluated."]
    #[doc = " - applyMultiVarPhaseFunc() for multi-variable exponential polynomial phase functions."]
    #[doc = " - applyNamedPhaseFunc() for a set of specific phase functions."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density matrix to be modified"]
    #[doc = " @param[in] qubits a list of the indices of the qubits which will inform \\f$r\\f$ for each amplitude in \\p qureg"]
    #[doc = " @param[in] numQubits the length of list \\p qubits"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r\\f$ from the bits of \\p qubits in each basis state of \\p qureg"]
    #[doc = " @param[in] coeffs the coefficients of the exponential polynomial phase function \\f$f(r)\\f$"]
    #[doc = " @param[in] exponents the exponents of the exponential polynomial phase function \\f$f(r)\\f$"]
    #[doc = " @param[in] numTerms the length of list \\p coeffs, which must be the same as that of \\p exponents"]
    #[doc = " @param[in] overrideInds a list of sub-state indices (values of \\f$r\\f$) of which to explicit set the phase change"]
    #[doc = " @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$r\\f$ values in \\p overrideInds (one to one)"]
    #[doc = " @param[in] numOverrides the lengths of lists \\p overrideInds and \\p overridePhases"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique"]
    #[doc = " - if \\p numQubits < 0 or \\p numQubits >= `qureg.numQubitsRepresented`"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if \\p encoding is not compatible with \\p numQubits (i.e. \\p TWOS_COMPLEMENT with 1 qubit)"]
    #[doc = " - if \\p numTerms <= 0"]
    #[doc = " - if any value in \\p overrideInds is not producible by \\p qubits under the given \\p encoding (e.g. 2 unsigned qubits cannot represent index 9)"]
    #[doc = " - if \\p numOverrides < 0"]
    #[doc = " - if \\p exponents contains a negative power and the (consequently diverging) zero index is not contained in \\p overrideInds"]
    #[doc = " - if \\p encoding is ::TWOS_COMPLEMENT, and \\p exponents contains a fractional number, but \\p overrideInds does not contain every possible negative index (checked only up to 16 targeted qubits)"]
    #[doc = " @author Tyson Jones"]
    pub fn applyPhaseFuncOverrides(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubits: ::std::os::raw::c_int,
        encoding: bitEncoding,
        coeffs: *mut f64,
        exponents: *mut f64,
        numTerms: ::std::os::raw::c_int,
        overrideInds: *mut ::std::os::raw::c_longlong,
        overridePhases: *mut f64,
        numOverrides: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " multi-variable exponential polynomial \"phase function\"."]
    #[doc = ""]
    #[doc = " This is a multi-variable extension of applyPhaseFunc(), whereby multiple sub-registers inform"]
    #[doc = " separate variables in the exponential polynomial function, and effects a diagonal unitary"]
    #[doc = " operator."]
    #[doc = ""]
    #[doc = " - Arguments \\p coeffs, \\p exponents and \\p numTermsPerReg together specify a real"]
    #[doc = "   exponential polynomial \\f$f(\\vec{r})\\f$ of the form"]
    #[doc = "   \\f["]
    #[doc = "    f(r_1, \\; \\dots, \\; r_{\\text{numRegs}}) = \\sum\\limits_j^{\\text{numRegs}} \\; \\sum\\limits_{i}^{\\text{numTermsPerReg}[j]} \\; c_{i,j} \\; {r_j}^{\\; p_{i,j}}\\,,"]
    #[doc = "   \\f]"]
    #[doc = "   where both coefficients \\f$c_{i,j}\\f$ and exponents \\f$p_{i,j}\\f$ can be any real number, subject to constraints described below."]
    #[doc = "   \\n\\n"]
    #[doc = "   While \\p coeffs and \\p exponents are flat lists, they should be considered grouped into"]
    #[doc = "   #`numRegs` sublists with lengths given by \\p numTermsPerReg (which itself has length \\p numRegs). \\n\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "      int numRegs = 3;"]
    #[doc = "      qreal coeffs[] =        {1,  2, 4,  -3.14};"]
    #[doc = "      qreal exponents[] =     {2,  1, 5,   0.5 };"]
    #[doc = "      int numTermsPerReg[] =  {1,  2,      1   };"]
    #[doc = "   ```"]
    #[doc = "   constitutes the function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}) =  1 \\, {r_1}^2 + 2 \\, {r_2} + 4 \\, {r_2}^{5} - 3.14 \\, {r_3}^{0.5}."]
    #[doc = "   \\f] \\n"]
    #[doc = "   > This means lists \\p coeffs and \\p exponents should both be of length equal to the sum of \\p numTermsPerReg."]
    #[doc = "   Unlike applyPhaseFunc(), applyMultiVarPhaseFunc() places additional constraints on the"]
    #[doc = "   exponents in \\f$f(\\vec{r})\\f$, due to the exponentially growing costs of overriding"]
    #[doc = "   diverging indices. Namely:\\n"]
    #[doc = "   -# \\p exponents must not contain a negative number, since this would result in a divergence"]
    #[doc = "         when that register is zero, which would need to be overriden for every other register"]
    #[doc = "         basis state. If \\f$f(\\vec{r})\\f$ must contain a negative exponent, you should instead"]
    #[doc = "         call applyPhaseFuncOverrides() once for each register/variable, and override the"]
    #[doc = "         zero index for the relevant variable. This works, because"]
    #[doc = "         \\f[  \\exp( i \\sum_j f_j(r_j) ) = \\prod_j \\exp(i f_j(r_j) ). \\f]"]
    #[doc = "   -# \\p exponents must not contain a fractional number if \\p endoding <b>=</b> ::TWOS_COMPLEMENT,"]
    #[doc = "         because such a term would produce illegal complex values at negative register indices."]
    #[doc = "         Similar to the problem above, each negative register index would require overriding at"]
    #[doc = "         every index of the other registers, and hence require an exponential number of overrides."]
    #[doc = "         Therefore, if \\f$f(\\vec{r})\\f$ must contain a negative exponent, you should instead"]
    #[doc = "         call applyPhaseFuncOverrides() once for each register/variable, and override every"]
    #[doc = "         negative index of each register in turn."]
    #[doc = " \\n\\n"]
    #[doc = " - Lists \\p qubits and \\p numQubitsPerReg together describe #`numRegs` sub-registers of \\p qureg,"]
    #[doc = "   which can each contain a different number of qubits. \\n"]
    #[doc = "   Although \\p qubits is a flat list of unique qubit indices, it should be imagined grouped into #`numRegs` sub-lists,"]
    #[doc = "   of lengths given by \\p numQubitsPerReg. \\n\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "      int qubits[] =          {0,1,  3,4,5,  7}"]
    #[doc = "      int numQubitsPerReg[] = {2,    3,      1};"]
    #[doc = "      int numRegs = 3;"]
    #[doc = "   ```"]
    #[doc = "   describes three sub-registers, which are bolded below in an eight-qubit zero-state."]
    #[doc = "   \\f["]
    #[doc = "      |r_3\\rangle \\; |0\\rangle \\; |r_2\\rangle \\; |0\\rangle \\; |r_1\\rangle ="]
    #[doc = "      |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle"]
    #[doc = "   \\f]"]
    #[doc = "   Note that the qubits need not be ordered increasing, and qubits within each sub-register"]
    #[doc = "   are assumed ordered least to most significant in that sub-register.\\n\\n"]
    #[doc = "   > List \\p qubits should have length equal to the sum of elements in \\p numQubitsPerReg."]
    #[doc = ""]
    #[doc = " - Each sub-register is associated with a variable \\f$r_j\\f$ in phase function \\f$f(\\vec{r})\\f$. \\n"]
    #[doc = "   For a given computational basis state of \\p qureg, the value of each variable is determined"]
    #[doc = "   by the binary value in the corresponding sub-register, when intepreted with ::bitEncoding \\p encoding. \\n"]
    #[doc = "   See ::bitEncoding for more information.\\n\\n"]
    #[doc = ""]
    #[doc = " - The function \\f$f(\\vec{r})\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$"]
    #[doc = "   of computational basis state with the nominated sub-registers encoding values \\f$r_1, \\; \\dots\\f$."]
    #[doc = "   \\f["]
    #[doc = "    \\alpha \\, |r_{\\text{numRegs}}, \\; \\dots, \\; r_2, \\; r_1 \\rangle \\rightarrow \\, \\exp(i f(\\vec{r}\\,)) \\; \\alpha \\, |r_{\\text{numRegs}}, \\; \\dots, \\; r_2, \\; r_1 \\rangle."]
    #[doc = "   \\f]"]
    #[doc = "   For example, using the sub-registers in the previous example and \\p encoding <b>=</b> \\p UNSIGNED, the"]
    #[doc = "   following states receive amplitude factors:"]
    #[doc = "   \\f["]
    #[doc = "   \\begin{aligned}"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=1)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{10}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=2)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=3)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |1\\rangle \\; |\\mathbf{00}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\"]
    #[doc = "   & \\;\\;\\;\\vdots \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=7,r_1=1)} \\\\"]
    #[doc = "   & \\;\\;\\;\\vdots \\\\"]
    #[doc = "     |\\mathbf{1}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=1,r_2=7,r_1=3)}"]
    #[doc = "   \\end{aligned}"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix \\f$\\rho\\f$, then its elements are modified as"]
    #[doc = "   \\f["]
    #[doc = "      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;"]
    #[doc = "          \\exp(i \\, (f(\\vec{r}_j) - f(\\vec{r}_k)) \\, ) \\; \\alpha \\, |j\\rangle\\langle k|,"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$f(\\vec{r}_j)\\f$ and \\f$f(\\vec{r}_k)\\f$ are determined as above.\\n\\n"]
    #[doc = ""]
    #[doc = " - The interpreted phase function can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyMultiVarPhaseFunc(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   would show, for the above example,"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyMultiVarPhaseFunc() multiplied a complex scalar of the form"]
    #[doc = "   //     exp(i ("]
    #[doc = "   //          + 1 x^2"]
    #[doc = "   //          + 2 y + 4 y^(-1)"]
    #[doc = "   //          - 3.14 z^0.5 ))"]
    #[doc = "   //   upon substates informed by qubits (under an unsigned binary encoding)"]
    #[doc = "   //     |x> = {0, 1}"]
    #[doc = "   //     |y> = {3, 4, 5}"]
    #[doc = "   //     |z> = {7}"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyMultiVarPhaseFuncOverrides() to additionally specify explicit phases for specific sub-register values."]
    #[doc = " - applyNamedPhaseFunc() for a set of specific and potentially multi-variable phase functions."]
    #[doc = " - applyPhaseFunc() for a single-variable polynomial exponential phase function, which is approximately twice as fast."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] coeffs the coefficients of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$"]
    #[doc = " @param[in] exponents the exponents of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$"]
    #[doc = " @param[in] numTermsPerReg a list of the number of \\p coeff and \\p exponent terms supplied for each variable/sub-register"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if any element of \\p numTermsPerReg is < 1"]
    #[doc = " - if \\p exponents contains a negative number"]
    #[doc = " - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMultiVarPhaseFunc(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        coeffs: *mut f64,
        exponents: *mut f64,
        numTermsPerReg: *mut ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " multi-variable exponential polynomial \"phase function\", and an explicit set of 'overriding'"]
    #[doc = " values at specific state indices."]
    #[doc = ""]
    #[doc = " See applyMultiVarPhaseFunc() first for a full description."]
    #[doc = ""]
    #[doc = " - As in applyMultiVarPhaseFunc(), the arguments \\p coeffs and \\p exponents specify a"]
    #[doc = "   multi-variable phase function \\f$f(\\vec{r})\\f$, where \\f$\\vec{r}\\f$ is determined by"]
    #[doc = "   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n"]
    #[doc = ""]
    #[doc = " - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies"]
    #[doc = "   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n"]
    #[doc = "   While flat, \\p overrideInds should be imagined grouped into sub-lists of length"]
    #[doc = "   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n"]
    #[doc = "   Each sublist corresponds to a single element of \\p overridePhases. \\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   int numRegs = 3;"]
    #[doc = "   int numOverrides = 2;"]
    #[doc = "   long long int overrideInds[] = { 0,0,0,   1,2,3  };"]
    #[doc = "   qreal overridePhases[]       = { M_PI,   - M_PI };"]
    #[doc = "   ```"]
    #[doc = "   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$"]
    #[doc = "   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)"]
    #[doc = "   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0))\\f$.\\n\\n"]
    #[doc = "   > Note that you cannot use applyMultiVarPhaseFuncOverrides() to override divergences"]
    #[doc = "   > in \\f$f(\\vec{r})\\f$, since each diverging value \\f$r_j\\f$ would need to be overriden"]
    #[doc = "   > as an \\f$\\vec{r}\\f$ coordinate for every basis state of the other registers; the number"]
    #[doc = "   > of overrides grows exponentially. Ergo, if \\p exponents contains a negative number"]
    #[doc = "   > (diverging at \\f$r_j=0\\f$), or \\p exponents contains a fractional number despite"]
    #[doc = "   > \\p encoding <b>=</b> ::TWOS_COMPLEMENT (producing complex phases at negative indices),"]
    #[doc = "   > you must instead call applyPhaseFuncOverrides() for each variable in turn and"]
    #[doc = "   > override the diverging \\f$r_j\\f$ (each independently of the other registers)."]
    #[doc = ""]
    #[doc = " - The interpreted overrides can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyMultiVarPhaseFuncOverrides(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyMultiVarPhaseFunc() multiplied ..."]
    #[doc = "   //   though with overrides"]
    #[doc = "   //     |x=0, y=0, z=0> -> exp(i 3.14159)"]
    #[doc = "   //     |x=1, y=2, z=3> -> exp(i (-3.14159))"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyNamedPhaseFunc() for a set of specific and potentially multi-variable phase functions."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density-matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] coeffs the coefficients of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$"]
    #[doc = " @param[in] exponents the exponents of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$"]
    #[doc = " @param[in] numTermsPerReg a list of the number of \\p coeff and \\p exponent terms supplied for each variable/sub-register"]
    #[doc = " @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change"]
    #[doc = " @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds"]
    #[doc = " @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if any element of \\p numTermsPerReg is < 1"]
    #[doc = " - if \\p exponents contains a negative number"]
    #[doc = " - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT"]
    #[doc = " - if any value in \\p overrideInds is not producible by its corresponding sub-register under the given \\p encoding (e.g. 2 unsigned qubits cannot represent index 9)"]
    #[doc = " - if \\p numOverrides < 0"]
    #[doc = " @author Tyson Jones"]
    pub fn applyMultiVarPhaseFuncOverrides(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        coeffs: *mut f64,
        exponents: *mut f64,
        numTermsPerReg: *mut ::std::os::raw::c_int,
        overrideInds: *mut ::std::os::raw::c_longlong,
        overridePhases: *mut f64,
        numOverrides: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " named (and potentially multi-variable) phase function."]
    #[doc = ""]
    #[doc = " This effects a diagonal unitary operator, with a phase function \\f$f(\\vec{r})\\f$ which may not be"]
    #[doc = " simply expressible as an exponential polynomial in functions applyPhaseFunc() and applyMultiVarPhaseFunc()."]
    #[doc = ""]
    #[doc = " Arguments \\p qubits and \\p numQubitsPerReg encode sub-registers of \\p qureg in the same"]
    #[doc = " manner as in applyMultiVarPhaseFunc():"]
    #[doc = " - Lists \\p qubits and \\p numQubitsPerReg together describe #`numRegs` sub-registers of \\p qureg,"]
    #[doc = "   which can each contain a different number of qubits. \\n"]
    #[doc = "   Although \\p qubits is a flat list of unique qubit indices, it should be imagined grouped into #`numRegs` sub-lists,"]
    #[doc = "   of lengths given by \\p numQubitsPerReg. \\n\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "      int qubits[] =          {0,1,  3,4,5,  7}"]
    #[doc = "      int numQubitsPerReg[] = {2,    3,      1};"]
    #[doc = "      int numRegs = 3;"]
    #[doc = "   ```"]
    #[doc = "   describes three sub-registers, which are bolded below in an eight-qubit zero-state."]
    #[doc = "   \\f["]
    #[doc = "      |r_3\\rangle \\; |0\\rangle \\; |r_2\\rangle \\; |0\\rangle \\; |r_1\\rangle ="]
    #[doc = "      |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle"]
    #[doc = "   \\f]"]
    #[doc = "   Note that the qubits need not be ordered increasing, and qubits within each sub-register"]
    #[doc = "   are assumed ordered least to most significant in that sub-register.\\n\\n"]
    #[doc = "   > List \\p qubits should have length equal to the sum of elements in \\p numQubitsPerReg."]
    #[doc = ""]
    #[doc = " - Each sub-register is associated with a variable \\f$r_j\\f$ in phase function \\f$f(\\vec{r})\\f$. \\n"]
    #[doc = "   For a given computational basis state of \\p qureg, the value of each variable is determined"]
    #[doc = "   by the binary value in the corresponding sub-register, when intepreted with ::bitEncoding \\p encoding. \\n"]
    #[doc = "   See ::bitEncoding for more information.\\n\\n"]
    #[doc = ""]
    #[doc = " - Argument \\p functionNameCode determines the phase function \\f$f(\\vec{r})\\f$.\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   int numRegs = 3;"]
    #[doc = "   enum phaseFunc functionNameCode = NORM;"]
    #[doc = "   ```"]
    #[doc = "   describes phase function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}) = \\sqrt{ {r_1}^2 + {r_2}^2 + {r_3} ^2 }."]
    #[doc = "   \\f]"]
    #[doc = "   See ::phaseFunc for a list and description of all named phase functions. \\n"]
    #[doc = "   Some phase functions, like \\p SCALED_NORM, require passing additional parameters, through"]
    #[doc = "   the function applyParamNamedPhaseFunc().\\n\\n"]
    #[doc = "   > If the phase function \\f$f(\\vec{r})\\f$ diverges at one or more \\f$\\vec{r}\\f$ values, you should instead"]
    #[doc = "   > use applyNamedPhaseFuncOverrides() and specify explicit phase changes for these coordinates."]
    #[doc = "   > Otherwise, the corresponding amplitudes of \\p qureg will become indeterminate (like `NaN`). \\n"]
    #[doc = ""]
    #[doc = " - The function \\f$f(\\vec{r})\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$"]
    #[doc = "   of computational basis state with the nominated sub-registers encoding values \\f$r_1, \\; \\dots\\f$."]
    #[doc = "   \\f["]
    #[doc = "    \\alpha \\, |r_{\\text{numRegs}}, \\; \\dots, \\; r_2, \\; r_1 \\rangle \\rightarrow \\, \\exp(i f(\\vec{r}\\,)) \\; \\alpha \\, |r_{\\text{numRegs}}, \\; \\dots, \\; r_2, \\; r_1 \\rangle."]
    #[doc = "   \\f]"]
    #[doc = "   For example, using the sub-registers in the above example and \\p encoding <b>=</b> \\p UNSIGNED, the"]
    #[doc = "   following states receive amplitude factors:"]
    #[doc = "   \\f["]
    #[doc = "   \\begin{aligned}"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=1)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{10}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=2)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=3)} \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |1\\rangle \\; |\\mathbf{00}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\"]
    #[doc = "   & \\;\\;\\;\\vdots \\\\"]
    #[doc = "     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=0,r_2=7,r_1=1)} \\\\"]
    #[doc = "   & \\;\\;\\;\\vdots \\\\"]
    #[doc = "     |\\mathbf{1}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &"]
    #[doc = "        \\rightarrow \\,"]
    #[doc = "            e^{i f(r_3=1,r_2=7,r_1=3)}"]
    #[doc = "   \\end{aligned}"]
    #[doc = "   \\f]\\n"]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix, its elements are modified to"]
    #[doc = "   \\f["]
    #[doc = "\\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;"]
    #[doc = "\\exp(i (f(\\vec{r}_j) \\, - \\, f(\\vec{r}_k))) \\; \\alpha \\, |j\\rangle\\langle k|"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$f(\\vec{r}_j)\\f$ and \\f$f(\\vec{r}_k)\\f$ are determined as above. This is equivalent"]
    #[doc = "   to modification"]
    #[doc = "   \\f["]
    #[doc = "          \\rho \\; \\rightarrow \\; \\hat{D} \\, \\rho \\, \\hat{D}^\\dagger"]
    #[doc = "   \\f]"]
    #[doc = "   where \\f$\\hat{D}\\f$ is the diagonal unitary"]
    #[doc = "   \\f["]
    #[doc = "      \\hat{D} = \\text{diag}\\, \\{ \\; e^{i f(\\vec{r_0})}, \\; e^{i f(\\vec{r_1})}, \\; \\dots \\; \\}."]
    #[doc = "   \\f]\\n"]
    #[doc = ""]
    #[doc = " - The interpreted phase function can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyNamedPhaseFunc(qureg, ..., INVERSE_DISTANCE, ... );"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyNamedPhaseFunc() multiplied a complex scalar of form"]
    #[doc = "   //     exp(i 1 / sqrt((x-y)^2 + (z-t)^2))"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyNamedPhaseFuncOverrides() to additionally specify phase values for specific sub-register indices."]
    #[doc = " - applyParamNamedPhaseFunc() to specify named phase functions which require additional parameters."]
    #[doc = " - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function."]
    #[doc = " - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density-matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r})\\f$"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if \\p functionNameCode is not a valid ::phaseFunc"]
    #[doc = " - if \\p functionNameCode requires additional parameters, which must instead be passed with applyParamNamedPhaseFunc()"]
    #[doc = " @author Tyson Jones"]
    pub fn applyNamedPhaseFunc(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        functionNameCode: phaseFunc,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " named (and potentially multi-variable) phase function, and an explicit set of 'overriding'"]
    #[doc = " values at specific state indices."]
    #[doc = ""]
    #[doc = " See applyNamedPhaseFunc() first for a full description."]
    #[doc = ""]
    #[doc = " - As in applyNamedPhaseFunc(), \\p functionNameCode specifies a"]
    #[doc = "   multi-variable phase function \\f$f(\\vec{r})\\f$, where \\f$\\vec{r}\\f$ is determined by"]
    #[doc = "   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n"]
    #[doc = ""]
    #[doc = " - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies"]
    #[doc = "   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n"]
    #[doc = "   While flat, \\p overrideInds should be imagined grouped into sub-lists of length"]
    #[doc = "   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n"]
    #[doc = "   Each sublist corresponds to a single element of \\p overridePhases. \\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   int numRegs = 3;"]
    #[doc = "   int numOverrides = 2;"]
    #[doc = "   long long int overrideInds[] = { 0,0,0,   1,2,3  };"]
    #[doc = "   qreal overridePhases[]       = { M_PI,   - M_PI };"]
    #[doc = "   ```"]
    #[doc = "   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$"]
    #[doc = "   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)"]
    #[doc = "   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0))\\f$.\\n\\n"]
    #[doc = ""]
    #[doc = " - The interpreted overrides can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyNamedPhaseFuncOverrides(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyNamedPhaseFunc() multiplied ..."]
    #[doc = "   //   though with overrides"]
    #[doc = "   //     |x=0, y=0, z=0> -> exp(i 3.14159)"]
    #[doc = "   //     |x=1, y=2, z=3> -> exp(i (-3.14159))"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyParamNamedPhaseFuncOverrides() to specify <em>parameterised</em> named phase functions, with phase overrides."]
    #[doc = " - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function."]
    #[doc = " - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector pr density-matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r})\\f$"]
    #[doc = " @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change"]
    #[doc = " @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds"]
    #[doc = " @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if \\p functionNameCode is not a valid ::phaseFunc"]
    #[doc = " - if \\p functionNameCode requires additional parameters, which must instead be passed with applyParamNamedPhaseFunc()"]
    #[doc = " - if any value in \\p overrideInds is not producible by its corresponding sub-register under the given \\p encoding (e.g. 2 unsigned qubits cannot represent index 9)"]
    #[doc = " - if \\p numOverrides < 0"]
    #[doc = " @author Tyson Jones"]
    pub fn applyNamedPhaseFuncOverrides(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        functionNameCode: phaseFunc,
        overrideInds: *mut ::std::os::raw::c_longlong,
        overridePhases: *mut f64,
        numOverrides: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " named, paramaterized (and potentially multi-variable) phase function."]
    #[doc = ""]
    #[doc = " See applyNamedPhaseFunc() for full documentation. \\n"]
    #[doc = " This function merely accepts additional ::phaseFunc names which accept one (or more) parameters."]
    #[doc = ""]
    #[doc = " - Argument \\p functionNameCode, which determines the phase function \\f$f(\\vec{r}, \\vec{\\theta})\\f$,"]
    #[doc = "   can include parameterised ::phaseFunc names like \\p SCALED_NORM, which require additional"]
    #[doc = "   parameters \\f$\\vec{\\theta}\\f$ passed via list \\p params.\\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   enum phaseFunc functionNameCode = SCALED_PRODUCT;"]
    #[doc = "   qreal params[] = {0.5};"]
    #[doc = "   int numParams = 1;"]
    #[doc = "   applyParamNamedPhaseFunc(..., functionNameCode, params, numParams);"]
    #[doc = "   ```"]
    #[doc = "   invokes phase function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}, \\theta)|_{\\theta=0.5} \\; = \\; 0.5 \\prod_j^{\\text{numRegs}} \\; r_j\\,."]
    #[doc = "   \\f]"]
    #[doc = "   See ::phaseFunc for all named phased functions."]
    #[doc = ""]
    #[doc = " - Functions with divergences, like \\p INVERSE_NORM and \\p SCALED_INVERSE_DISTANCE, must accompany"]
    #[doc = "   an extra parameter to specify an overriding phase at the divergence. For example,"]
    #[doc = "   ```"]
    #[doc = "   enum phaseFunc functionNameCode = SCALED_INVERSE_NORM;"]
    #[doc = "   qreal params[] = {0.5, M_PI};"]
    #[doc = "   int numParams = 2;"]
    #[doc = "   applyParamNamedPhaseFunc(..., functionNameCode, params, numParams);"]
    #[doc = "   ```"]
    #[doc = "   invokes phase function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}, \\theta)|_{\\theta=0.5} \\; = \\; \\begin{cases} \\pi & \\;\\;\\; \\vec{r}=\\vec{0} \\\\ \\displaystyle 0.5 \\left[ \\sum_j^{\\text{numRegs}} {r_j}^2 \\right]^{-1/2} & \\;\\;\\;\\text{otherwise} \\end{cases}."]
    #[doc = "   \\f]"]
    #[doc = "   Notice the order of the parameters matches the order of the words in the \\p phaseFunc."]
    #[doc = "   > Functions \\p SCALED_INVERSE_SHIFTED_NORM and \\p SCALED_INVERSE_SHIFTED_DISTANCE,"]
    #[doc = "   > which can have denominators arbitrarily close to zero, will invoke the"]
    #[doc = "   > divergence parameter whenever the denominator is smaller than (or equal to)"]
    #[doc = "   > machine precision `REAL_EPS`."]
    #[doc = ""]
    #[doc = " - Functions allowing the shifting of sub-register values, which are \\p SCALED_INVERSE_SHIFTED_NORM"]
    #[doc = "   and \\p SCALED_INVERSE_SHIFTED_DISTANCE, need these shift values to be passed in the \\p params"]
    #[doc = "   argument _after_ the scaling and divergence override parameters listed above. The function"]
    #[doc = "   \\p SCALED_INVERSE_SHIFTED_NORM needs as many extra parameters, as there are sub-registers;"]
    #[doc = "   \\p SCALED_INVERSE_SHIFTED_DISTANCE needs one extra parameter for each pair of sub-registers."]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   enum phaseFunc functionNameCode = SCALED_INVERSE_SHIFTED_NORM;"]
    #[doc = "   int qubits[] = {0,1,2,3, 4,5,6,7};"]
    #[doc = "   int qubitsPerReg[] = {4, 4};"]
    #[doc = "   qreal params[] = {0.5, M_PI, 0.8, -0.3};"]
    #[doc = "   int numParams = 4;"]
    #[doc = "   applyParamNamedPhaseFunc(..., qubits, qubitsPerReg, 2, ..., functionNameCode, params, numParams);"]
    #[doc = "   ```"]
    #[doc = "   invokes phase function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}) \\; = \\; \\begin{cases} \\pi & \\;\\;\\; \\vec{r}=\\vec{0} \\\\ \\displaystyle 0.5 \\left[(r_1-0.8)^2 + (r_2+0.3)^2\\right]^{-1/2} & \\;\\;\\;\\text{otherwise} \\end{cases}."]
    #[doc = "   \\f]"]
    #[doc = "   and"]
    #[doc = "   ```"]
    #[doc = "   enum phaseFunc functionNameCode = SCALED_INVERSE_SHIFTED_DISTANCE;"]
    #[doc = "   int qubits[] = {0,1, 2,3, 4,5, 6,7};"]
    #[doc = "   int qubitsPerReg[] = {2, 2, 2, 2};"]
    #[doc = "   qreal params[] = {0.5, M_PI, 0.8, -0.3};"]
    #[doc = "   int numParams = 4;"]
    #[doc = "   applyParamNamedPhaseFunc(..., qubits, qubitsPerReg, 4, ..., functionNameCode, params, numParams);"]
    #[doc = "   ```"]
    #[doc = "   invokes phase function"]
    #[doc = "   \\f["]
    #[doc = "      f(\\vec{r}) \\; = \\; \\begin{cases} \\pi & \\;\\;\\; \\vec{r}=\\vec{0} \\\\ \\displaystyle 0.5 \\left[(r_1-r_2-0.8)^2 + (r_3-r_4+0.3)^2\\right]^{-1/2} & \\;\\;\\;\\text{otherwise} \\end{cases}."]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = "   > You can further override \\f$f(\\vec{r}, \\vec{\\theta})\\f$ at one or more \\f$\\vec{r}\\f$ values"]
    #[doc = "   > via applyParamNamedPhaseFuncOverrides()."]
    #[doc = ""]
    #[doc = " - The interpreted parameterised phase function can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyParamNamedPhaseFunc(...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyNamedPhaseFunc() multiplied a complex scalar of form"]
    #[doc = "   //     exp(i (-0.5) / (x y z))"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyParamNamedPhaseFuncOverrides() to additionally specify phase values for specific sub-register indices."]
    #[doc = " - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function."]
    #[doc = " - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density-matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r}, \\vec{\\theta})\\f$"]
    #[doc = " @param[in] params a list of any additional parameters needed by the ::phaseFunc \\p functionNameCode"]
    #[doc = " @param[in] numParams the length of list \\p params"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if \\p functionNameCode is not a valid ::phaseFunc"]
    #[doc = " - if \\p numParams is incompatible with \\p functionNameCode (for example, no parameters were passed to \\p SCALED_PRODUCT)"]
    #[doc = " @author Tyson Jones"]
    #[doc = " @author Richard Meister (shifted functions)"]
    pub fn applyParamNamedPhaseFunc(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        functionNameCode: phaseFunc,
        params: *mut f64,
        numParams: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a"]
    #[doc = " named, parameterised (and potentially multi-variable) phase function, and an explicit set of 'overriding'"]
    #[doc = " values at specific state indices."]
    #[doc = ""]
    #[doc = " See applyParamNamedPhaseFunc() and applyNamedPhaseFunc() first for a full description."]
    #[doc = ""]
    #[doc = " - As in applyParamNamedPhaseFunc(), \\p functionNameCode specifies a parameterised"]
    #[doc = "   multi-variable phase function \\f$f(\\vec{r}, \\vec{\\theta})\\f$, where \\f$\\vec{\\theta}\\f$ is"]
    #[doc = "   passed in list \\p params, and \\f$\\vec{r}\\f$ is determined both by"]
    #[doc = "   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n"]
    #[doc = ""]
    #[doc = " - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies"]
    #[doc = "   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n"]
    #[doc = "   While flat, \\p overrideInds should be imagined grouped into sub-lists of length"]
    #[doc = "   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n"]
    #[doc = "   Each sublist corresponds to a single element of \\p overridePhases. \\n"]
    #[doc = "   For example,"]
    #[doc = "   ```"]
    #[doc = "   int numRegs = 3;"]
    #[doc = "   int numOverrides = 2;"]
    #[doc = "   long long int overrideInds[] = { 0,0,0,   1,2,3  };"]
    #[doc = "   qreal overridePhases[]       = { M_PI,   - M_PI };"]
    #[doc = "   ```"]
    #[doc = "   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$"]
    #[doc = "   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)"]
    #[doc = "   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0, \\vec{\\theta}))\\f$.\\n\\n"]
    #[doc = ""]
    #[doc = " - The interpreted overrides can be previewed in the QASM log, as a comment. \\n"]
    #[doc = "   For example:"]
    #[doc = "   ```"]
    #[doc = "   startRecordingQASM(qureg);"]
    #[doc = "   applyParamNamedPhaseFuncOverrides(qureg, ...);"]
    #[doc = "   printRecordedQASM(qureg);"]
    #[doc = "   ```"]
    #[doc = "   may show"]
    #[doc = "   ```"]
    #[doc = "   // Here, applyParamNamedPhaseFunc() multiplied ..."]
    #[doc = "   //   though with overrides"]
    #[doc = "   //     |x=0, y=0, z=0> -> exp(i 3.14159)"]
    #[doc = "   //     |x=1, y=2, z=3> -> exp(i (-3.14159))"]
    #[doc = "   ```"]
    #[doc = " \\n"]
    #[doc = ""]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function."]
    #[doc = " - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function."]
    #[doc = " - applyDiagonalOp() to apply a non-unitary diagonal operator."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg the state-vector or density-matrix to be modified"]
    #[doc = " @param[in] qubits a list of all the qubit indices contained in each sub-register"]
    #[doc = " @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits"]
    #[doc = " @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg"]
    #[doc = " @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register"]
    #[doc = " @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r}, \\vec{\\theta})\\f$"]
    #[doc = " @param[in] params a list of any additional parameters \\f$\\vec{\\theta}\\f$ needed by the ::phaseFunc \\p functionNameCode"]
    #[doc = " @param[in] numParams the length of list \\p params"]
    #[doc = " @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change"]
    #[doc = " @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds"]
    #[doc = " @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)"]
    #[doc = " @exception invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)"]
    #[doc = " - if the elements of \\p qubits are not unique (including if sub-registers overlap)"]
    #[doc = " - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)"]
    #[doc = " - if \\p encoding is not a valid ::bitEncoding"]
    #[doc = " - if the size of any sub-register is incompatible with \\p encoding (e.g. contains fewer than two qubits in \\p encoding <b>=</b> \\p TWOS_COMPLEMENT)"]
    #[doc = " - if \\p functionNameCode is not a valid ::phaseFunc"]
    #[doc = " - if \\p numParams is incompatible with \\p functionNameCode (for example, no parameters were passed to \\p SCALED_PRODUCT)"]
    #[doc = " - if any value in \\p overrideInds is not producible by its corresponding sub-register under the given \\p encoding (e.g. 2 unsigned qubits cannot represent index 9)"]
    #[doc = " - if \\p numOverrides < 0"]
    #[doc = " @author Tyson Jones"]
    pub fn applyParamNamedPhaseFuncOverrides(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubitsPerReg: *mut ::std::os::raw::c_int,
        numRegs: ::std::os::raw::c_int,
        encoding: bitEncoding,
        functionNameCode: phaseFunc,
        params: *mut f64,
        numParams: ::std::os::raw::c_int,
        overrideInds: *mut ::std::os::raw::c_longlong,
        overridePhases: *mut f64,
        numOverrides: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Applies the quantum Fourier transform (QFT) to the entirety of \\p qureg."]
    #[doc = " The effected unitary circuit (shown here for 4 qubits, bottom qubit is <b>0</b>) resembles"]
    #[doc = "\\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\draw (-2, 5) -- (23, 5);"]
    #[doc = "\\draw (-2, 3) -- (23, 3);"]
    #[doc = "\\draw (-2, 1) -- (23, 1);"]
    #[doc = "\\draw (-2, -1) -- (23, -1);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1, 4) -- (-1, 6) -- (1, 6) -- (1,4) -- cycle;"]
    #[doc = "\\node[draw=none] at (0, 5) {H};"]
    #[doc = ""]
    #[doc = "\\draw(2, 5) -- (2, 3);"]
    #[doc = "\\draw[fill=black] (2, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (2, 3) circle (.2);"]
    #[doc = "\\draw(4, 5) -- (4, 1);"]
    #[doc = "\\draw[fill=black] (4, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (4, 1) circle (.2);"]
    #[doc = "\\draw(6, 5) -- (6, -1);"]
    #[doc = "\\draw[fill=black] (6, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (6, -1) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8, 4-2) -- (-1+8, 6-2) -- (1+8, 6-2) -- (1+8,4-2) -- cycle;"]
    #[doc = "\\node[draw=none] at (8, 5-2) {H};"]
    #[doc = ""]
    #[doc = "\\draw(10, 5-2) -- (10, 3-2);"]
    #[doc = "\\draw[fill=black] (10, 5-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (10, 3-2) circle (.2);"]
    #[doc = "\\draw(12, 5-2) -- (12, 3-4);"]
    #[doc = "\\draw[fill=black] (12, 5-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (12, 3-4) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8+6, 4-4) -- (-1+8+6, 6-4) -- (1+8+6, 6-4) -- (1+8+6,4-4) -- cycle;"]
    #[doc = "\\node[draw=none] at (8+6, 5-4) {H};"]
    #[doc = ""]
    #[doc = "\\draw(16, 5-2-2) -- (16, 3-4);"]
    #[doc = "\\draw[fill=black] (16, 5-2-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (16, 3-4) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8+6+4, 4-4-2) -- (-1+8+6+4, 6-4-2) -- (1+8+6+4, 6-4-2) -- (1+8+6+4,4-4-2) -- cycle;"]
    #[doc = "\\node[draw=none] at (8+6+4, 5-4-2) {H};"]
    #[doc = ""]
    #[doc = "\\draw (20, 5) -- (20, -1);"]
    #[doc = "\\draw (20 - .35, 5 + .35) -- (20 + .35, 5 - .35);"]
    #[doc = "\\draw (20 - .35, 5 - .35) -- (20 + .35, 5 + .35);"]
    #[doc = "\\draw (20 - .35, -1 + .35) -- (20 + .35, -1 - .35);"]
    #[doc = "\\draw (20 - .35, -1 - .35) -- (20 + .35, -1 + .35);"]
    #[doc = "\\draw (22, 3) -- (22, 1);"]
    #[doc = "\\draw (22 - .35, 3 + .35) -- (22 + .35, 3 - .35);"]
    #[doc = "\\draw (22 - .35, 3 - .35) -- (22 + .35, 3 + .35);"]
    #[doc = "\\draw (22 - .35, 1 + .35) -- (22 + .35, 1 - .35);"]
    #[doc = "\\draw (22 - .35, 1 - .35) -- (22 + .35, 1 + .35);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = "\\f]"]
    #[doc = " though is performed more efficiently."]
    #[doc = ""]
    #[doc = " - If \\p qureg is a state-vector, the output amplitudes are the discrete Fourier"]
    #[doc = "   transform (DFT) of the input amplitudes, in the exact ordering. This is true"]
    #[doc = "   even if \\p qureg is unnormalised. \\n"]
    #[doc = "   Precisely,"]
    #[doc = "   \\f["]
    #[doc = "      \\text{QFT} \\, \\left(  \\sum\\limits_{x=0}^{2^N-1} \\alpha_x |x\\rangle \\right)"]
    #[doc = "      ="]
    #[doc = "      \\frac{1}{\\sqrt{2^N}}"]
    #[doc = "       \\sum\\limits_{x=0}^{2^N-1} \\left("]
    #[doc = "           \\sum\\limits_{y=0}^{2^N-1} e^{2 \\pi \\, i \\, x \\, y / 2^N} \\; \\alpha_y"]
    #[doc = "       \\right) |x\\rangle"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix \\f$\\rho\\f$, it will be changed under the unitary action"]
    #[doc = "   of the QFT. This can be imagined as each mixed state-vector undergoing the DFT"]
    #[doc = "   on its amplitudes. This is true even if \\p qureg is unnormalised."]
    #[doc = "   \\f["]
    #[doc = "      \\rho \\; \\rightarrow \\; \\text{QFT} \\; \\rho \\; \\text{QFT}^{\\dagger}"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " > This function merges contiguous controlled-phase gates into single invocations"]
    #[doc = " > of applyNamedPhaseFunc(), and hence is significantly faster than performing"]
    #[doc = " > the QFT circuit directly."]
    #[doc = ""]
    #[doc = " > Furthermore, in distributed mode, this function requires only \\f$\\log_2(\\text{\\#nodes})\\f$"]
    #[doc = " > rounds of pair-wise"]
    #[doc = " > communication, and hence is exponentially faster than directly performing the"]
    #[doc = " > DFT on the amplitudes of \\p qureg."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyQFT() to apply the QFT to a sub-register of \\p qureg."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg a state-vector or density matrix to modify"]
    #[doc = " @author Tyson Jones"]
    pub fn applyFullQFT(qureg: Qureg);
}
extern "C" {
    #[doc = " Applies the quantum Fourier transform (QFT) to a specific subset of qubits"]
    #[doc = " of the register \\p qureg."]
    #[doc = ""]
    #[doc = " The order of \\p qubits affects the ultimate unitary."]
    #[doc = " The canonical full-state QFT (applyFullQFT()) is achieved by targeting every"]
    #[doc = " qubit in increasing order."]
    #[doc = ""]
    #[doc = " The effected unitary circuit (shown here for \\p numQubits <b>= 4</b>) resembles"]
    #[doc = " \\f["]
    #[doc = "\\begin{tikzpicture}[scale=.5]"]
    #[doc = "\\draw (-2, 5) -- (23, 5);    \\node[draw=none] at (-4,5) {qubits[3]};"]
    #[doc = "\\draw (-2, 3) -- (23, 3);    \\node[draw=none] at (-4,3) {qubits[2]};"]
    #[doc = "\\draw (-2, 1) -- (23, 1);     \\node[draw=none] at (-4,1) {qubits[1]};"]
    #[doc = "\\draw (-2, -1) -- (23, -1);  \\node[draw=none] at (-4,-1) {qubits[0]};"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1, 4) -- (-1, 6) -- (1, 6) -- (1,4) -- cycle;"]
    #[doc = "\\node[draw=none] at (0, 5) {H};"]
    #[doc = ""]
    #[doc = "\\draw(2, 5) -- (2, 3);"]
    #[doc = "\\draw[fill=black] (2, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (2, 3) circle (.2);"]
    #[doc = "\\draw(4, 5) -- (4, 1);"]
    #[doc = "\\draw[fill=black] (4, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (4, 1) circle (.2);"]
    #[doc = "\\draw(6, 5) -- (6, -1);"]
    #[doc = "\\draw[fill=black] (6, 5) circle (.2);"]
    #[doc = "\\draw[fill=black] (6, -1) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8, 4-2) -- (-1+8, 6-2) -- (1+8, 6-2) -- (1+8,4-2) -- cycle;"]
    #[doc = "\\node[draw=none] at (8, 5-2) {H};"]
    #[doc = ""]
    #[doc = "\\draw(10, 5-2) -- (10, 3-2);"]
    #[doc = "\\draw[fill=black] (10, 5-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (10, 3-2) circle (.2);"]
    #[doc = "\\draw(12, 5-2) -- (12, 3-4);"]
    #[doc = "\\draw[fill=black] (12, 5-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (12, 3-4) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8+6, 4-4) -- (-1+8+6, 6-4) -- (1+8+6, 6-4) -- (1+8+6,4-4) -- cycle;"]
    #[doc = "\\node[draw=none] at (8+6, 5-4) {H};"]
    #[doc = ""]
    #[doc = "\\draw(16, 5-2-2) -- (16, 3-4);"]
    #[doc = "\\draw[fill=black] (16, 5-2-2) circle (.2);"]
    #[doc = "\\draw[fill=black] (16, 3-4) circle (.2);"]
    #[doc = ""]
    #[doc = "\\draw[fill=white] (-1+8+6+4, 4-4-2) -- (-1+8+6+4, 6-4-2) -- (1+8+6+4, 6-4-2) -- (1+8+6+4,4-4-2) -- cycle;"]
    #[doc = "\\node[draw=none] at (8+6+4, 5-4-2) {H};"]
    #[doc = ""]
    #[doc = "\\draw (20, 5) -- (20, -1);"]
    #[doc = "\\draw (20 - .35, 5 + .35) -- (20 + .35, 5 - .35);"]
    #[doc = "\\draw (20 - .35, 5 - .35) -- (20 + .35, 5 + .35);"]
    #[doc = "\\draw (20 - .35, -1 + .35) -- (20 + .35, -1 - .35);"]
    #[doc = "\\draw (20 - .35, -1 - .35) -- (20 + .35, -1 + .35);"]
    #[doc = "\\draw (22, 3) -- (22, 1);"]
    #[doc = "\\draw (22 - .35, 3 + .35) -- (22 + .35, 3 - .35);"]
    #[doc = "\\draw (22 - .35, 3 - .35) -- (22 + .35, 3 + .35);"]
    #[doc = "\\draw (22 - .35, 1 + .35) -- (22 + .35, 1 - .35);"]
    #[doc = "\\draw (22 - .35, 1 - .35) -- (22 + .35, 1 + .35);"]
    #[doc = "\\end{tikzpicture}"]
    #[doc = " \\f]"]
    #[doc = " though is performed more efficiently."]
    #[doc = ""]
    #[doc = " - If \\p qureg is a state-vector, the output amplitudes are a kronecker product of"]
    #[doc = "   the discrete Fourier transform (DFT) acting upon the targeted amplitudes, and the"]
    #[doc = "   remaining. \\n"]
    #[doc = "   Precisely,"]
    #[doc = "   - let \\f$|x,r\\rangle\\f$ represent a computational basis state where"]
    #[doc = "     \\f$x\\f$ is the binary value of the targeted qubits, and \\f$r\\f$ is the binary value"]
    #[doc = "     of the remaining qubits."]
    #[doc = "   - let \\f$|x_j,r_j\\rangle\\f$ be the \\f$j\\text{th}\\f$ such state."]
    #[doc = "   - let \\f$n =\\f$ \\p numQubits, and \\f$N =\\f$ `qureg.numQubitsRepresented`.\\n"]
    #[doc = " Then, this function effects"]
    #[doc = "   \\f["]
    #[doc = "      (\\text{QFT}\\otimes 1) \\, \\left(  \\sum\\limits_{j=0}^{2^N-1} \\alpha_j \\, |x_j,r_j\\rangle \\right)"]
    #[doc = "      ="]
    #[doc = "      \\frac{1}{\\sqrt{2^n}}"]
    #[doc = "       \\sum\\limits_{j=0}^{2^N-1} \\alpha_j \\left("]
    #[doc = "           \\sum\\limits_{y=0}^{2^n-1} e^{2 \\pi \\, i \\, x_j \\, y / 2^n} \\;"]
    #[doc = "           |y,r_j \\rangle"]
    #[doc = "       \\right)"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " - If \\p qureg is a density matrix \\f$\\rho\\f$, it will be changed under the unitary action"]
    #[doc = "   of the QFT. This can be imagined as each mixed state-vector undergoing the DFT"]
    #[doc = "   on its amplitudes. This is true even if \\p qureg is unnormalised."]
    #[doc = "   \\f["]
    #[doc = "      \\rho \\; \\rightarrow \\; \\text{QFT} \\; \\rho \\; \\text{QFT}^{\\dagger}"]
    #[doc = "   \\f]"]
    #[doc = ""]
    #[doc = " > This function merges contiguous controlled-phase gates into single invocations"]
    #[doc = " > of applyNamedPhaseFunc(), and hence is significantly faster than performing"]
    #[doc = " > the QFT circuit directly."]
    #[doc = ""]
    #[doc = " > Furthermore, in distributed mode, this function requires only \\f$\\log_2(\\text{\\#nodes})\\f$"]
    #[doc = " > rounds of pair-wise"]
    #[doc = " > communication, and hence is exponentially faster than directly performing the"]
    #[doc = " > DFT on the amplitudes of \\p qureg."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - applyFullQFT() to apply the QFT to the entirety of \\p qureg."]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg a state-vector or density matrix to modify"]
    #[doc = " @param[in] qubits a list of the qubits to operate the QFT upon"]
    #[doc = " @param[in] numQubits the length of list \\p qubits"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if any qubit in \\p qubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>"]
    #[doc = " - if \\p qubits contain any repetitions"]
    #[doc = " - if \\p numQubits <b>< 1</b>"]
    #[doc = " - if \\p numQubits <b>></b>`qureg.numQubitsRepresented`"]
    #[doc = " @throws segmentation-fault"]
    #[doc = " - if \\p qubits contains fewer elements than \\p numQubits"]
    #[doc = " @author Tyson Jones"]
    pub fn applyQFT(
        qureg: Qureg,
        qubits: *mut ::std::os::raw::c_int,
        numQubits: ::std::os::raw::c_int,
    );
}
extern "C" {
    #[doc = " Force the target \\p qubit of \\p qureg into the given classical \\p outcome, via a"]
    #[doc = " non-renormalising projection."]
    #[doc = ""]
    #[doc = " This function zeroes all amplitudes in the state-vector or density-matrix which"]
    #[doc = " correspond to the opposite \\p outcome given. Unlike collapseToOutcome(), it does"]
    #[doc = " not thereafter normalise \\p qureg, and hence may leave it in a non-physical state."]
    #[doc = ""]
    #[doc = " Note there is no requirement that the \\p outcome state has a non-zero proability, and hence"]
    #[doc = " this function may leave \\p qureg in a blank state, like that produced by initBlankState()."]
    #[doc = ""]
    #[doc = " @see"]
    #[doc = " - collapseToOutcome() for a norm-preserving equivalent, like a forced measurement"]
    #[doc = ""]
    #[doc = " @ingroup operator"]
    #[doc = " @param[in,out] qureg a state-vector or density matrix to modify"]
    #[doc = " @param[in] qubit the qubit to which to apply the projector"]
    #[doc = " @param[in] the single-qubit outcome (`0` or `1`) to project \\p qubit into"]
    #[doc = " @throws invalidQuESTInputError()"]
    #[doc = " - if \\p qubit is outside [0, `qureg.numQubitsRepresented`)"]
    #[doc = " - if \\p outcome is not in {0,1}"]
    #[doc = " @author Tyson Jones"]
    pub fn applyProjector(
        qureg: Qureg,
        qubit: ::std::os::raw::c_int,
        outcome: ::std::os::raw::c_int,
    );
}
extern "C" {
    pub fn statevec_twoQubitUnitary(
        qureg: Qureg,
        targetQubit1: ::std::os::raw::c_int,
        targetQubit2: ::std::os::raw::c_int,
        u: ComplexMatrix4,
    );
}
