quest_sys/
bindings.rs

1/* automatically generated by rust-bindgen 0.69.4 */
2
3#[doc = " A logger of QASM instructions\n\n @ingroup type\n @author Tyson Jones"]
4#[repr(C)]
5#[derive(Debug, Copy, Clone)]
6pub struct QASMLogger {
7    pub buffer: *mut ::std::os::raw::c_char,
8    pub bufferSize: ::std::os::raw::c_int,
9    pub bufferFill: ::std::os::raw::c_int,
10    pub isLogging: ::std::os::raw::c_int,
11}
12#[test]
13fn bindgen_test_layout_QASMLogger() {
14    const UNINIT: ::std::mem::MaybeUninit<QASMLogger> = ::std::mem::MaybeUninit::uninit();
15    let ptr = UNINIT.as_ptr();
16    assert_eq!(::std::mem::size_of::<QASMLogger>(), 24usize,);
17    assert_eq!(::std::mem::align_of::<QASMLogger>(), 8usize,);
18    assert_eq!(
19        unsafe { ::std::ptr::addr_of!((*ptr).buffer) as usize - ptr as usize },
20        0usize,
21    );
22    assert_eq!(
23        unsafe { ::std::ptr::addr_of!((*ptr).bufferSize) as usize - ptr as usize },
24        8usize,
25    );
26    assert_eq!(
27        unsafe { ::std::ptr::addr_of!((*ptr).bufferFill) as usize - ptr as usize },
28        12usize,
29    );
30    assert_eq!(
31        unsafe { ::std::ptr::addr_of!((*ptr).isLogging) as usize - ptr as usize },
32        16usize,
33    );
34}
35#[doc = " Represents an array of complex numbers grouped into an array of\n real components and an array of coressponding complex components.\n\n @ingroup type\n @author Ania Brown"]
36#[repr(C)]
37#[derive(Debug, Copy, Clone)]
38pub struct ComplexArray {
39    pub real: *mut f64,
40    pub imag: *mut f64,
41}
42#[test]
43fn bindgen_test_layout_ComplexArray() {
44    const UNINIT: ::std::mem::MaybeUninit<ComplexArray> = ::std::mem::MaybeUninit::uninit();
45    let ptr = UNINIT.as_ptr();
46    assert_eq!(::std::mem::size_of::<ComplexArray>(), 16usize,);
47    assert_eq!(::std::mem::align_of::<ComplexArray>(), 8usize,);
48    assert_eq!(
49        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
50        0usize,
51    );
52    assert_eq!(
53        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
54        8usize,
55    );
56}
57pub const pauliOpType_PAULI_I: pauliOpType = 0;
58pub const pauliOpType_PAULI_X: pauliOpType = 1;
59pub const pauliOpType_PAULI_Y: pauliOpType = 2;
60pub const pauliOpType_PAULI_Z: pauliOpType = 3;
61#[doc = " Codes for specifying Pauli operators\n\n @ingroup type\n @author Tyson Jones"]
62pub type pauliOpType = ::std::os::raw::c_uint;
63#[doc = " Represents one complex number.\n\n @ingroup type\n @author Ania Brown"]
64#[repr(C)]
65#[derive(Debug, Copy, Clone)]
66pub struct Complex {
67    pub real: f64,
68    pub imag: f64,
69}
70#[test]
71fn bindgen_test_layout_Complex() {
72    const UNINIT: ::std::mem::MaybeUninit<Complex> = ::std::mem::MaybeUninit::uninit();
73    let ptr = UNINIT.as_ptr();
74    assert_eq!(::std::mem::size_of::<Complex>(), 16usize,);
75    assert_eq!(::std::mem::align_of::<Complex>(), 8usize,);
76    assert_eq!(
77        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
78        0usize,
79    );
80    assert_eq!(
81        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
82        8usize,
83    );
84}
85#[doc = " Represents a 2x2 matrix of complex numbers.\n\n In C, a ::ComplexMatrix2 can be initialised by separately specifying\n the real and imaginary components as nested arrays. \\n\n For example,\n ```\n ComplexMatrix2 m = {\n     .real = {{1,2},\n              {3,4}},\n     .imag = {{5,6},\n              {7, 8}}};\n ```\n specifies matrix\n \\f[\n   m = \\begin{pmatrix}\n      1 + 5\\,i & 2+6\\,i \\\\\n      3 + 7\\,i & 4+ 8\\,i\n   \\end{pmatrix}\n \\f]\n\n @see\n - ::ComplexMatrix4\n - createComplexMatrixN()\n\n @ingroup type\n @author Balint Koczor\n @author Tyson Jones (doc)"]
86#[repr(C)]
87#[derive(Debug, Copy, Clone)]
88pub struct ComplexMatrix2 {
89    pub real: [[f64; 2usize]; 2usize],
90    pub imag: [[f64; 2usize]; 2usize],
91}
92#[test]
93fn bindgen_test_layout_ComplexMatrix2() {
94    const UNINIT: ::std::mem::MaybeUninit<ComplexMatrix2> = ::std::mem::MaybeUninit::uninit();
95    let ptr = UNINIT.as_ptr();
96    assert_eq!(::std::mem::size_of::<ComplexMatrix2>(), 64usize,);
97    assert_eq!(::std::mem::align_of::<ComplexMatrix2>(), 8usize,);
98    assert_eq!(
99        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
100        0usize,
101    );
102    assert_eq!(
103        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
104        32usize,
105    );
106}
107#[doc = " Represents a 4x4 matrix of complex numbers\n\n In C, a ::ComplexMatrix4 can be initialised by separately specifying\n the real and imaginary components as nested arrays. Note that in C99, a short row\n that ends with a 0 with be padded with 0. \\n\n For example,\n ```\n ComplexMatrix4 m = {\n      .real = {{1,2, 3, 4},\n               {0},\n               {5,6,7,8},\n               {0}},\n      .imag = {{0},{0},{0},{1,1,1,1}}};\n ```\n specifies matrix\n \\f[\n   m = \\begin{pmatrix}\n      1 & 2 & 3 & 4 \\\\\n      0 & 0 & 0 & 0 \\\\\n      5 & 6 & 7 & 8 \\\\\n      i & i & i & i\n   \\end{pmatrix}\n \\f]\n\n @see\n - ::ComplexMatrix2\n - createComplexMatrixN()\n\n @ingroup type\n @author Balint Koczor\n @author Tyson Jones (doc)"]
108#[repr(C)]
109#[derive(Debug, Copy, Clone)]
110pub struct ComplexMatrix4 {
111    pub real: [[f64; 4usize]; 4usize],
112    pub imag: [[f64; 4usize]; 4usize],
113}
114#[test]
115fn bindgen_test_layout_ComplexMatrix4() {
116    const UNINIT: ::std::mem::MaybeUninit<ComplexMatrix4> = ::std::mem::MaybeUninit::uninit();
117    let ptr = UNINIT.as_ptr();
118    assert_eq!(::std::mem::size_of::<ComplexMatrix4>(), 256usize,);
119    assert_eq!(::std::mem::align_of::<ComplexMatrix4>(), 8usize,);
120    assert_eq!(
121        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
122        0usize,
123    );
124    assert_eq!(
125        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
126        128usize,
127    );
128}
129#[doc = " Represents a general 2^N by 2^N matrix of complex numbers.\n\n @ingroup type\n @author Tyson Jones"]
130#[repr(C)]
131#[derive(Debug, Copy, Clone)]
132pub struct ComplexMatrixN {
133    pub numQubits: ::std::os::raw::c_int,
134    pub real: *mut *mut f64,
135    pub imag: *mut *mut f64,
136}
137#[test]
138fn bindgen_test_layout_ComplexMatrixN() {
139    const UNINIT: ::std::mem::MaybeUninit<ComplexMatrixN> = ::std::mem::MaybeUninit::uninit();
140    let ptr = UNINIT.as_ptr();
141    assert_eq!(::std::mem::size_of::<ComplexMatrixN>(), 24usize,);
142    assert_eq!(::std::mem::align_of::<ComplexMatrixN>(), 8usize,);
143    assert_eq!(
144        unsafe { ::std::ptr::addr_of!((*ptr).numQubits) as usize - ptr as usize },
145        0usize,
146    );
147    assert_eq!(
148        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
149        8usize,
150    );
151    assert_eq!(
152        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
153        16usize,
154    );
155}
156#[doc = " Represents a 3-vector of real numbers\n\n @ingroup type\n @author Ania Brown"]
157#[repr(C)]
158#[derive(Debug, Copy, Clone)]
159pub struct Vector {
160    pub x: f64,
161    pub y: f64,
162    pub z: f64,
163}
164#[test]
165fn bindgen_test_layout_Vector() {
166    const UNINIT: ::std::mem::MaybeUninit<Vector> = ::std::mem::MaybeUninit::uninit();
167    let ptr = UNINIT.as_ptr();
168    assert_eq!(::std::mem::size_of::<Vector>(), 24usize,);
169    assert_eq!(::std::mem::align_of::<Vector>(), 8usize,);
170    assert_eq!(
171        unsafe { ::std::ptr::addr_of!((*ptr).x) as usize - ptr as usize },
172        0usize,
173    );
174    assert_eq!(
175        unsafe { ::std::ptr::addr_of!((*ptr).y) as usize - ptr as usize },
176        8usize,
177    );
178    assert_eq!(
179        unsafe { ::std::ptr::addr_of!((*ptr).z) as usize - ptr as usize },
180        16usize,
181    );
182}
183pub const phaseFunc_NORM: phaseFunc = 0;
184pub const phaseFunc_SCALED_NORM: phaseFunc = 1;
185pub const phaseFunc_INVERSE_NORM: phaseFunc = 2;
186pub const phaseFunc_SCALED_INVERSE_NORM: phaseFunc = 3;
187pub const phaseFunc_SCALED_INVERSE_SHIFTED_NORM: phaseFunc = 4;
188pub const phaseFunc_PRODUCT: phaseFunc = 5;
189pub const phaseFunc_SCALED_PRODUCT: phaseFunc = 6;
190pub const phaseFunc_INVERSE_PRODUCT: phaseFunc = 7;
191pub const phaseFunc_SCALED_INVERSE_PRODUCT: phaseFunc = 8;
192pub const phaseFunc_DISTANCE: phaseFunc = 9;
193pub const phaseFunc_SCALED_DISTANCE: phaseFunc = 10;
194pub const phaseFunc_INVERSE_DISTANCE: phaseFunc = 11;
195pub const phaseFunc_SCALED_INVERSE_DISTANCE: phaseFunc = 12;
196pub const phaseFunc_SCALED_INVERSE_SHIFTED_DISTANCE: phaseFunc = 13;
197pub const phaseFunc_SCALED_INVERSE_SHIFTED_WEIGHTED_DISTANCE: phaseFunc = 14;
198#[doc = " Flags for specifying named phase functions.\n These can be passed to functions applyNamedPhaseFunc(), applyNamedPhaseFuncOverrides(),\n applyParamNamedPhaseFunc(), and applyParamNamedPhaseFuncOverrides().\n\n Norm based phase functions:\n    - \\p NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\sqrt{x^2 + y^2 + \\dots}\\f$\n    - \\p SCALED_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\text{coeff} \\sqrt{x^2 + y^2 + \\dots}\\f$\n    - \\p INVERSE_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$1/\\sqrt{x^2 + y^2 + \\dots}\\f$\n    - \\p SCALED_INVERSE_NORM maps state \\f$|x\\rangle|y\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{x^2 + y^2 + \\dots}\\f$\n    - \\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$\n\n Product based phase functions:\n    - \\p PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$x \\; y \\; z \\dots\\f$\n    - \\p SCALED_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$\\text{coeff} \\; x \\; y \\; z \\dots\\f$\n    - \\p INVERSE_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$1/(x \\; y \\; z \\dots)\\f$\n    - \\p SCALED_INVERSE_PRODUCT maps state \\f$|x\\rangle|y\\rangle|z\\rangle\\dots\\f$ to \\f$\\text{coeff}/(x \\; y \\; z \\dots)\\f$\n\n Euclidean distance based phase functions:\n    - \\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$\n    - \\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$\n    - \\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$\n    - \\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$\n    - \\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$\n    - \\p SCALED_INVERSE_SHIFTED_WEIGHTED_DISTANCE maps state \\f$|x_1\\rangle|x_2\\rangle|y_1\\rangle|y_2\\rangle\\dots\\f$ to \\f$\\text{coeff}/\\sqrt{f_x \\, (x_1-x_2-\\Delta_x)^2 + f_y \\; (y_1-y_2-\\Delta_y)^2 + \\dots}\\f$\n\n @ingroup type\n @author Tyson Jones\n @author Richard Meister (shifted functions)"]
199pub type phaseFunc = ::std::os::raw::c_uint;
200pub const bitEncoding_UNSIGNED: bitEncoding = 0;
201pub const bitEncoding_TWOS_COMPLEMENT: bitEncoding = 1;
202#[doc = " Flags for specifying how the bits in sub-register computational basis states\n are mapped to indices in functions like applyPhaseFunc().\n\n    - \\p UNSIGNED means the bits encode an unsigned integer, hence\n \\f[\n \\begin{aligned}\n     |00\\rangle & \\rightarrow \\, 0 \\\\\n     |01\\rangle & \\rightarrow \\, 1 \\\\\n     |10\\rangle & \\rightarrow \\, 2 \\\\\n     |11\\rangle & \\rightarrow \\, 3\n \\end{aligned}\n \\f]\n    - \\p TWOS_COMPLEMENT means the bits encode a signed integer through\n      [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement), such that\n \\f[\n \\begin{aligned}\n     |000\\rangle & \\rightarrow \\, 0 \\\\\n     |001\\rangle & \\rightarrow \\, 1 \\\\\n     |010\\rangle & \\rightarrow \\, 2 \\\\\n     |011\\rangle & \\rightarrow \\, 3 \\\\\n     |100\\rangle & \\rightarrow \\,-4 \\\\\n     |101\\rangle & \\rightarrow \\,-3 \\\\\n     |110\\rangle & \\rightarrow \\,-2 \\\\\n     |111\\rangle & \\rightarrow \\,-1\n \\end{aligned}\n \\f]\n > Remember that the qubits specified within a sub-register, and their ordering (least to most\n > significant) determine the bits of a computational basis state, before intrepretation\n > as an encoding of an integer.\n\n @ingroup type\n @author Tyson Jones"]
203pub type bitEncoding = ::std::os::raw::c_uint;
204#[doc = " A Pauli Hamiltonian, expressed as a real-weighted sum of pauli products,\n and which can hence represent any Hermitian operator.\n\n @ingroup type\n @author Tyson Jones"]
205#[repr(C)]
206#[derive(Debug, Copy, Clone)]
207pub struct PauliHamil {
208    #[doc = "The Pauli operators acting on each qubit, flattened over every operator.\n! This is a flat array of length PauliHamil.numSumTerms * PauliHamil.numQubits."]
209    pub pauliCodes: *mut pauliOpType,
210    #[doc = "The real coefficient of each Pauli product. This is an array of length PauliHamil.numSumTerms;"]
211    pub termCoeffs: *mut f64,
212    #[doc = "The number of terms in the weighted sum, or the number of Pauli products."]
213    pub numSumTerms: ::std::os::raw::c_int,
214    #[doc = "The number of qubits informing the Hilbert dimension of the Hamiltonian."]
215    pub numQubits: ::std::os::raw::c_int,
216}
217#[test]
218fn bindgen_test_layout_PauliHamil() {
219    const UNINIT: ::std::mem::MaybeUninit<PauliHamil> = ::std::mem::MaybeUninit::uninit();
220    let ptr = UNINIT.as_ptr();
221    assert_eq!(::std::mem::size_of::<PauliHamil>(), 24usize,);
222    assert_eq!(::std::mem::align_of::<PauliHamil>(), 8usize,);
223    assert_eq!(
224        unsafe { ::std::ptr::addr_of!((*ptr).pauliCodes) as usize - ptr as usize },
225        0usize,
226    );
227    assert_eq!(
228        unsafe { ::std::ptr::addr_of!((*ptr).termCoeffs) as usize - ptr as usize },
229        8usize,
230    );
231    assert_eq!(
232        unsafe { ::std::ptr::addr_of!((*ptr).numSumTerms) as usize - ptr as usize },
233        16usize,
234    );
235    assert_eq!(
236        unsafe { ::std::ptr::addr_of!((*ptr).numQubits) as usize - ptr as usize },
237        20usize,
238    );
239}
240#[doc = " Represents a diagonal complex operator on the full Hilbert state of a \\p Qureg.\n The operator need not be unitary nor Hermitian (which would constrain it to\n real values)\n\n @ingroup type\n @author Tyson Jones"]
241#[repr(C)]
242#[derive(Debug, Copy, Clone)]
243pub struct DiagonalOp {
244    #[doc = "The number of qubits this operator can act on (informing its size)"]
245    pub numQubits: ::std::os::raw::c_int,
246    #[doc = "The number of the 2^numQubits amplitudes stored on each distributed node"]
247    pub numElemsPerChunk: ::std::os::raw::c_longlong,
248    #[doc = "The number of nodes between which the elements of this operator are split"]
249    pub numChunks: ::std::os::raw::c_int,
250    #[doc = "The position of the chunk of the operator held by this process in the full operator"]
251    pub chunkId: ::std::os::raw::c_int,
252    #[doc = "The real values of the 2^numQubits complex elements"]
253    pub real: *mut f64,
254    #[doc = "The imaginary values of the 2^numQubits complex elements"]
255    pub imag: *mut f64,
256    #[doc = "A copy of the elements stored persistently on the GPU"]
257    pub deviceOperator: ComplexArray,
258}
259#[test]
260fn bindgen_test_layout_DiagonalOp() {
261    const UNINIT: ::std::mem::MaybeUninit<DiagonalOp> = ::std::mem::MaybeUninit::uninit();
262    let ptr = UNINIT.as_ptr();
263    assert_eq!(::std::mem::size_of::<DiagonalOp>(), 56usize,);
264    assert_eq!(::std::mem::align_of::<DiagonalOp>(), 8usize,);
265    assert_eq!(
266        unsafe { ::std::ptr::addr_of!((*ptr).numQubits) as usize - ptr as usize },
267        0usize,
268    );
269    assert_eq!(
270        unsafe { ::std::ptr::addr_of!((*ptr).numElemsPerChunk) as usize - ptr as usize },
271        8usize,
272    );
273    assert_eq!(
274        unsafe { ::std::ptr::addr_of!((*ptr).numChunks) as usize - ptr as usize },
275        16usize,
276    );
277    assert_eq!(
278        unsafe { ::std::ptr::addr_of!((*ptr).chunkId) as usize - ptr as usize },
279        20usize,
280    );
281    assert_eq!(
282        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
283        24usize,
284    );
285    assert_eq!(
286        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
287        32usize,
288    );
289    assert_eq!(
290        unsafe { ::std::ptr::addr_of!((*ptr).deviceOperator) as usize - ptr as usize },
291        40usize,
292    );
293}
294#[doc = " Represents a diagonal complex operator of a smaller dimension than the full\n Hilbert state of a \\p Qureg.\n\n @ingroup type\n @author Tyson Jones"]
295#[repr(C)]
296#[derive(Debug, Copy, Clone)]
297pub struct SubDiagonalOp {
298    #[doc = "The number of target qubits which this SubDiagonalOp can operate upon"]
299    pub numQubits: ::std::os::raw::c_int,
300    #[doc = "The number of diagonal elements, i.e. 2^numQubits"]
301    pub numElems: ::std::os::raw::c_longlong,
302    #[doc = "The real values of the 2^numQubits complex elements"]
303    pub real: *mut f64,
304    #[doc = "The imaginary values of the 2^numQubits complex elements"]
305    pub imag: *mut f64,
306}
307#[test]
308fn bindgen_test_layout_SubDiagonalOp() {
309    const UNINIT: ::std::mem::MaybeUninit<SubDiagonalOp> = ::std::mem::MaybeUninit::uninit();
310    let ptr = UNINIT.as_ptr();
311    assert_eq!(::std::mem::size_of::<SubDiagonalOp>(), 32usize,);
312    assert_eq!(::std::mem::align_of::<SubDiagonalOp>(), 8usize,);
313    assert_eq!(
314        unsafe { ::std::ptr::addr_of!((*ptr).numQubits) as usize - ptr as usize },
315        0usize,
316    );
317    assert_eq!(
318        unsafe { ::std::ptr::addr_of!((*ptr).numElems) as usize - ptr as usize },
319        8usize,
320    );
321    assert_eq!(
322        unsafe { ::std::ptr::addr_of!((*ptr).real) as usize - ptr as usize },
323        16usize,
324    );
325    assert_eq!(
326        unsafe { ::std::ptr::addr_of!((*ptr).imag) as usize - ptr as usize },
327        24usize,
328    );
329}
330#[doc = " Represents a system of qubits.\n Qubits are zero-based\n\n @ingroup type\n @author Ania Brown\n @author Tyson Jones (density matrix)"]
331#[repr(C)]
332#[derive(Debug, Copy, Clone)]
333pub struct Qureg {
334    #[doc = "Whether this instance is a density-state representation"]
335    pub isDensityMatrix: ::std::os::raw::c_int,
336    #[doc = "The number of qubits represented in either the state-vector or density matrix"]
337    pub numQubitsRepresented: ::std::os::raw::c_int,
338    #[doc = "Number of qubits in the state-vector - this is double the number represented for mixed states"]
339    pub numQubitsInStateVec: ::std::os::raw::c_int,
340    #[doc = "Number of probability amplitudes held in stateVec by this process\n! In the non-MPI version, this is the total number of amplitudes"]
341    pub numAmpsPerChunk: ::std::os::raw::c_longlong,
342    #[doc = "Total number of amplitudes, which are possibly distributed among machines"]
343    pub numAmpsTotal: ::std::os::raw::c_longlong,
344    #[doc = "The position of the chunk of the state vector held by this process in the full state vector"]
345    pub chunkId: ::std::os::raw::c_int,
346    #[doc = "Number of chunks the state vector is broken up into -- the number of MPI processes used"]
347    pub numChunks: ::std::os::raw::c_int,
348    #[doc = "Computational state amplitudes - a subset thereof in the MPI version"]
349    pub stateVec: ComplexArray,
350    #[doc = "Temporary storage for a chunk of the state vector received from another process in the MPI version"]
351    pub pairStateVec: ComplexArray,
352    #[doc = "Storage for wavefunction amplitudes in the GPU version"]
353    pub deviceStateVec: ComplexArray,
354    #[doc = "Storage for reduction of probabilities on GPU"]
355    pub firstLevelReduction: *mut f64,
356    #[doc = "Storage for reduction of probabilities on GPU"]
357    pub secondLevelReduction: *mut f64,
358    #[doc = "Storage for wavefunction amplitues and config (copy of QuESTEnv's handle) in cuQuantum deployment"]
359    pub cuStateVec: *mut ::std::os::raw::c_void,
360    pub deviceCuStateVec: *mut ::std::os::raw::c_void,
361    pub cuConfig: *mut *mut ::std::os::raw::c_void,
362    #[doc = "Storage for generated QASM output"]
363    pub qasmLog: *mut QASMLogger,
364}
365#[test]
366fn bindgen_test_layout_Qureg() {
367    const UNINIT: ::std::mem::MaybeUninit<Qureg> = ::std::mem::MaybeUninit::uninit();
368    let ptr = UNINIT.as_ptr();
369    assert_eq!(::std::mem::size_of::<Qureg>(), 136usize,);
370    assert_eq!(::std::mem::align_of::<Qureg>(), 8usize,);
371    assert_eq!(
372        unsafe { ::std::ptr::addr_of!((*ptr).isDensityMatrix) as usize - ptr as usize },
373        0usize,
374    );
375    assert_eq!(
376        unsafe { ::std::ptr::addr_of!((*ptr).numQubitsRepresented) as usize - ptr as usize },
377        4usize,
378    );
379    assert_eq!(
380        unsafe { ::std::ptr::addr_of!((*ptr).numQubitsInStateVec) as usize - ptr as usize },
381        8usize,
382    );
383    assert_eq!(
384        unsafe { ::std::ptr::addr_of!((*ptr).numAmpsPerChunk) as usize - ptr as usize },
385        16usize,
386    );
387    assert_eq!(
388        unsafe { ::std::ptr::addr_of!((*ptr).numAmpsTotal) as usize - ptr as usize },
389        24usize,
390    );
391    assert_eq!(
392        unsafe { ::std::ptr::addr_of!((*ptr).chunkId) as usize - ptr as usize },
393        32usize,
394    );
395    assert_eq!(
396        unsafe { ::std::ptr::addr_of!((*ptr).numChunks) as usize - ptr as usize },
397        36usize,
398    );
399    assert_eq!(
400        unsafe { ::std::ptr::addr_of!((*ptr).stateVec) as usize - ptr as usize },
401        40usize,
402    );
403    assert_eq!(
404        unsafe { ::std::ptr::addr_of!((*ptr).pairStateVec) as usize - ptr as usize },
405        56usize,
406    );
407    assert_eq!(
408        unsafe { ::std::ptr::addr_of!((*ptr).deviceStateVec) as usize - ptr as usize },
409        72usize,
410    );
411    assert_eq!(
412        unsafe { ::std::ptr::addr_of!((*ptr).firstLevelReduction) as usize - ptr as usize },
413        88usize,
414    );
415    assert_eq!(
416        unsafe { ::std::ptr::addr_of!((*ptr).secondLevelReduction) as usize - ptr as usize },
417        96usize,
418    );
419    assert_eq!(
420        unsafe { ::std::ptr::addr_of!((*ptr).cuStateVec) as usize - ptr as usize },
421        104usize,
422    );
423    assert_eq!(
424        unsafe { ::std::ptr::addr_of!((*ptr).deviceCuStateVec) as usize - ptr as usize },
425        112usize,
426    );
427    assert_eq!(
428        unsafe { ::std::ptr::addr_of!((*ptr).cuConfig) as usize - ptr as usize },
429        120usize,
430    );
431    assert_eq!(
432        unsafe { ::std::ptr::addr_of!((*ptr).qasmLog) as usize - ptr as usize },
433        128usize,
434    );
435}
436#[doc = " Information about the environment the program is running in.\n In practice, this holds info about MPI ranks and helps to hide MPI initialization code\n\n @ingroup type\n @author Ania Brown\n @author Tyson Jones (seeding)"]
437#[repr(C)]
438#[derive(Debug, Copy, Clone)]
439pub struct QuESTEnv {
440    pub rank: ::std::os::raw::c_int,
441    pub numRanks: ::std::os::raw::c_int,
442    pub seeds: *mut ::std::os::raw::c_ulong,
443    pub numSeeds: ::std::os::raw::c_int,
444    pub cuConfig: *mut *mut ::std::os::raw::c_void,
445}
446#[test]
447fn bindgen_test_layout_QuESTEnv() {
448    const UNINIT: ::std::mem::MaybeUninit<QuESTEnv> = ::std::mem::MaybeUninit::uninit();
449    let ptr = UNINIT.as_ptr();
450    assert_eq!(::std::mem::size_of::<QuESTEnv>(), 32usize,);
451    assert_eq!(::std::mem::align_of::<QuESTEnv>(), 8usize,);
452    assert_eq!(
453        unsafe { ::std::ptr::addr_of!((*ptr).rank) as usize - ptr as usize },
454        0usize,
455    );
456    assert_eq!(
457        unsafe { ::std::ptr::addr_of!((*ptr).numRanks) as usize - ptr as usize },
458        4usize,
459    );
460    assert_eq!(
461        unsafe { ::std::ptr::addr_of!((*ptr).seeds) as usize - ptr as usize },
462        8usize,
463    );
464    assert_eq!(
465        unsafe { ::std::ptr::addr_of!((*ptr).numSeeds) as usize - ptr as usize },
466        16usize,
467    );
468    assert_eq!(
469        unsafe { ::std::ptr::addr_of!((*ptr).cuConfig) as usize - ptr as usize },
470        24usize,
471    );
472}
473extern "C" {
474    #[doc = " Creates a state-vector Qureg object representing a set of qubits which will remain in a pure state.\n\n Allocates space for a state-vector of complex amplitudes, which assuming a single\n ::qreal floating-point number requires <b>qrealBytes</b>, requires memory\n \\f[\n      \\text{qrealBytes} \\times 2 \\times 2^\\text{numQubits}\\;\\;\\text{(bytes)},\n \\f]\n though there are additional memory costs in GPU and distributed modes.\n\n The returned ::Qureg begins in the zero state, as produced by initZeroState().\n\n Once created, the following ::Qureg fields are relevant in all backends:\n - Qureg.numQubitsRepresented\n - Qureg.isDensityMatrix\n\n > ::QuESTEnv \\p env must be prior created with createQuESTEnv().\n\n ### Serial\n In serial and local (non-distributed) multithreaded modes, a state-vector \\p Qureg\n costs only the memory above. For example, at double precision\n (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:\n \\p numQubits  | memory\n ------------- | -------------\n 10            | 16 KiB\n 16            | 1 MiB\n 20            | 16 MiB\n 26            | 1 GiB\n 30            | 16 GiB\n\n Individual amplitudes should be fetched and modified with functions like getAmp() and setAmps().\n However, it is sometimes useful to access the state-vector directly, for example to\n create your own low-level (high performance) multithreaded functions.\n In those instants, Qureg.stateVec can be accessed directly, storing the real\n and imaginary components of the state-vector amplitudes in:\n - `Qureg.stateVec.real`\n - `Qureg.stateVec.imag`\n\n The total number of amplitudes in the state-vector is\n - Qureg.numAmpsTotal\n\n For example,\n ```\n Qureg qureg = createQureg(10, env);\n\n // ruin a perfectly good state-vector\n for (long long int i=0; i<qureg.numAmpsTotal; i++) {\n     qureg.stateVec.real[i] = rand();\n     qureg.stateVec.imag[i] = rand();\n }\n ```\n \\n\n\n\n ### GPU\n\n In GPU-accelerated mode, an <em>additional</em> state-vector is created in GPU memory.\n Therefore both RAM and VRAM must be of sufficient memory to store the state-vector,\n each of the size indicated in the Serial table above.\n\n > Note that many GPUs do not support quad precision ::qreal.\n\n Individual amplitudes of the created ::Qureg should be fetched and modified with functions like getAmp() and setAmps().\n This is especially important since the GPU state-vector can be accessed directly,\n and changes to Qureg.stateVec will be ignored and overwritten.\n To modify the state-vector \"directly\", one must use copyStateFromGPU() and\n copyStateToGPU() before and after.\n\n For example,\n ```\n Qureg qureg = createQureg(10, env);\n\n // ruin a perfectly good state-vector\n for (long long int i=0; i<qureg.numAmpsTotal; i++) {\n     qureg.stateVec.real[i] = rand();\n     qureg.stateVec.imag[i] = rand();\n }\n copyStateToGPU();\n ```\n \\n\n\n\n ### Distributed\n\n In distributed mode, the state-vector is uniformly partitioned between the <b>N</b>\n distributed nodes.\n\n > Only a power-of-2 number of nodes <b>N</b> may be used (e.g. <b>N = 1, 2, 4, 8, </b>...).\n > There must additionally be at least 1 amplitude of a state-vector stored on each node.\n > This means one cannot create a state-vector ::Qureg with fewer than \\f$\\log_2(\\text{N})\\f$ qubits.\n\n In addition to Qureg.stateVec, additional memory is allocated on each node for\n communication buffers, of size equal to the state-vector partition.\n Hence the total memory <em>per-node</em> required is:\n \\f[\n      2 \\times \\text{qrealBytes} \\times 2 \\times 2^\\text{numQubits}/N  \\;\\;\\text{(bytes)},\n \\f]\n\n For example, at double precision\n (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:\n\n | \\p numQubits | memory per node  |||||\n |-------------|-------|-------|-------|--------| ------ |\n |            | <b>N = 2</b>  | <b>N = 4</b> | <b>N = 8</b> | <b>N = 16</b> | <b>N = 32</b> |\n | 10            | 16 KiB | 8 KiB | 4 KiB | 2 KiB  | 1 KiB  |\n | 20           | 16 MiB | 8 MiB | 4 MiB | 2 MiB  | 1 MiB  |\n | 30           | 16 GiB | 8 GiB | 4 GiB | 2 GiB  | 1 GiB  |\n | 40           | 16 TiB | 8 TiB | 4 TiB | 2 TiB  | 1 TiB  |\n\n State-vector amplitudes should be set and modified using getAmp() and setAmps().\n Direct modification is possible, but should be done extremely carefully, since\n each node only stores a <em>partition</em> of the full state-vector, which itself\n mightn't fit on any single node. Furthermore, an asynchronous MPI process may\n may unexpectedly modify local amplitudes; avoid this with syncQuESTEnv().\n\n The fields relevant to distribution are:\n\n - Qureg.numAmpsPerChunk: the length of Qureg.stateVec (`.real` and `.imag`) on each node.\n - Qureg.chunkId: the id of the node, from <b>0</b> to <b>N-1</b>.\n\n Therefore, this code is valid\n ```\nsyncQuESTEnv(env);\n // set state |i> to have amplitude i\n for (long long int i=0; i<qureg.numAmpsPerChunk; i++)\n     qureg.stateVec.real[i] = i + qureg.chunkId * qureg.numAmpsPerChunk;\n ```\n while the following erroneous code would cause a segmentation fault:\n ```\n // incorrectly attempt to set state |i> to have amplitude i\n for (long long int i=0; i<qureg.numAmpsTotal; i++)\n     qureg.stateVec.real[i] = i;\n ```\n \\n\n\n\n @see\n - createDensityQureg() to create a density matrix of the equivalent number of qubits, which can enter noisy states.\n - createCloneQureg() to create a new qureg of the size and state of an existing qureg.\n - destroyQureg() to free the allocated ::Qureg memory.\n - reportQuregParams() to print information about a ::Qureg.\n - copyStateFromGPU() and copyStateToGPU() for directly modifying state-vectors in GPU mode.\n - syncQuESTEnv() for directly modifying state-vectors in distributed mode.\n\n @ingroup type\n @returns an object representing the set of qubits\n @param[in] numQubits number of qubits in the system\n @param[in] env object representing the execution environment (local, multinode etc)\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if \\p numQubits is so large that the number of amplitudes cannot fit in a long long int type,\n - if in distributed mode, there are more nodes than elements in the would-be state-vector\n @throws exit\n - if in GPU mode, but GPU memory cannot be allocated.\n @author Ania Brown\n @author Tyson Jones (validation, doc)"]
475    pub fn createQureg(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> Qureg;
476}
477extern "C" {
478    #[doc = " Creates a density matrix Qureg object representing a set of qubits which\n can enter noisy and mixed states.\n\n Allocates space for a matrix of complex amplitudes, which assuming a single\n ::qreal floating-point number requires <b>qrealBytes</b>, requires memory\n \\f[\n      \\text{qrealBytes} \\times 2 \\times 2^{2 \\times\\text{numQubits}}\\;\\;\\text{(bytes)},\n \\f]\n though there are additional memory costs in GPU and distributed modes.\n Notice this is the memory cost of a state-vector created with createQureg()\n of twice as many qubits.\n\n The returned ::Qureg begins in the zero state, as produced by initZeroState().\n\n Once created, the following ::Qureg fields are relevant in all backends:\n - Qureg.numQubitsRepresented\n - Qureg.isDensityMatrix\n\n Behind the scenes, density matrice are stored as state-vectors, flattened column-wise.\n As such, individual amplitudes should be fetched with getDensityAmp(), in lieu\n of direct access.\n \\n\n\n > ::QuESTEnv \\p env must be prior created with createQuESTEnv().\n\n ### Serial\n In serial and local (non-distributed) multithreaded modes, a density matrix \\p Qureg\n costs only the memory above. For example, at double precision\n (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:\n \\p numQubits  | memory\n ------------- | -------------\n 10            | 16 MiB\n 12            | 256 MiB\n 14            | 4 GiB\n 16            | 64 GiB\n 18            | 1 TiB\n 20            | 16 TiB\n\n\n ### GPU\n\n In GPU-accelerated mode, an <em>additional</em> density matrix is created in GPU memory.\n Therefore both RAM and VRAM must be of sufficient memory to store the state-vector,\n each of the size indicated in the Serial table above.\n\n > Note that many GPUs do not support quad precision ::qreal.\n\n ### Distributed\n\n In distributed mode, the density matrix is uniformly partitioned between the <b>N</b>\n distributed nodes (column-wise).\n\n > Only a power-of-2 number of nodes <b>N</b> may be used (e.g. <b>N = 1, 2, 4, 8, </b>...).\n > There must additionally be at least 1 amplitude of a density matrix stored on each node.\n > This means one cannot create a density matrix ::Qureg with fewer than \\f$\\log_2(\\text{N})/2\\f$ qubits.\n\n Additional memory is allocated on each node for communication buffers, of size\n equal to the density matrix partition.\n Hence the total memory <em>per-node</em> required is:\n \\f[\n      2 \\times \\text{qrealBytes} \\times 2 \\times 2^{2\\times\\text{numQubits}}/N  \\;\\;\\text{(bytes)},\n \\f]\n\n For example, at double precision\n (#QuEST_PREC <b>= 2</b>, <b>qrealBytes = 8</b>), the memory costs are:\n\n | \\p numQubits | memory per node  |||||\n |-------------|-------|-------|-------|--------| ------ |\n |            | <b>N = 2</b>  | <b>N = 4</b> | <b>N = 8</b> | <b>N = 16</b> | <b>N = 32</b> |\n | 10           | 16 MiB | 8 MiB | 4 MiB | 2 MiB  | 1 MiB  |\n | 15           | 16 GiB | 8 GiB | 4 GiB | 2 GiB  | 1 GiB  |\n | 20           | 16 TiB | 8 TiB | 4 TiB | 2 TiB  | 1 TiB  |\n\n\n @see\n - createQureg() to create a state-vector of the equivalent number of qubits, with a square-root memory cost\n - createCloneQureg() to create a new qureg of the size and state of an existing qureg.\n - destroyQureg() to free the allocated \\p Qureg memory.\n - reportQuregParams() to print information about a ::Qureg.\n\n @ingroup type\n @returns an object representing the set of qubits\n @param[in] numQubits number of qubits in the system\n @param[in] env object representing the execution environment (local, multinode etc)\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if \\p numQubits is so large that the number of amplitudes cannot fit in a long long int type,\n - if in distributed mode, there are more nodes than elements in the would-be state-vector\n @throws exit\n - if in GPU mode, but GPU memory cannot be allocated.\n @author Tyson Jones"]
479    pub fn createDensityQureg(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> Qureg;
480}
481extern "C" {
482    #[doc = " Create a new ::Qureg which is an exact clone of the passed qureg, which can be\n either a state-vector or a density matrix.\n\n The returned \\ref Qureg will have the same\n dimensions as the passed \\p qureg and begin in an identical quantum state.\n This must be destroyed by the user later with destroyQureg().\n\n @see\n - destroyQureg()\n - cloneQureg()\n - createQureg()\n - createDensityQureg()\n\n @ingroup type\n @returns an object representing the set of qubits\n @param[in] qureg an existing \\ref Qureg to be cloned\n @param[in] env the ::QuESTEnv\n @author Tyson Jones"]
483    pub fn createCloneQureg(qureg: Qureg, env: QuESTEnv) -> Qureg;
484}
485extern "C" {
486    #[doc = " Deallocate a ::Qureg, freeing its memory.\n\n This frees all memory bound to \\p qureg, including its state-vector or\n density matrix in RAM, in VRAM (in GPU mode), and communication buffers\n (in distributed mode).\n\n The \\p qureg must have been previously created with createQureg(),\n createDensityQureg() or createCloneQureg().\n\n @see\n - createQureg()\n - createDensityQureg()\n - createCloneQureg()\n\n @ingroup type\n @param[in,out] qureg the ::Qureg to be destroyed\n @param[in] env the ::QuESTEnv\n @author Ania Brown\n @author Tyson Jones (improved doc)"]
487    pub fn destroyQureg(qureg: Qureg, env: QuESTEnv);
488}
489extern "C" {
490    #[doc = " Allocate dynamic memory for a square complex matrix of any size,\n which can be passed to functions like multiQubitUnitary() and applyMatrixN().\n\n The returned matrix will have dimensions\n \\f[\n      2^{\\text{numQubits}} \\times 2^{\\text{numQubits}},\n \\f]\n stored as nested arrays ComplexMatrixN.real and ComplexMatrixN.imag,\n initialised to zero.\n\n > If your matrix will ultimately be diagonal, use createSubDiagonalOp()\n > instead to save quadratic memory and runtime.\n\n Unlike a ::Qureg, the memory of a ::ComplexMatrixN is always stored in RAM,\n and non-distributed. Hence, elements can be directly accessed and modified:\n ```\n int numQubits = 5;\n int dim = (1 << numQubits);\n ComplexMatrixN m = createComplexMatrixN(numQubits);\n\n for (int r=0; r<dim; r++) {\n     for (int c=0; c<dim; c++) {\n         m.real[r][c] = rand();\n         m.imag[r][c] = rand();\n     }\n }\n ```\n \\n\n A ::ComplexMatrixN can be initialised in bulk using initComplexMatrixN(),\n though this is not C++ compatible.\n\n Like ::ComplexMatrix2 and ::ComplexMatrix4 (which are incidentally stored in the stack),\n the returned ::ComplexMatrixN is safe to return from functions.\n\n > The ::ComplexMatrixN must eventually be freed using destroyComplexMatrixN(),\n > since it is created in the dynamic heap. One can instead use getStaticComplexMatrixN()\n > to create a ComplexMatrixN struct in the stack (which doesn't need to be later destroyed),\n > though this may cause a stack overflow if the matrix is too large (approx 10+ qubits).\n\n @see\n - destroyComplexMatrixN()\n - getStaticComplexMatrixN()\n - initComplexMatrixN()\n - applyMatrixN()\n - multiQubitUnitary()\n - mixMultiQubitKrausMap()\n - createSubDiagonalOp()\n\n @ingroup type\n @param[in] numQubits the number of qubits of which the returned ComplexMatrixN will correspond\n @returns a dynamic ComplexMatrixN struct, that is one where the .real and .imag\n  fields are arrays kept in the heap and must be later destroyed.\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if the memory was not allocated successfully\n @author Tyson Jones"]
491    pub fn createComplexMatrixN(numQubits: ::std::os::raw::c_int) -> ComplexMatrixN;
492}
493extern "C" {
494    #[doc = " Destroy a ComplexMatrixN instance created with createComplexMatrixN()\n\n It is invalid to attempt to destroy a matrix created with getStaticComplexMatrixN().\n\n @see\n - getStaticComplexMatrixN()\n - createComplexMatrixN()\n\n @ingroup type\n @param[in] matr the dynamic matrix (created with createComplexMatrixN()) to deallocate\n @throws invalidQuESTInputError()\n - if \\p matr was not yet allocated.\n @throws malloc_error\n -  if \\p matr was static (created with getStaticComplexMatrixN())\n @author Tyson Jones"]
495    pub fn destroyComplexMatrixN(matr: ComplexMatrixN);
496}
497extern "C" {
498    #[doc = " Initialises a ComplexMatrixN instance to have the passed\n \\p real and \\p imag values. This allows succint population of any-sized\n ComplexMatrixN, e.g. through 2D arrays:\n\n     ComplexMatrixN m = createComplexMatrixN(3);\n     initComplexMatrixN(m,\n         (qreal[8][8]) {{1,2,3,4,5,6,7,8}, {0}},\n         (qreal[8][8]) {{0}});\n\n \\p m can be created by either createComplexMatrixN() or getStaticComplexMatrixN().\n\n This function is only callable in C, since C++ signatures cannot\n contain variable-length 2D arrays\n\n @ingroup type\n @param[in] m the matrix to initialise\n @param[in] real matrix of real values; can be 2D array of array of pointers\n @param[in] imag matrix of imaginary values; can be 2D array of array of pointers\n @throws invalidQuESTInputError()\n - if \\p m has not been allocated (e.g. with createComplexMatrixN())\n @author Tyson Jones"]
499    pub fn initComplexMatrixN(m: ComplexMatrixN, real: *mut *mut f64, imag: *mut *mut f64);
500}
501extern "C" {
502    #[doc = " Dynamically allocates a Hamiltonian expressed as a real-weighted sum of products of Pauli operators.\n\n A ::PauliHamil is merely an encapsulation of the multiple parameters of functions\n like applyPauliSum().\n\n The Pauli operators (PauliHamil.pauliCodes) are all initialised to identity\n (::PAULI_I), but the coefficients (PauliHamil.termCoeffs) are not initialised.\n\n The Hamiltonian can be used in functions like applyPauliHamil() and applyTrotterCircuit(),\n with \\p Qureg instances of the same number of qubits.\n\n A ::PauliHamil can be modified directly (see ::PauliHamil), or through initPauliHamil().\n It can furthermore be created and initialised from a file description directly with\n createPauliHamilFromFile().\n\n > The returned dynamic \\p PauliHamil instance must later be freed via destroyPauliHamil().\n\n @see\n - createPauliHamilFromFile()\n - createDiagonalOpFromPauliHamilFile()\n - initPauliHamil()\n - destroyPauliHamil()\n - applyPauliSum()\n - applyTrotterCircuit()\n - calcExpecPauliHamil()\n\n @ingroup type\n @param[in] numQubits the number of qubits on which this Hamiltonian acts\n @param[in] numSumTerms the number of weighted terms in the sum, or the number of Pauli products\n @returns a dynamic \\p PauliHamil struct, with fields \\p pauliCodes and \\p termCoeffs stored in the heap\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if \\p numSumTerms <= 0\n @author Tyson Jones"]
503    pub fn createPauliHamil(
504        numQubits: ::std::os::raw::c_int,
505        numSumTerms: ::std::os::raw::c_int,
506    ) -> PauliHamil;
507}
508extern "C" {
509    #[doc = " Destroy a ::PauliHamil instance, created with either createPauliHamil() or createPauliHamilFromFile().\n\n @ingroup type\n @param[in] hamil a dynamic \\p PauliHamil instantiation\n @author Tyson Jones"]
510    pub fn destroyPauliHamil(hamil: PauliHamil);
511}
512extern "C" {
513    #[doc = " Creates a \\p PauliHamil instance, a real-weighted sum of products of Pauli operators,\n populated with the data in filename \\p fn.\n\n Each line in the plaintext file is interpreted as a separate product of Pauli operators\n in the total sum.\n Each line must be a space-separated list with format\n\n     c p1 p2 p3 ... pN\n\n where \\p c is the real coefficient of the term, and \\p p1 ... \\p pN are\n numbers in <b>{0,1,2,3}</b> to indicate ::PAULI_I, ::PAULI_X, ::PAULI_Y, ::PAULI_Z\n operators respectively, which act on qubits \\p 0 through \\p N-1 (all qubits).\n\n For example, the file containing\n\n     0.31 1 0 1 2\n     -0.2 3 2 0 0\n\n encodes a two-term four-qubit Hamiltonian\n \\f[\n      0.31 \\, X_0 \\, X_2 \\, Y_3 -0.2 \\, Z_0 \\, Y_1 \\,.\n \\f]\n\n The initialised ::PauliHamil can be previewed with reportPauliHamil().\n\n The number of qubits and terms are inferred from the file.\n The created Hamiltonian can be used just like one created via createPauliHamil().\n It can be modified directly (see ::PauliHamil), or through initPauliHamil().\n\n > The returned dynamic \\p PauliHamil instance must later be freed via destroyPauliHamil().\n\n @see\n - reportPauliHamil()\n - destroyPauliHamil()\n - createPauliHamil()\n - initPauliHamil()\n - createDiagonalOpFromPauliHamilFile()\n\n @ingroup type\n @param[in] fn filename of the plaintext file specifying the pauli operators and coefficients\n @returns a dynamic ::PauliHamil struct\n @throws invalidQuESTInputError()\n - if the file with name \\p fn cannot be read\n - if the file is not correctly formatted as described above\n @author Tyson Jones"]
514    pub fn createPauliHamilFromFile(fn_: *mut ::std::os::raw::c_char) -> PauliHamil;
515}
516extern "C" {
517    #[doc = " Initialise ::PauliHamil instance \\p hamil with the given term coefficients and\n Pauli codes (one for every qubit in every term).\n\n Arguments \\p coeffs and \\p codes encode a weighted sum of Pauli operators, with the same\n format as other QuEST functions (like calcExpecPauliSum()).\n\n This is useful to set the elements of the ::PauliHamil in batch. \\n\n For example\n ```\n int numQubits = 3;\n int numTerms = 2;\n PauliHamil hamil = createPauliHamil(numQubits, numTerms);\n\n // hamil = 0.5 X0 Y1 - 0.5 Z1 X3\n initPauliHamil(hamil,\n     (qreal[]) {0.5, -0.5},\n     (enum pauliOpType[]) {PAULI_X,PAULI_Y,PAULI_I, PAULI_I, PAULI_Z, PAULI_X});\n ```\n\n The initialised ::PauliHamil can be previewed with reportPauliHamil().\n\n > \\p hamil must be already created with createPauliHamil(), or createPauliHamilFromFile().\n\n @see\n - reportPauliHamil()\n - createPauliHamil()\n - createPauliHamilFromFile()\n\n @ingroup type\n @param[in, out] hamil an existing ::PauliHamil instance to be modified\n @param[in] coeffs an array of sum term coefficients, which must have length `hamil.numSumTerms`\n @param[in] codes a flat array of Pauli codes, of length `hamil.numSumTerms`*`hamil.numQubits`\n @throws invalidQuESTInputError()\n - if \\p hamil has invalid parameters (\\p numQubits <= 0, \\p numSumTerms <= 0)\n - if any code in \\p codes is not a valid Pauli code (::pauliOpType)\n @author Tyson Jones"]
518    pub fn initPauliHamil(hamil: PauliHamil, coeffs: *mut f64, codes: *mut pauliOpType);
519}
520extern "C" {
521    #[doc = " Creates a ::DiagonalOp representing a diagonal operator on the\n full Hilbert space of a ::Qureg.\n\n The resulting operator need not be unitary nor Hermitian, and can be\n applied to any ::Qureg of a compatible number of qubits.\n\n This function allocates space for \\f$2^{\\text{numQubits}}\\f$ complex amplitudes,\n which are initially zero. This is the same cost as a local state-vector of equal\n number of qubits; see the Serial section of createQureg().\n Note that this is a <em>paralell</em> data-type, so its\n ultimate memory costs depend on the hardware backends, as elaborated below.\n\n The operator elements should be modified with initDiagonalOp() and setDiagonalOpElems(),\n and must be later freed with destroyDiagonalOp().\n\n ### GPU\n\n In GPU-accelerated mode, this function also creates additional equally-sized\n persistent memory on the GPU.\n If you wish to modify the operator elements directly (in lieu of setDiagonalOpElems()),\n you must thereafter call syncDiagonalOp() to update the operator stored in VRAM.\n\n For example,\n ```\n DiagonalOp op = createDiagonalOp(4, env);\n for (long long int i=0; i<op.numElemsPerChunk; i++) {\n     op.real[i] = rand();\n     op.imag[i] = rand();\n }\n syncDiagonalOp(op);\n ```\n\n ### Distribution\n\n In distributed mode, the memory for the diagonal operator is divided evenly\n between the \\f$N\\f$ available nodes, such that each node contains only\n \\f$2^{\\text{numQubits}}/N\\f$ complex values. This is assigned to\n DiagonalOp.numElemsPerChunk.\n\n Users must therefore exercise care in modifying DiagonalOp.real and DiagonalOp.imag\n directly.\n\n For example, the following is valid code when when distributed between <b>N = 2</b> nodes:\n ```\n      // create diag({1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16})\n      int numQubits = 4;\n      DiagonalOp op = createDiagonalOp(numQubits, env);\n      for (int i=0; i<8; i++) {\n          if (env.rank == 0)\n              op.real[i] = (i+1);\n          if (env.rank == 1)\n              op.real[i] = (i+1+8);\n      }\n ```\n \\n\n\n\n @see\n - createDiagonalOpFromPauliHamilFile()\n - setDiagonalOpElems()\n - initDiagonalOp()\n - syncDiagonalOp()\n - applyDiagonalOp()\n - calcExpecDiagonalOp()\n - destroyDiagonalOp()\n\n @ingroup type\n @returns a dynamic DiagonalOp instance initialised to diag(0,0,...).\n @param[in] numQubits number of qubits which inform the Hilbert dimension of the operator.\n @param[in] env the ::QuESTEnv\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if \\p numQubits is so large that the number of elements cannot fit in a long long int type,\n - if in distributed mode, there are more nodes than elements in the operator\n @throws exit\n - if the memory could not be allocated\n @author Tyson Jones"]
522    pub fn createDiagonalOp(numQubits: ::std::os::raw::c_int, env: QuESTEnv) -> DiagonalOp;
523}
524extern "C" {
525    #[doc = " Destroys a ::DiagonalOp created with createDiagonalOp(), freeing its memory.\n\n @see\n - createDiagonalOp()\n\n @ingroup type\n @param[in] op the ::DiagonalOp to destroy\n @param[in] env the ::QuESTEnv\n @throws invalidQuESTInputError()\n - if \\p op was not previously created\n @author Tyson Jones"]
526    pub fn destroyDiagonalOp(op: DiagonalOp, env: QuESTEnv);
527}
528extern "C" {
529    #[doc = " Overwrites the entire ::DiagonalOp \\p op with the given \\p real and \\p imag\n complex elements.\n\n Both \\p real and \\p imag must have length equal to <b>pow(2, </b>`op.numQubits`<b>)</b>.\n\n In GPU mode, this updates both the RAM (\\p op.real and \\p op.imag) <em>and</em>\n persistent GPU memory; there is no need to call syncDiagonalOp() afterward.\n\n In distributed mode, this function assumes \\p real and \\p imag exist fully on every\n node. For ::DiagonalOp which are too large to fit into a single node, use\n setDiagonalOpElems() or syncDiagonalOp().\n\n @see\n - setDiagonalOpElems()\n - initDiagonalOpFromPauliHamil()\n\n @ingroup type\n @param[in,out] op the diagonal operator to modify\n @param[in] real the real components of the full set of new elements\n @param[in] imag the imaginary components of the full set of new elements\n @throws invalidQuESTInputError()\n - if \\p op was not created\n @throws segmentation-fault\n - if either \\p real or \\p imag have length smaller than <b>pow(2, </b>`op.numQubits`<b>)</b>\n @author Tyson Jones"]
530    pub fn initDiagonalOp(op: DiagonalOp, real: *mut f64, imag: *mut f64);
531}
532extern "C" {
533    #[doc = " Populates the diagonal operator \\p op to be equivalent to the given Pauli\n Hamiltonian \\p hamil, assuming \\p hamil contains only `PAULI_Z` operators.\n\n Given a ::PauliHamil \\p hamil featuring only `PAULI_Z` and `PAULI_I`, with\n term coefficients \\f$\\{\\lambda_j\\}\\f$, which\n hence has form\n \\f[\n      \\begin{aligned}\n      \\text{hamil} &= \\sum\\limits_j^{\\text{numSumTerms}} \\lambda_j\n                      \\bigotimes\\limits_{k_j} \\hat{Z}_k \\\\\n      &\\equiv \\begin{pmatrix}\n              r_1 \\\\ & r_2 \\\\ & & r_3 \\\\ & & & \\ddots \\\\ & & & & r_{2^{\\,\\text{numQubits}}}\n          \\end{pmatrix},\n      \\end{aligned}\n \\f]\n this function modifies \\p op to\n \\f[\n      \\text{op} \\; \\rightarrow \\; \\text{diag}\n          \\big( \\; r_1, \\; r_2, \\; r_3, \\; \\dots, \\; r_{2^{\\,\\text{numQubits}}} \\, \\big),\n \\f]\n where the real amplitudes have form\n \\f[\n       r_i = \\sum\\limits_j \\, s_{ij} \\, \\lambda_j, \\;\\;\\;\\; s_{ij} = \\pm  1 \\,.\n \\f]\n This is useful since calculations with ::DiagonalOp are significantly faster than\n the equivalent calculations with a general ::PauliHamil. For example,\n applyDiagonalOp() requires a factor `numSumTerms * numQubits` fewer operations\n than applyPauliHamil().\n\n > In distributed mode, each node will contain only a sub-partition of the full diagonal matrix.\n > In GPU mode, both the CPU and GPU memory copies of \\p op will be updated, so there\n > is no need to call syncDiagonalOp() afterward.\n\n @see\n - createDiagonalOp()\n - createPauliHamil()\n - createDiagonalOpFromPauliHamilFile()\n - initDiagonalOp()\n - setDiagonalOpElems()\n\n @ingroup type\n @param[in,out] op an existing ::DiagonalOp (e.g. created with createDiagonalOp()) to modify\n @param[in] hamil a ::PauliHamil of equal dimension to \\p op, containing only `PAULI_Z` and `PAULI_I` operators\n @throws invalidQuESTInputError()\n - if \\p hamil has invalid parameters (\\p numQubits <= 0, \\p numSumTerms <= 0)\n - if \\p op and \\p hamil have unequal dimensions\n - if \\p hamil contains any operator other than `PAULI_Z` and `PAULI_I`\n @throws segmentation-fault\n - if either \\p op or \\p hamil have not been already created\n @author Tyson Jones\n @author Milos Prokop (serial prototype)"]
534    pub fn initDiagonalOpFromPauliHamil(op: DiagonalOp, hamil: PauliHamil);
535}
536extern "C" {
537    #[doc = " Creates and initialiases a diagonal operator from the Z Pauli Hamiltonian encoded in\n file with filename \\p fn.\n\n This is a convenience function to prepare a diagonal operator from a plaintext\n description of an all-Z Pauli Hamiltonian. The returned ::DiagonalOp is a\n distributed data structure, and significantly faster to use (through functions\n like calcExpecDiagonalOp()) than ::PauliHamil functions (like calcExpecPauliHamil()).\n\n - See createDiagonalOp() for info about the returned operator.\n - See initDiagonalOpFromPauliHamil() for info about the initialised state.\n - See createPauliHamilFromFile() for info about the required file format.\n\n > The returned ::DiagonalOp must be later freed with destroyDiagonalOp().\n > Note a ::PauliHamil from \\p fn is temporarily internally created.\n\n This function is equivalent to\n ```\n // produce diagonal matrix d\n PauliHamil h = createPauliHamilFromFile(fn);\n DiagonalOp d = createDiagonalOp(h.numQubits, env);\n initDiagonalOpFromPauliHamil(d, h);\n destroyPauliHamil(h);\n ```\n <br>\n\n @see\n - initDiagonalOpFromPauliHamil()\n - createPauliHamilFromFile()\n - createDiagonalOp()\n - destroyDiagonalOp()\n\n @ingroup type\n @param[in] fn filename of a plaintext file encoding an all-Z Pauli Hamiltonian\n @param[in] env the session ::QuESTEnv\n @returns a created ::DiagonalOp equivalent to the Hamiltonian in \\p fn\n @throws invalidQuESTInputError()\n - if file \\p fn cannot be read\n - if file \\p fn does not encode a valid ::PauliHamil\n - if the encoded ::PauliHamil consists of operators other than `PAULI_Z` and `PAULI_I`\n @author Tyson Jones\n @author Milos Prokop (serial prototype)"]
538    pub fn createDiagonalOpFromPauliHamilFile(
539        fn_: *mut ::std::os::raw::c_char,
540        env: QuESTEnv,
541    ) -> DiagonalOp;
542}
543extern "C" {
544    #[doc = " Modifies a subset (starting at index \\p startInd, and ending at index\n \\p startInd <b>+</b> \\p numElems) of the elements in ::DiagonalOp \\p op\n with the given complex numbers (passed as \\p real and \\p imag components).\n\n In GPU mode, this updates both the RAM (\\p op.real and \\p op.imag), and the\n persistent GPU memory.\n\n In distributed mode, this function assumes the subset \\p real and \\p imag exist\n (at least) on the node containing the ultimately updated elements.\\n\n For example, below is the correct way to modify the full 8 elements of \\p op\n when split between 2 nodes.\n ```\n     DiagonalOp op = createDiagonalOp(3, env);\n\n     int numElems = 4;\n     qreal re[] = {1,2,3,4};\n     qreal im[] = {1,2,3,4};\n     setDiagonalOpElems(op, 0, re, im, numElems);\n\n     // modify re and im to the next set of elements\n     for (int i=0; i<4; i++) {\n       re[i] += 4;\n       im[i] += 4;\n     }\n     setDiagonalOpElems(op, 4, re, im, numElems);\n ```\n\n In this way, one can avoid a single node containing all new elements which might\n not fit. If more elements are passed than exist on an individual node, each\n node merely ignores the additional elements.\n\n @ingroup type\n @param[in,out] op the ::DiagonalOp to modify\n @param[in] startInd the starting index (globally) of the subset of elements to modify\n @param[in] real  the real components of the new elements\n @param[in] imag  the imaginary components of the new elements\n @param[in] numElems the number of new elements (the length of \\p real and \\p imag)\n @throws invalidQuESTInputError()\n - if \\p op was not created\n - if \\p startInd is an invalid index (<0 or >=<b>pow(2,</b>`op.numQubits`<b>)</b>)\n - if \\p numElems is an invalid number of elements (<=0 or ><b>pow(2,</b>`op.numQubits`<b>)</b>)\n - if there are fewer than \\p numElems elements in \\p op after \\p startInd\n @throws segmentation-fault\n - if either \\p real or \\p imag have fewer elements than \\p numElems\n @author Tyson Jones"]
545    pub fn setDiagonalOpElems(
546        op: DiagonalOp,
547        startInd: ::std::os::raw::c_longlong,
548        real: *mut f64,
549        imag: *mut f64,
550        numElems: ::std::os::raw::c_longlong,
551    );
552}
553extern "C" {
554    #[doc = " Apply a diagonal operator, which is possibly non-unitary and non-Hermitian,\n to the entire \\p qureg.\n\n Let \\f$d_j = \\text{op.real}[j] + (\\text{op.imag}[j])\\,\\text{i} \\f$, and\n \\f[\n  \\hat{D} = \\begin{pmatrix}\n  d_0 \\\\\n  & d_1 \\\\\n  & & \\ddots \\\\\n  & & & d_{2^{\\text{op.numQubits}}-1}\n  \\end{pmatrix}.\n \\f]\n If \\p qureg is a state-vector \\f$|\\psi\\rangle\\f$, this function performs\n  \\f$|\\psi\\rangle \\rightarrow \\hat{D} \\, |\\psi\\rangle\\f$. \\n\n If \\p qureg is a density-matrix \\f$\\rho\\f$, this function performs\n  \\f$\\rho \\rightarrow \\hat{D}\\, \\rho\\f$. Notice this has not applied \\f$\\hat{D}\\f$\n in the fashion of a unitary.\n\n > If your operator is unitary with unit amplitudes, the phases of which can be\n > described by an analytic expression, you should instead use applyPhaseFunc()\n > or applyNamedPhaseFunc() for significant memory and runtime savings.\n\n > To apply a diagonal operator upon a specific subset of qubits, use applySubDiagonalOp()\n\n @see\n - createDiagonalOp()\n - calcExpecDiagonalOp()\n - applyPhaseFunc()\n - applyNamedPhaseFunc()\n - applySubDiagonalOp()\n\n @ingroup operator\n @param[in,out] qureg the state to operate the diagonal operator upon\n @param[in] op the diagonal operator to apply\n @throws invalidQuESTInputError()\n - if \\p op was not created\n - if \\p op acts on a different number of qubits than \\p qureg represents\n @author Tyson Jones"]
555    pub fn applyDiagonalOp(qureg: Qureg, op: DiagonalOp);
556}
557extern "C" {
558    #[doc = " Computes the expected value of the diagonal operator \\p op for state \\p qureg.\n Since \\p op is not necessarily Hermitian, the expected value may be a complex\n number.\n\n Let \\f$ D \\f$ be the diagonal operator \\p op, with diagonal elements \\f$ d_i \\f$.\n Then if \\p qureg is a state-vector \\f$|\\psi\\rangle \\f$, this function computes\n \\f[\n\\langle \\psi | D | \\psi \\rangle = \\sum_i |\\psi_i|^2 \\, d_i\n \\f]\n If \\p qureg is a density matrix \\f$ \\rho \\f$, this function computes\n \\f[\n\\text{Trace}( D \\rho ) = \\sum_i \\rho_{ii} \\, d_i\n \\f]\n\n @see\n - createDiagonalOp()\n - applyDiagonalOp()\n - calcExpecPauliSum()\n - calcExpecPauliProd()\n - calcExpecPauliHamil()\n\n @ingroup calc\n @param[in] qureg a state-vector or density matrix\n @param[in] op    the diagonal operator to compute the expected value of\n @return the expected vaulue of the operator\n @throws invalidQuESTInputError()\n - if \\p op was not created\n - if \\p op acts on a different number of qubits than \\p qureg represents\n @author Tyson Jones"]
559    pub fn calcExpecDiagonalOp(qureg: Qureg, op: DiagonalOp) -> Complex;
560}
561extern "C" {
562    #[doc = " Creates a ::SubDiagonalOp representing a diagonal operator which can act upon\n a subset of the qubits in a ::Qureg. This is similar to a ::DiagonalOp acting\n upon specific qubits.\n\n The resulting operator (initially all zero) need not be unitary nor Hermitian,\n and can be applied to any ::Qureg of a compatible number of qubits.\n\n > This function allocates space for \\f$2^{\\text{numQubits}}\\f$ complex amplitudes,\n > which are initially zero. This is the same cost as a local state-vector of equal\n > number of qubits; see the Serial section of createQureg().\n > Unlike ::DiagonalOp, this object is <em>not</em> distributed; instead, all\n > nodes (during distributed simulation) store the full set of diagonal elements,\n > similar to a ::ComplexMatrixN.\n\n\n The returned ::SubDiagonalOp must be later freed with destroySubDiagonalOp().\n\n For example, the below code creates an 8x8 identity operator.\n ```\n      SubDiagonalOp op = createSubDiagonalOp(3);\n      for (int i=0; i<op.numElems; i++)\n           op.real[i] = 1;\n ```\n \\n\n\n\n @see\n - diagonalUnitary() to apply the created ::SubDiagonalOp upon a subset of qubits of a ::Qureg\n - applyGateSubDiagonalOp() to relax the numerical unitarity requirement of diagonalUnitary()\n - applySubDiagonalOp() to apply the SubDiagonalOp through left-multiplication only\n   (as a non-unitary) upon a density matrix\n - destroySubDiagonalOp()\n - createDiagonalOp()\n\n @ingroup type\n @returns a SubDiagonalOp instance initialised to diag(0,0,...).\n @param[in] numQubits number of qubits which inform the Hilbert dimension of the returned ::SubDiagonalOp.\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if \\p numQubits is so large that the number of elements cannot fit in a long long int type,\n @throws exit\n - if the memory could not be allocated\n @author Tyson Jones"]
563    pub fn createSubDiagonalOp(numQubits: ::std::os::raw::c_int) -> SubDiagonalOp;
564}
565extern "C" {
566    #[doc = " Destroy a ::SubDiagonalOp instance created with createSubDiagonalOp().\n\n @see\n - createSubDiagonalOp()\n\n @ingroup type\n @param[in] op ::SubDiagonalOp to destroy\n @throws malloc_error\n -  if \\p op was not prior created\n @author Tyson Jones"]
567    pub fn destroySubDiagonalOp(op: SubDiagonalOp);
568}
569extern "C" {
570    #[doc = " Apply a many-qubit unitary specified as a diagonal matrix upon a specific\n set of qubits of a quantum register.\n\n This is identical to function diagonalUnitary(), except here unitarity is not\n numerically checked nor enforced. That is, \\p op is mathematically treated as if\n it were unitary despite its true unitarity. This is useful for numerically relaxing\n the precision of unitarity.\n\n > To apply the operator as if it were e.g. Hermitian, use applySubDiagonalOp().\n\n @see\n - createSubDiagonalOp()\n - diagonalUnitary()\n - applySubDiagonalOp()\n - applyDiagonalOp()\n\n @ingroup operator\n @param[in,out] qureg the ::Qureg instance to operate upon\n @param[in] targets the list of target qubit indices\n @param[in] numTargets the length of list \\p targets, which must match the dimension of \\p op\n @param[in] op a ::SubDiagonalOp initialised to any complex values\n @throws invalidQuESTInputError()\n - if \\p numTargets does not match the size of \\p op\n - if \\p numTargets is invalid (<0 or larger than \\p qureg)\n - if \\p numTargets contains an invalid qubit index, or a repetition\n @author Tyson Jones"]
571    pub fn applyGateSubDiagonalOp(
572        qureg: Qureg,
573        targets: *mut ::std::os::raw::c_int,
574        numTargets: ::std::os::raw::c_int,
575        op: SubDiagonalOp,
576    );
577}
578extern "C" {
579    #[doc = " Left-apply a many-qubit a diagonal matrix upon a specific set of qubits of a quantum register.\n\n This is similar to applyGateSubDiagonalOp(), except that here, the operator \\p op\n is only <em>left</em> multiplied onto density matrices.\n\n Let \\f$\\hat{D}\\f$ denote the operator \\p op. Precisely, this function effects\n \\f[\n      |\\psi\\rangle \\rightarrow \\hat{D}_{\\text{targets}} |\\psi\\rangle\n \\f]\n upon state-vectors \\f$|\\psi\\rangle\\f$, and\n \\f[\n      \\rho \\rightarrow \\hat{D}_{\\text{targets}} \\; \\rho\n \\f]\n upon density matrices \\f$\\rho\\f$, imposing no numerical conditions (like unitarity) upon \\p op.\n\n > To apply \\p op as if it were unitary, use applyGateSubDiagonalOp() (or use\n > diagonalUnitary() to explicitly check/enforce unitarity).\n\n > To apply a full-Hilbert diagonal operator which must ergo itself be distributed,\n > use applyDiagonalOp()\n\n @see\n - createSubDiagonalOp()\n - applyGateSubDiagonalOp()\n - diagonalUnitary()\n - applyDiagonalOp()\n\n @ingroup operator\n @param[in,out] qureg the ::Qureg instance to operate upon\n @param[in] targets the list of target qubit indices\n @param[in] numTargets the length of list \\p targets, which must match the dimension of \\p op\n @param[in] op a ::SubDiagonalOp with any complex elements\n @throws invalidQuESTInputError()\n - if \\p numTargets does not match the size of \\p op\n - if \\p numTargets is invalid (<0 or larger than \\p qureg)\n - if \\p numTargets contains an invalid qubit index, or a repetition\n @author Tyson Jones"]
580    pub fn applySubDiagonalOp(
581        qureg: Qureg,
582        targets: *mut ::std::os::raw::c_int,
583        numTargets: ::std::os::raw::c_int,
584        op: SubDiagonalOp,
585    );
586}
587extern "C" {
588    #[doc = " Print the current state vector of probability amplitudes for a set of qubits to file.\n File format:\n @verbatim\nreal, imag\nrealComponent1, imagComponent1\nrealComponent2, imagComponent2\n...\nrealComponentN, imagComponentN\n@endverbatim\n\n File naming convention:\n\n For each node that the program runs on, a file 'state_rank_[node_rank].csv' is generated. If there is\n more than one node, ranks after the first do not include the header\n @verbatim\nreal, imag\n@endverbatim\n so that files are easier to combine.\n\n @ingroup debug\n @param[in,out] qureg object representing the set of qubits\n @author Ania Brown"]
589    pub fn reportState(qureg: Qureg);
590}
591extern "C" {
592    #[doc = " Print the current state vector of probability amplitudes for a set of qubits to standard out.\n For debugging purposes. Each rank should print output serially.\n Only print output for systems <= 5 qubits\n\n @ingroup debug\n @author Ania Brown"]
593    pub fn reportStateToScreen(qureg: Qureg, env: QuESTEnv, reportRank: ::std::os::raw::c_int);
594}
595extern "C" {
596    #[doc = " Report metainformation about a set of qubits: number of qubits, number of probability amplitudes.\n\n @ingroup debug\n @param[in] qureg object representing the set of qubits\n @author Ania Brown"]
597    pub fn reportQuregParams(qureg: Qureg);
598}
599extern "C" {
600    #[doc = " Print the \\p PauliHamil to screen.\n The output features a new line for each term, each with format\n\n     c p1 p2 p3 ... pN\n\n where \\p c is the real coefficient of the term, and \\p p1 ... \\p pN are\n numbers \\p 0, \\p 1, \\p 2, \\p 3 to indicate identity, pauliX, pauliY and pauliZ\n operators respectively, acting on qubits \\p 0 through \\p N-1 (all qubits).\n A tab character separates c and p1, but single spaces separate the Pauli operators.\n\n @see\n - createPauliHamil()\n - initPauliHamil()\n - createPauliHamilFromFile()\n\n @ingroup debug\n @param[in] hamil an instantiated PauliHamil\n @throws invalidQuESTInputError if the parameters of \\p hamil are invalid, i.e.\n      if \\p numQubits <= 0, or if \\p numSumTerms <= 0, or if \\p pauliCodes\n      contains an invalid Pauli code.\n @author Tyson Jones"]
601    pub fn reportPauliHamil(hamil: PauliHamil);
602}
603extern "C" {
604    #[doc = " Returns the number of qubits represented by \\p qureg.\n\n @see\n - getNumAmps()\n\n @ingroup calc\n @param[in] qureg a state-vecor or density matrix\n @return `qureg.numQubitsRepresented`\n @author Tyson Jones"]
605    pub fn getNumQubits(qureg: Qureg) -> ::std::os::raw::c_int;
606}
607extern "C" {
608    #[doc = " Returns the number of complex amplitudes in a state-vector \\p qureg.\n\n In distributed mode, this returns the total number of amplitudes in the full\n representation of \\p qureg, and so may be larger than the number stored on\n each node. For the latter, refer to Qureg.numAmpsPerChunk.\n\n @see\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg a state-vecotor\n @return the total number of complex amplitudes representing \\p qureg.\n @throws invalidQuESTInputError()\n - if \\p qureg is a density matrix\n @author Tyson Jones"]
609    pub fn getNumAmps(qureg: Qureg) -> ::std::os::raw::c_longlong;
610}
611extern "C" {
612    #[doc = " Initialises a qureg to have all-zero-amplitudes. This is an unphysical state\n useful for iteratively building a state with functions like setWeightedQureg(),\n and should not be confused with initZeroState().\n\n @ingroup init\n @param[in,out] qureg a ::Qureg of which to clear all amplitudes\n @author Tyson Jones"]
613    pub fn initBlankState(qureg: Qureg);
614}
615extern "C" {
616    #[doc = " Initialise \\p qureg into the zero state.\n\n If \\p qureg is a state-vector of \\f$N\\f$ qubits, it is modified to state\n \\f$ {| 0 \\rangle}^{\\otimes N} \\f$. \\n\n If \\p qureg is a density matrix of \\f$ N \\f$ qubits, it is modified to state\n \\f$ {| 0 \\rangle\\langle 0 |}^{\\otimes N} \\f$\n\n @ingroup init\n @param[in,out] qureg the object representing the set of all qubits to initialise\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
617    pub fn initZeroState(qureg: Qureg);
618}
619extern "C" {
620    #[doc = " Initialise \\p qureg into the plus state.\n\n If \\p qureg is a state-vector of \\f$N\\f$ qubits, it is modified to state\n \\f[\n   {| + \\rangle}^{\\otimes N} = \\frac{1}{\\sqrt{2^N}} (| 0 \\rangle + | 1 \\rangle)^{\\otimes N}\\,.\n \\f]\n If \\p qureg is a density matrix of \\f$N\\f$ qubits, it is modified to state\n \\f[\n   {| + \\rangle\\langle+|}^{\\otimes N} = \\frac{1}{{2^N}} \\sum_i\\sum_j |i\\rangle\\langle j|\\,.\n \\f]\n\n\n @ingroup init\n @param[in,out] qureg the object representing the set of qubits to be initialised\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
621    pub fn initPlusState(qureg: Qureg);
622}
623extern "C" {
624    #[doc = " Initialise \\p qureg into the classical state (also known as a\n \"computational basis state\") with index \\p stateInd.\n\n If \\p qureg is a state-vector, it will become\n      \\f$ | \\text{stateInd} \\rangle \\f$. \\n\n If \\p qureg is a density matrix, it will become\n      \\f$ | \\text{stateInd} \\rangle \\langle \\text{stateInd} | \\f$.\n\n Classical states are indexed from zero, so that \\p stateInd <b>= 0</b> produces\n \\f$ | 00 \\dots 00 \\rangle \\f$,\n and  \\p stateInd <b>= 1</b> produces \\f$ | 00 \\dots 01 \\rangle \\f$, and\n \\p stateInd <b>=</b> \\f$ 2^N - 1 \\f$ produces\n \\f$ | 11 \\dots 11 \\rangle \\f$.\n\n Subsequent calls to getProbAmp() will yield 0 for all indices except \\p stateInd,\n and the phase of \\p stateInd's amplitude will be 1 (real).\n\n This function can be used to initialise \\p qureg into a specific binary state\n (e.g. \\p 11001) using a binary literal (supported by only some compilers):\n ```\n      initClassicalState(qureg, 0b11001);\n ```\n \\n\n\n\n @see\n - initPureState()\n\n @ingroup init\n @param[in,out] qureg the ::Qureg to modify\n @param[in] stateInd the index of the basis state to modify \\p qureg into\n @throws invalidQuESTInputError()\n - if \\p stateInd is outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n @author Tyson Jones"]
625    pub fn initClassicalState(qureg: Qureg, stateInd: ::std::os::raw::c_longlong);
626}
627extern "C" {
628    #[doc = " Initialise \\p qureg into to a given pure state of an equivalent Hilbert dimension.\n\n If \\p qureg is a state-vector, this merely clones \\p pure into \\p qureg. \\n\n If \\p qureg is a density matrix, this makes \\p qureg 100% likely to be in the \\p pure state.\n\n ::Qureg \\p pure is not modified.\n\n @see\n - initClassicalState()\n\n @ingroup init\n @param[in,out] qureg the ::Qureg to modify\n @param[in] pure a state-vector containing the pure state into which to initialise \\p qureg\n @throws invalidQuESTInputError()\n - if \\p qureg and \\p pure have mismatching dimensions\n - if \\p pure is a density matrix\n @author Tyson Jones"]
629    pub fn initPureState(qureg: Qureg, pure_: Qureg);
630}
631extern "C" {
632    #[doc = " Initialises \\p qureg to be in the un-normalised, non-physical state with\n with \\f$n\\f$-th complex amplitude given by \\f$2n/10 + i(2n+1)/10\\f$.\n\n This is used internally for debugging and testing.\n\n @ingroup debug\n @param[in,out] qureg the register to have its amplitudes overwritten\n @author Ania Brown\n @author Tyson Jones (doc)"]
633    pub fn initDebugState(qureg: Qureg);
634}
635extern "C" {
636    #[doc = " Initialise \\p qureg by specifying all amplitudes.\n For density matrices, it is assumed the amplitudes have been flattened\n column-wise into the given arrays.\n\n The real and imaginary components of the amplitudes are passed in separate arrays,\n \\p reals and \\p imags,\n each of which must have length `qureg.numAmpsTotal`.\n There is no automatic checking that the passed arrays are L2 normalised, so this\n can be used to prepare \\p qureg in a non-physical state.\n\n In distributed mode, this would require the complete state to fit in\n every node. To manually prepare a state for which all amplitudes cannot fit into a single node,\n use setAmps()\n\n @see\n - setAmps()\n\n @ingroup init\n @param[in,out] qureg the ::Qureg to overwrite\n @param[in] reals array of the real components of the new amplitudes\n @param[in] imags array of the imaginary components of the new amplitudes\n @throws segmentation-fault\n - if either \\p reals or \\p imags have fewer than `qureg.numAmpsTotal` elements\n @author Tyson Jones"]
637    pub fn initStateFromAmps(qureg: Qureg, reals: *mut f64, imags: *mut f64);
638}
639extern "C" {
640    #[doc = " Overwrites a contiguous subset of the amplitudes in state-vector \\p qureg,\n with those passed in \\p reals and \\p imags.\n\n Only amplitudes with indices in <b>[</b>\\p startInd<b>,</b> \\p startInd <b>+</b> \\p numAmps<b>]</b>\n will be changed. The resulting \\p qureg may not necessarily be in an L2 normalised state.\n\n In distributed mode, this function assumes the subset \\p reals and \\p imags exist\n (at least) on the node containing the ultimately updated elements.\\n\n For example, below is the correct way to modify the full 8 elements of \\p qureg\n when split between 2 nodes.\n ```\n     Qureg qureg = createQureg(3, env);\n\n     long long int numAmps = 4;\n     qreal re[] = {1,2,3,4};\n     qreal im[] = {1,2,3,4};\n     setAmps(qureg, 0, re, im, numAmps);\n\n     // modify re and im to the next set of elements\n     for (int i=0; i<4; i++) {\n       re[i] += 4;\n       im[i] += 4;\n     }\n     setAmps(qureg, 4, re, im, numAmps);\n ```\n \\n\n\n\n @see\n - setDensityAmps()\n - setWeightedQureg()\n - initStateFromAmps()\n - initBlankState()\n\n @ingroup init\n @param[in,out] qureg the state-vector to modify\n @param[in] startInd the index of the first amplitude in \\p qureg to modify\n @param[in] reals array of the real components of the new amplitudes\n @param[in] imags array of the imaginary components of the new amplitudes\n @param[in] numAmps the length of each of the reals and imags arrays.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a state-vector (i.e. is a density matrix)\n - if \\p startInd is outside [0, `qureg.numAmpsTotal`]\n - if \\p numAmps is outside [0, `qureg.numAmpsTotal`]\n - if \\p numAmps + \\p startInd >= `qureg.numAmpsTotal`\n @author Tyson Jones"]
641    pub fn setAmps(
642        qureg: Qureg,
643        startInd: ::std::os::raw::c_longlong,
644        reals: *mut f64,
645        imags: *mut f64,
646        numAmps: ::std::os::raw::c_longlong,
647    );
648}
649extern "C" {
650    #[doc = " Overwrites a contiguous subset of the amplitudes in density-matrix \\p qureg,\n with those passed in \\p reals and \\p imags, intrepreted column-wise.\n\n Only the first \\p numAmp amplitudes starting from row-column index (\\p startRow, \\p startCol), and\n proceeding down the column (wrapping around between rows) will be modified.\n The resulting \\p qureg may not necessarily be a valid density matrix normalisation.\n\n In distributed mode, this function assumes the subset \\p reals and \\p imags exist\n (at least) on the node(s) containing the ultimately updated elements.\\n\n\n\n @see\n - setAmps()\n - initStateFromAmps()\n\n @ingroup init\n @param[in,out] qureg the density-matrix to modify\n @param[in] startRow the row-index of the first amplitude in \\p qureg to modify\n @param[in] startCol the column-index of the first amplitude in \\p qureg to modify\n @param[in] reals array of the real components of the new amplitudes\n @param[in] imags array of the imaginary components of the new amplitudes\n @param[in] numAmps the length of each of the reals and imags arrays\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix (i.e. is a state-vector)\n - if \\p startRow is outside [0, `1 << qureg.numQubitsRepresented`]\n - if \\p startCol is outside [0, `1 << qureg.numQubitsRepresented`]\n - if \\p numAmps is outside [0, `qureg.numAmpsTotal`]\n - if \\p numAmps is larger than the remaining number of amplitudes from (`startRow`, `startCol`), column-wise\n @author Tyson Jones"]
651    pub fn setDensityAmps(
652        qureg: Qureg,
653        startRow: ::std::os::raw::c_longlong,
654        startCol: ::std::os::raw::c_longlong,
655        reals: *mut f64,
656        imags: *mut f64,
657        numAmps: ::std::os::raw::c_longlong,
658    );
659}
660extern "C" {
661    #[doc = " Overwrites the density-matrix \\p qureg with the Z-basis matrix representation\n of the given real-weighted sum of Pauli tensors \\p hamil.\n\n This leaves \\p qureg in a non-physical state - as a matrix form of \\p hamil -\n and is useful for establishing a persistent-backend dense representation of\n the Hamiltonian. For example, \\p qureg can be subsequently passed to functions\n like calcDensityInnerProduct() which would effectively in-place compute\n calcExpecPauliHamil().\n\n @see\n - createPauliHamil()\n - createDensityQureg()\n - calcDensityInnerProduct()\n\n @ingroup init\n @param[in,out] qureg the density-matrix to overwrite\n @param[in] hamil the ::PauliHamil to expand into a matrix representation\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix (i.e. is a state-vector)\n - if the dimensions of \\p qureg and \\p hamil do not match\n - if \\p hamil is an invalid ::PauliHamil\n @author Tyson Jones"]
662    pub fn setQuregToPauliHamil(qureg: Qureg, hamil: PauliHamil);
663}
664extern "C" {
665    #[doc = " Overwrite the amplitudes of \\p targetQureg with those from \\p copyQureg.\n\n Registers must either both be state-vectors, or both be density matrices, and\n of equal dimensions.\n Only the quantum state is cloned, while auxilary info (like recorded QASM) is unchanged.\n copyQureg is unaffected.\n\n @see\n - createCloneQureg()\n - initPureState()\n - setWeightedQureg()\n\n @ingroup init\n @param[in, out] targetQureg the qureg to have its quantum state overwritten\n @param[in] copyQureg the qureg to have its quantum state cloned into targetQureg.\n @throws invalidQuESTInputError()\n - if \\p targetQureg is a state-vector while \\p copyQureg is a density matrix (and vice versa)\n - if \\p targetQureg and \\p copyQureg have different dimensions\n @author Tyson Jones"]
666    pub fn cloneQureg(targetQureg: Qureg, copyQureg: Qureg);
667}
668extern "C" {
669    #[doc = " Shift the phase between \\f$ |0\\rangle \\f$ and \\f$ |1\\rangle \\f$ of a single qubit by a given angle.\n\n > This is equivalent to a Z-axis rotation of the Bloch-sphere up to a global phase factor.\n For angle \\f$\\theta\\f$, this effects single-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 & 0 \\\\\n 0 & \\exp(i \\theta)\n \\end{pmatrix}\n \\f]\n with circuit diagram\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-4, 0) {targetQubit};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_\\theta$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - controlledPhaseShift()\n - multiControlledPhaseShift()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to undergo a phase shift\n @param[in] angle amount by which to shift the phase in radians\n @throws invalidQuESTInputError()\n - \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented).\n @author Tyson Jones"]
670    pub fn phaseShift(qureg: Qureg, targetQubit: ::std::os::raw::c_int, angle: f64);
671}
672extern "C" {
673    #[doc = " Introduce a phase factor \\f$ \\exp(i \\theta) \\f$ on state \\f$ |11\\rangle \\f$ of qubits\n \\p idQubit1 and \\p idQubit2.\n For angle \\f$\\theta\\f$, this effects the unitary\n \\f[\n \\begin{pmatrix}\n 1 & & & \\\\\n & 1 & & \\\\\n & & 1 & \\\\\n & & & \\exp(i \\theta)\n \\end{pmatrix}\n \\f]\n on \\p idQubit1 and \\p idQubit2.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {qubit1};\n\\node[draw=none] at (-3.5, 0) {qubit2};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_\\theta$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - phaseShift()\n - multiControlledPhaseShift()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] idQubit1 first qubit in the state to phase shift\n @param[in] idQubit2 second qubit in the state to phase shift\n @param[in] angle amount by which to shift the phase in radians\n @throws invalidQuESTInputError()\n - if \\p idQubit1 or \\p idQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p idQubit1 and \\p idQubit2 are equal\n @author Tyson Jones"]
674    pub fn controlledPhaseShift(
675        qureg: Qureg,
676        idQubit1: ::std::os::raw::c_int,
677        idQubit2: ::std::os::raw::c_int,
678        angle: f64,
679    );
680}
681extern "C" {
682    #[doc = " Introduce a phase factor \\f$ \\exp(i \\theta) \\f$ on state \\f$ |1 \\dots 1 \\rangle \\f$\n of the passed qubits.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {controls};\n\\node[draw=none] at (1, .7) {$\\theta$};\n\n\\node[draw=none] at (0, 6) {$\\vdots$};\n\\draw (0, 5) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw (0, 4) -- (0, 2);\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 0);\n\n\\draw (-2,0) -- (2, 0);\n\\draw[fill=black] (0, 0) circle (.2);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - phaseShift()\n - controlledPhaseShift()\n - controlledPhaseFlip()\n - multiControlledPhaseFlip()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits array of qubits to phase shift\n @param[in] numControlQubits the length of array \\p controlQubits\n @param[in] angle amount by which to shift the phase in radians\n @throws invalidQuESTInputError()\n - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented])\n - if any qubit index in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented])\n - if the qubits in \\p controlQubits are not unique\n @author Tyson Jones"]
683    pub fn multiControlledPhaseShift(
684        qureg: Qureg,
685        controlQubits: *mut ::std::os::raw::c_int,
686        numControlQubits: ::std::os::raw::c_int,
687        angle: f64,
688    );
689}
690extern "C" {
691    #[doc = " Apply the (two-qubit) controlled phase flip gate, also known as the controlled pauliZ gate.\n For each state, if both input qubits have value one, multiply the amplitude of that state by -1. This applies the two-qubit unitary:\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & 1 \\\\\n & & & -1\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {idQubit1};\n\\node[draw=none] at (-3.5, 0) {idQubit2};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 0);\n\n\\draw (-2,0) -- (2, 0);\n\\draw[fill=black] (0, 0) circle (.2);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - pauliZ()\n - phaseShift()\n - multiControlledPhaseFlip()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] idQubit1, idQubit2 qubits to operate upon\n @throws invalidQuESTInputError()\n - if \\p idQubit1 or \\p idQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p idQubit1 and \\p idQubit2 are equal\n @author Tyson Jones"]
692    pub fn controlledPhaseFlip(
693        qureg: Qureg,
694        idQubit1: ::std::os::raw::c_int,
695        idQubit2: ::std::os::raw::c_int,
696    );
697}
698extern "C" {
699    #[doc = " Apply the multiple-qubit controlled phase flip gate, also known as the multiple-qubit controlled pauliZ gate.\n For each state, if all control qubits have value one, multiply the amplitude of that state by -1. This applies the many-qubit unitary:\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & 1 \\\\\n & & & & -1\n \\end{pmatrix}\n \\f]\n on the control qubits.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {controls};\n\n\\node[draw=none] at (0, 6) {$\\vdots$};\n\\draw (0, 5) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw (0, 4) -- (0, 2);\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 0);\n\n\\draw (-2,0) -- (2, 0);\n\\draw[fill=black] (0, 0) circle (.2);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits array of input qubits\n @param[in] numControlQubits number of input qubits\n @throws invalidQuESTInputError()\n - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented)\n - if any qubit in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented)\n - if any qubit in \\p qubits is repeated\n @author Tyson Jones"]
700    pub fn multiControlledPhaseFlip(
701        qureg: Qureg,
702        controlQubits: *mut ::std::os::raw::c_int,
703        numControlQubits: ::std::os::raw::c_int,
704    );
705}
706extern "C" {
707    #[doc = " Apply the single-qubit S gate.\n This is a rotation of \\f$\\pi/2\\f$ around the Z-axis on the Bloch sphere, or the unitary:\n \\f[\n \\begin{pmatrix}\n 1 & 0 \\\\\n 0 & i\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {S};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - tGate()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate upon\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
708    pub fn sGate(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
709}
710extern "C" {
711    #[doc = " Apply the single-qubit T gate.\n This is a rotation of \\f$\\pi/4\\f$ around the Z-axis on the Bloch sphere, or the unitary:\n \\f[\n \\begin{pmatrix}\n 1 & 0 \\\\\n 0 & \\exp\\left(i \\frac{\\pi}{4}\\right)\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {T};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - sGate()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate upon\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
712    pub fn tGate(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
713}
714extern "C" {
715    #[doc = " Create the QuEST execution environment.\n This should be called only once, and the environment should be freed with destroyQuESTEnv at the end\n of the user's code.\n If something needs to be done to set up the execution environment, such as\n initializing MPI when running in distributed mode, it is handled here.\n\n @see\n - reportQuESTEnv()\n - destroyQuESTEnv()\n - syncQuESTEnv()\n\n @ingroup type\n @return object representing the execution environment. A single instance is used for each program\n @author Ania Brown"]
716    pub fn createQuESTEnv() -> QuESTEnv;
717}
718extern "C" {
719    #[doc = " Destroy the QuEST environment.\n If something needs to be done to clean up the execution environment, such as\n finalizing MPI when running in distributed mode, it is handled here\n\n @see\n - createQuESTEnv()\n\n @ingroup type\n @param[in] env object representing the execution environment. A single instance is used for each program\n @author Ania Brown"]
720    pub fn destroyQuESTEnv(env: QuESTEnv);
721}
722extern "C" {
723    #[doc = " Report information about the QuEST environment\n\n @ingroup debug\n @param[in] env object representing the execution environment. A single instance is used for each program\n @author Ania Brown"]
724    pub fn reportQuESTEnv(env: QuESTEnv);
725}
726extern "C" {
727    #[doc = " Sets \\p str to a string containing information about the runtime environment,\n including whether simulation is using CUDA (for GPU), OpenMP (for multithreading)\n and/or MPI (for distribution). The number of CPU threads and distributed ranks is\n also reported. Note there is currently no reporting of the number of GPU cores used.\n\n The string format is:\n ```\n \"CUDA=b OpenMP=b MPI=b threads=n ranks=n\"\n ```\n where <b>b</b> is 0 or 1, and <b>n</b> are integers.\n\n @ingroup debug\n @param[in] env object representing the execution environment. A single instance is used for each program\n @param[out] str to be populated with the output string\n @author Ania Brown\n @author Tyson Jones"]
728    pub fn getEnvironmentString(env: QuESTEnv, str_: *mut ::std::os::raw::c_char);
729}
730extern "C" {
731    #[doc = " In GPU mode, this copies the state-vector (or density matrix) from GPU memory\n (qureg.deviceStateVec) to RAM (qureg.stateVec), where it can be accessed/modified\n by the user.\n In CPU mode, this function has no effect.\n In conjunction with copyStateToGPU(), this allows a user to directly modify the\n state-vector in a harware agnostic way.\n Note though that users should instead use setAmps() if possible.\n\n For example, to set the first real element to 1, one could do:\n ```\n     copyStateFromGPU(qureg);\n     qureg.stateVec.real[0] = 1;\n     copyStateToGPU(qureg);\n ```\n\n Note users should never access qureg.deviceStateVec directly.\n\n @see\n - copyStateToGPU()\n - copySubstateFromGPU()\n - copySubstateToGPU()\n\n @ingroup debug\n @param[in, out] qureg the qureg of which to copy `.deviceStateVec` to `.stateVec` in GPU mode\n @author Ania Brown\n @author Tyson Jones (doc)"]
732    pub fn copyStateFromGPU(qureg: Qureg);
733}
734extern "C" {
735    #[doc = " Get the complex amplitude at a given index in the state vector.\n\n @see\n - getDensityAmp()\n - getRealAmp()\n - getImagAmp()\n - getProbAmp()\n - getNumAmps()\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg object representing a set of qubits\n @param[in] index index in state vector of probability amplitudes\n @return amplitude at index, returned as a Complex struct (with .real and .imag attributes)\n @throws invalidQuESTInputError()\n - if \\p qureg is a density matrix\n - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented\n @author Tyson Jones"]
736    pub fn getAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> Complex;
737}
738extern "C" {
739    #[doc = " Get the real component of the complex probability amplitude at an index in the state vector.\n\n @see\n - getAmp()\n - getDensityAmp()\n - getImagAmp()\n - getProbAmp()\n - getNumAmps()\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg object representing a set of qubits\n @param[in] index index in state vector of probability amplitudes\n @return real component at that index\n @throws invalidQuESTInputError()\n - if \\p qureg is a density matrix\n - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented\n @author Ania Brown"]
740    pub fn getRealAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
741}
742extern "C" {
743    #[doc = " Get the imaginary component of the complex probability amplitude at an index in the state vector.\n\n @see\n - getAmp()\n - getDensityAmp()\n - getRealAmp()\n - getProbAmp()\n - getNumAmps()\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg object representing a set of qubits\n @param[in] index index in state vector of probability amplitudes\n @return imaginary component at that index\n @throws invalidQuESTInputError()\n - if \\p qureg is a density matrix\n - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented\n @author Ania Brown"]
744    pub fn getImagAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
745}
746extern "C" {
747    #[doc = " Get the probability of a state-vector at an index in the full state vector.\n\n @see\n - getAmp()\n - getDensityAmp()\n - getRealAmp()\n - getImagAmp()\n - getNumAmps()\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg object representing a set of qubits\n @param[in] index index in state vector of probability amplitudes\n @return realEl*realEl + imagEl*imagEl\n @throws invalidQuESTInputError()\n - if \\p qureg is a density matrix\n - if \\p index is outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented\n @author Ania Brown"]
748    pub fn getProbAmp(qureg: Qureg, index: ::std::os::raw::c_longlong) -> f64;
749}
750extern "C" {
751    #[doc = " Get an amplitude from a density matrix at a given row and column.\n\n @see\n - getAmp()\n - getRealAmp()\n - getImagAmp()\n - getProbAmp()\n - getNumAmps()\n - getNumQubits()\n\n @ingroup calc\n @param[in] qureg object representing a density matrix\n @param[in] row row of the desired amplitude in the density matrix\n @param[in] col column of the desired amplitude in the density matrix\n @return a Complex scalar representing the desired amplitude\n @throws invalidQuESTInputError()\n - if \\p qureg is a state-vector,\n - if \\p row or \\p col are outside [0, \\f$2^{N}\\f$) where \\f$N = \\f$ \\p qureg.numQubitsRepresented\n @author Tyson Jones"]
752    pub fn getDensityAmp(
753        qureg: Qureg,
754        row: ::std::os::raw::c_longlong,
755        col: ::std::os::raw::c_longlong,
756    ) -> Complex;
757}
758extern "C" {
759    #[doc = " A debugging function which calculates the probability of the qubits in \\p qureg\n being in any state, which should always be 1 for correctly normalised states\n (hence returning a real number).\n For state-vectors \\f$ \\psi \\f$, this is the norm of the entire state-vector\n (the sum of the absolute-value-squared of every amplitude):\n \\f[\n      \\sum\\limits_i |\\psi_i|^2\n \\f]\n and for density matrices \\f$ \\rho \\f$, it is the trace:\n \\f[\n      \\text{Trace}(\\rho) = \\sum\\limits_i \\rho_{i,i} \\;\n \\f]\n\n For un-normalised density matrices (those directly modified or initialised by the user),\n this function returns the real component of the trace.\n\n Note this calculation utilises Kahan summation for greater accuracy, and hence is\n not parallelised and so will be slower than other functions.\n\n @ingroup calc\n @param[in] qureg object representing a set of qubits\n @return the total probability of the qubits in \\p qureg being in any state\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
760    pub fn calcTotalProb(qureg: Qureg) -> f64;
761}
762extern "C" {
763    #[doc = " Apply a single-qubit unitary parameterised by two given complex scalars.\n Given valid complex numbers \\f$\\alpha\\f$ and \\f$\\beta\\f$, applies the unitary\n \\f[\n U =\n \\begin{pmatrix}\n \\alpha & -\\beta^* \\\\\n \\beta & \\alpha^*\n \\end{pmatrix}\n \\f]\n which is general up to a global phase factor.\n Valid \\f$\\alpha\\f$, \\f$\\beta\\f$ satisfy \\f$|\\alpha|^2 + |\\beta|^2 = 1\\f$.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - controlledCompactUnitary()\n - unitary()\n - twoQubitUnitary()\n - multiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @param[in] alpha complex unitary parameter (row 1, column 1)\n @param[in] beta complex unitary parameter (row 2, column 1)\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p alpha, \\p beta don't satisfy |`alpha`|^2 + |`beta`|^2 = 1\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
764    pub fn compactUnitary(
765        qureg: Qureg,
766        targetQubit: ::std::os::raw::c_int,
767        alpha: Complex,
768        beta: Complex,
769    );
770}
771extern "C" {
772    #[doc = " Apply a general single-qubit unitary (including a global phase factor).\n The passed 2x2 ComplexMatrix must be unitary, otherwise an error is thrown.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n If \\p qureg is a state-vector, then the resulting state is \\f$ u \\, |\\text{qureg}\\rangle \\f$.\\n\n If \\p qureg is a density-matrix \\f$ \\rho \\f$, then the resulting state is \\f$ u \\, \\rho \\, u^\\dagger \\f$.\n\n > Use applyMatrix2() to left-multiply a non-unitary ::ComplexMatrix2\n\n @see\n - ::ComplexMatrix2\n - controlledUnitary()\n - multiControlledUnitary()\n - multiStateControlledUnitary()\n - twoQubitUnitary()\n - multiQubitUnitary()\n - applyMatrix2()\n - compactUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if matrix \\p u is not unitary\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
773    pub fn unitary(qureg: Qureg, targetQubit: ::std::os::raw::c_int, u: ComplexMatrix2);
774}
775extern "C" {
776    #[doc = " Rotate a single qubit by a given angle around the X-axis of the Bloch-sphere. For angle \\f$\\theta\\f$, applies\n \\f[\n \\begin{pmatrix}\n \\cos\\theta/2 & -i \\sin \\theta/2\\\\\n -i \\sin \\theta/2 & \\cos \\theta/2\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {rot};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_x(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - controlledRotateX()\n - rotateY()\n - rotateZ()\n - rotateAroundAxis()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] rotQubit qubit to rotate\n @param[in] angle angle by which to rotate in radians\n @throws invalidQuESTInputError()\n - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
777    pub fn rotateX(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
778}
779extern "C" {
780    #[doc = " Rotate a single qubit by a given angle around the Y-axis of the Bloch-sphere.\n For angle \\f$\\theta\\f$, applies\n \\f[\n \\begin{pmatrix}\n \\cos\\theta/2 & - \\sin \\theta/2\\\\\n \\sin \\theta/2 & \\cos \\theta/2\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {rot};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_y(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - controlledRotateY()\n - rotateX()\n - rotateZ()\n - rotateAroundAxis()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] rotQubit qubit to rotate\n @param[in] angle angle by which to rotate in radians\n @throws invalidQuESTInputError\n      if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented).\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc, debug)"]
781    pub fn rotateY(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
782}
783extern "C" {
784    #[doc = " Rotate a single qubit by a given angle around the Z-axis of the Bloch-sphere (also known as a phase shift gate).\n For angle \\f$\\theta\\f$, applies\n \\f[\n \\begin{pmatrix}\n \\exp(-i \\theta/2) & 0 \\\\\n 0 & \\exp(i \\theta/2)\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {rot};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_z(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - multiRotateZ()\n - controlledRotateZ()\n - rotateY()\n - rotateX()\n - rotateAroundAxis()\n - multiRotatePauli()\n - phaseShift()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] rotQubit qubit to rotate\n @param[in] angle angle by which to rotate in radians\n @throws invalidQuESTInputError()\n - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
785    pub fn rotateZ(qureg: Qureg, rotQubit: ::std::os::raw::c_int, angle: f64);
786}
787extern "C" {
788    #[doc = " Rotate a single qubit by a given angle around a given \\ref Vector on the Bloch-sphere.\n The vector must not be zero (else an error is thrown), but needn't be unit magnitude, since\n it will be normalised by QuEST.\n\n 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$\n where \\f$\\vec{\\sigma}\\f$ is the vector of Pauli matrices.\n\n @see\n - controlledRotateAroundAxis()\n - rotateX()\n - rotateY()\n - rotateZ()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] rotQubit qubit to rotate\n @param[in] angle angle by which to rotate in radians\n @param[in] axis vector around which to rotate (can be non-unit; will be normalised)\n @throws invalidQuESTInputError()\n - if \\p rotQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p axis is the zero vector\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
789    pub fn rotateAroundAxis(
790        qureg: Qureg,
791        rotQubit: ::std::os::raw::c_int,
792        angle: f64,
793        axis: Vector,
794    );
795}
796extern "C" {
797    #[doc = " Applies a controlled rotation by a given angle around the X-axis of the Bloch-sphere.\n The target qubit is rotated in states where the control qubit has value 1.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_x(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - rotateX()\n - controlledRotateY()\n - controlledRotateZ()\n - controlledRotateAroundAxis()\n - controlledPhaseShift()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit qubit which has value 1 in the rotated states\n @param[in] targetQubit qubit to rotate\n @param[in] angle angle by which to rotate the target qubit in radians\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n @author Tyson Jones"]
798    pub fn controlledRotateX(
799        qureg: Qureg,
800        controlQubit: ::std::os::raw::c_int,
801        targetQubit: ::std::os::raw::c_int,
802        angle: f64,
803    );
804}
805extern "C" {
806    #[doc = " Applies a controlled rotation by a given angle around the Y-axis of the Bloch-sphere.\n The target qubit is rotated in states where the control qubit has value 1.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_y(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n - rotateY()\n - controlledRotateX()\n - controlledRotateZ()\n - controlledRotateAroundAxis()\n - controlledPhaseShift()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit qubit which has value 1 in the rotated states\n @param[in] targetQubit qubit to rotate\n @param[in] angle angle by which to rotate the target qubit in radians\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n @author Tyson Jones"]
807    pub fn controlledRotateY(
808        qureg: Qureg,
809        controlQubit: ::std::os::raw::c_int,
810        targetQubit: ::std::os::raw::c_int,
811        angle: f64,
812    );
813}
814extern "C" {
815    #[doc = " Applies a controlled rotation by a given angle around the Z-axis of the Bloch-sphere.\n The target qubit is rotated in states where the control qubit has value 1.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_z(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - rotateZ()\n - controlledRotateX()\n - controlledRotateY()\n - controlledRotateAroundAxis()\n - controlledPhaseShift()\n - multiRotateZ()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit qubit which has value 1 in the rotated states\n @param[in] targetQubit qubit to rotate\n @param[in] angle angle by which to rotate the target qubit in radians\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n @author Tyson Jones"]
816    pub fn controlledRotateZ(
817        qureg: Qureg,
818        controlQubit: ::std::os::raw::c_int,
819        targetQubit: ::std::os::raw::c_int,
820        angle: f64,
821    );
822}
823extern "C" {
824    #[doc = " Applies a controlled rotation by a given angle around a given vector on the Bloch-sphere.\n The vector must not be zero (else an error is thrown), but needn't be unit magnitude.\n\n 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\n (\\f$\\vec{\\sigma}\\f$ is the vector of Pauli matrices).\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$R_{\\hat{n}}(\\theta)$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - rotateAroundAxis()\n - multiRotatePauli()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit qubit with value 1 in the rotated states\n @param[in] targetQubit qubit to rotate\n @param[in] angle angle by which to rotate in radians\n @param[in] axis vector around which to rotate (can be non-unit; will be normalised)\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n - if \\p axis is the zero vector\n @author Tyson Jones"]
825    pub fn controlledRotateAroundAxis(
826        qureg: Qureg,
827        controlQubit: ::std::os::raw::c_int,
828        targetQubit: ::std::os::raw::c_int,
829        angle: f64,
830        axis: Vector,
831    );
832}
833extern "C" {
834    #[doc = " Apply a controlled unitary (single control, single target) parameterised by two given complex scalars.\n Given valid complex numbers \\f$\\alpha\\f$ and \\f$\\beta\\f$, applies the two-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\n & & \\alpha & -\\beta^* \\\\\n & & \\beta & \\alpha^*\n \\end{pmatrix}\n \\f]\n to the control and target qubits.\n Valid \\f$\\alpha\\f$, \\f$\\beta\\f$ satisfy \\f$|\\alpha|^2 + |\\beta|^2 = 1\\f$.\n The target unitary is general up to a global phase factor.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$U_{\\alpha, \\beta}$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - compactUnitary()\n - controlledUnitary()\n - multiControlledUnitary()\n - multiStateControlledUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit apply the target unitary if this qubit has value 1\n @param[in] targetQubit qubit on which to apply the target unitary\n @param[in] alpha complex unitary parameter (row 1, column 1)\n @param[in] beta complex unitary parameter (row 2, column 1)\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n - if \\p alpha, \\p beta don't satisfy |`alpha`|^2 + |`beta`|^2 = 1\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
835    pub fn controlledCompactUnitary(
836        qureg: Qureg,
837        controlQubit: ::std::os::raw::c_int,
838        targetQubit: ::std::os::raw::c_int,
839        alpha: Complex,
840        beta: Complex,
841    );
842}
843extern "C" {
844    #[doc = " Apply a general controlled unitary (single control, single target), which can include a global phase factor.\n The given unitary is applied to the target qubit if the control qubit has value 1,\n effecting the two-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\n & & u_{00} & u_{01}\\\\\n & & u_{10} & u_{11}\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - ::ComplexMatrix2\n - unitary()\n - multiControlledUnitary()\n - multiStateControlledUnitary()\n - twoQubitUnitary()\n - multiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit apply unitary if this qubit is 1\n @param[in] targetQubit qubit to operate on\n @param[in] u single-qubit unitary matrix to apply\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n - if \\p u is not unitary\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
845    pub fn controlledUnitary(
846        qureg: Qureg,
847        controlQubit: ::std::os::raw::c_int,
848        targetQubit: ::std::os::raw::c_int,
849        u: ComplexMatrix2,
850    );
851}
852extern "C" {
853    #[doc = " Apply a general multiple-control single-target unitary, which can include\n a global phase factor. Any number of control qubits can be specified,\n and if all have value 1, the given unitary is applied to the target qubit.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & u_{00} & u_{01}\\\\\n & & & u_{10} & u_{11}\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n The given 2x2 ComplexMatrix must be unitary, otherwise an error is thrown.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 3) {controls};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\node[draw=none] at (0, 6) {$\\vdots$};\n\\draw (0, 5) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw (0, 4) -- (0, 2);\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - ::ComplexMatrix2\n - unitary()\n - controlledUnitary()\n - multiStateControlledUnitary()\n - twoQubitUnitary()\n - multiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits applies unitary if all qubits in this array equal 1\n @param[in] numControlQubits number of control qubits\n @param[in] targetQubit qubit to operate on\n @param[in] u single-qubit unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p numControlQubits is outside [1, \\p qureg.numQubitsRepresented])\n - if any qubit index (\\p targetQubit or one in \\p controlQubits) is outside [0, \\p qureg.numQubitsRepresented])\n - if any qubit in \\p controlQubits is repeated\n - if \\p controlQubits contains \\p targetQubit\n - if \\p u is not unitary\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
854    pub fn multiControlledUnitary(
855        qureg: Qureg,
856        controlQubits: *mut ::std::os::raw::c_int,
857        numControlQubits: ::std::os::raw::c_int,
858        targetQubit: ::std::os::raw::c_int,
859        u: ComplexMatrix2,
860    );
861}
862extern "C" {
863    #[doc = " Apply the single-qubit Pauli-X (also known as the X, sigma-X, NOT or bit-flip) gate.\n This is a rotation of \\f$\\pi\\f$ around the x-axis on the Bloch sphere. I.e.\n \\f[\n \\begin{pmatrix}\n 0 & 1 \\\\\n 1 & 0\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (2, 0);\n\\draw (0, 0) circle (.5);\n\\draw (0, .5) -- (0, -.5);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - rotateX()\n - pauliY()\n - pauliZ()\n - controlledNot()\n - multiQubitNot()\n - multiControlledMultiQubitNot()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
864    pub fn pauliX(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
865}
866extern "C" {
867    #[doc = " Apply the single-qubit Pauli-Y (also known as the Y or sigma-Y) gate.\n This is a rotation of \\f$\\pi\\f$ around the Y-axis on the Bloch sphere. I.e.\n \\f[\n \\begin{pmatrix}\n 0 & -i \\\\\n i & 0\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$\\sigma_y$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - rotateY()\n - pauliX()\n - pauliZ()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
868    pub fn pauliY(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
869}
870extern "C" {
871    #[doc = " Apply the single-qubit Pauli-Z (also known as the Z, sigma-Z or phase-flip) gate.\n This is a rotation of \\f$\\pi\\f$ around the Z-axis (a phase shift) on the Bloch sphere. I.e.\n \\f[\n \\begin{pmatrix}\n 1 & 0 \\\\\n 0 & -1\n \\end{pmatrix}\n \\f]\n with circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {$\\sigma_z$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - phaseShift()\n - rotateZ()\n - pauliX()\n - pauliY()\n - controlledPhaseFlip()\n - multiControlledPhaseFlip()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
872    pub fn pauliZ(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
873}
874extern "C" {
875    #[doc = " Apply the single-qubit Hadamard gate.\n 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\n \\f$\\pi\\f$ around the x-axis then \\f$\\pi/2\\f$ about the y-axis on the Bloch-sphere. I.e.\n \\f[\n \\frac{1}{\\sqrt{2}}\n \\begin{pmatrix}\n 1 & 1 \\\\\n 1 & -1\n \\end{pmatrix}\n \\f]\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {H};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate on\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
876    pub fn hadamard(qureg: Qureg, targetQubit: ::std::os::raw::c_int);
877}
878extern "C" {
879    #[doc = " Apply the controlled not (single control, single target) gate, also\n known as the c-X, c-sigma-X, c-Pauli-X and c-bit-flip gate.\n This applies pauliX to the target qubit if the control qubit has value 1.\n This effects the two-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & & 1 \\\\\n & & 1\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, -.5);\n\n\\draw (-2,0) -- (2, 0);\n\\draw (0, 0) circle (.5);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - multiControlledMultiQubitNot()\n - pauliX()\n\n @ingroup unitary\n @param[in,out] qureg the state-vector or density matrix to modify\n @param[in] controlQubit nots the target if this qubit is 1\n @param[in] targetQubit qubit to not\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p controlQubit and \\p targetQubit are equal\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix, doc)"]
880    pub fn controlledNot(
881        qureg: Qureg,
882        controlQubit: ::std::os::raw::c_int,
883        targetQubit: ::std::os::raw::c_int,
884    );
885}
886extern "C" {
887    #[doc = " Apply a NOT (or Pauli X) gate with multiple control and target qubits.\n This applies pauliX to qubits \\p targs on every basis state for which the\n control qubits \\p ctrls are all in the \\f$|1\\rangle\\f$ state. The ordering within\n each of \\p ctrls and \\p targs has no effect on the operation.\n > This function is equivalent, but significantly faster (approximately \\p numTargs times)\n > than applying controlled NOTs on each qubit in \\p targs in turn, since:\n > \\f[\n >     C_{a, \\,b, \\,\\dots}( X_c \\otimes X_d \\otimes \\dots ) \\equiv\n >     C_{a, \\,b, \\,\\dots}( X_c) \\; \\otimes \\; C_{a, \\,b, \\,\\dots}(X_d) \\; \\otimes \\; \\dots\n > \\f]\n\n The effected unitary, if \\p targs and \\p ctrls happened to be contiguous, has matrix:\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & &   &    & {{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}}}} \\\\\n & & & &   & 1  &   \\\\\n & & & & 1 &    &  \\\\\n & & & {{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}^{{\\scriptstyle\\cdot}}}} & & &\n \\end{pmatrix}\n \\f]\n and circuit diagram:\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 1) {targets};\n\\node[draw=none] at (-3.5, 5) {controls};\n\n\\node[draw=none] at (0, 8) {$\\vdots$};\n\\draw (0, 7) -- (0, 6);\n\n\\draw (-2, 6) -- (2, 6);\n\\draw[fill=black] (0, 6) circle (.2);\n\\draw (0, 6) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, -1);\n\n\\draw (-2,2) -- (2, 2);\n\\draw (0, 2) circle (.4);\n\n\\draw (-2,0) -- (2, 0);\n\\draw (0, 0) circle (.4);\n\n\\node[draw=none] at (0, -1.5) {$\\vdots$};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n > In distributed mode, this operation requires at most a single round of pair-wise\n > communication between nodes, and hence is as efficient as pauliX().\n\n @see\n - multiQubitNot()\n - controlledNot()\n - pauliX()\n\n @ingroup unitary\n @param[in,out] qureg a state-vector or density matrix to modify\n @param[in] ctrls a list of the control qubit indices\n @param[in] numCtrls the length of list \\p ctrls\n @param[in] targs a list of the qubits to be targeted by the X gates\n @param[in] numTargs the length of list \\p targs\n @throws invalidQuESTInputError()\n - if any qubit in \\p ctrls and \\p targs is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p ctrls or \\p targs contain any repetitions\n - if any qubit in \\p ctrls is also in \\p targs (and vice versa)\n - if \\p numTargs <b>< 1</b>\n - if \\p numCtrls <b>< 1</b> (use multiQubitNot() for no controls)\n @throws segmentation-fault\n - if \\p ctrls contains fewer elements than \\p numCtrls\n - if \\p targs contains fewer elements than \\p numTargs\n @author Tyson Jones"]
888    pub fn multiControlledMultiQubitNot(
889        qureg: Qureg,
890        ctrls: *mut ::std::os::raw::c_int,
891        numCtrls: ::std::os::raw::c_int,
892        targs: *mut ::std::os::raw::c_int,
893        numTargs: ::std::os::raw::c_int,
894    );
895}
896extern "C" {
897    #[doc = " Apply the controlled pauliY (single control, single target) gate, also\n known as the c-Y and c-sigma-Y gate.\n This applies pauliY to the target qubit if the control qubit has value 1.\n This effects the two-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & & -i \\\\\n & & i\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {control};\n\\node[draw=none] at (-3.5, 0) {target};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw[fill=black] (0, 2) circle (.2);\n\\draw (0, 2) -- (0, 1);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-1,-1)--(-1,1)--(1,1)--(1,-1)--cycle;\n\\node[draw=none] at (0, 0) {Y};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit applies pauliY to the target if this qubit is 1\n @param[in] targetQubit qubit to not\n @throws invalidQuESTInputError()\n - if either \\p controlQubit or \\p targetQubit are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubit and \\p targetQubit are equal\n @author Tyson Jones\n @author Ania Brown (debug)"]
898    pub fn controlledPauliY(
899        qureg: Qureg,
900        controlQubit: ::std::os::raw::c_int,
901        targetQubit: ::std::os::raw::c_int,
902    );
903}
904extern "C" {
905    #[doc = " Gives the probability of a specified qubit being measured in the given outcome (0 or 1).\n This performs no actual measurement and does not change the state of the qubits.\n\n For state-vectors, this function works by summing the absolute-value-squared of every\n amplitude in the state-vector for which \\p measureQubit \\p = \\p 0.\n If \\p outcome \\p = \\p 1, it returns \\p 1 minus this value. Hence for unnormalised\n state-vectors, this result will differ from the absolute-value-squared of every\n amplitude where \\p measureQubit \\p = \\p outcome.\n\n For density matrices, this function sums the diagonal values (should be real)\n corresponding to \\p measureQubit \\p = \\p 0 (returning 1 minus this if \\p outcome \\p = \\p 1).\n\n @see\n - calcProbOfAllOutcomes()\n\n @see\n - measure()\n - measureWithStats()\n - collapseToOutcome()\n - calcTotalProb()\n\n @ingroup calc\n @param[in] qureg object representing the set of all qubits\n @param[in] measureQubit qubit to study\n @param[in] outcome for which to find the probability of the qubit being measured in\n @return probability of qubit measureQubit being measured in the given outcome\n @throws invalidQuESTInputError()\n - if \\p measureQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p outcome is not in {0, 1}\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix)"]
906    pub fn calcProbOfOutcome(
907        qureg: Qureg,
908        measureQubit: ::std::os::raw::c_int,
909        outcome: ::std::os::raw::c_int,
910    ) -> f64;
911}
912extern "C" {
913    #[doc = " Populates \\p outcomeProbs with the probabilities of every outcome of the sub-register\n contained in \\p qubits.\n\n > This performs no actual measurement and does not modify \\p qureg.\n\n - For \\p qubits <b>= {a, b, c, ...}</b>, \\p outcomeProbs\n   is populated to\n   \\f[\n     \\text{outcomeProbs} = \\{ \\; |\\alpha_0|^2, \\; |\\alpha_1|^2, \\; |\\alpha_2|^2, \\; |\\alpha_3|^2, \\; ... \\; \\},\n   \\f]\n   where \\f$|\\alpha_j|^2\\f$ are the probabilities of the respective outcome states (interpreting\n   \\p qubits as ordered least to most significant)\n   \\f[\n      |\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}\\rangle_i \\; \\; = \\;\\; |000\\rangle,  \\;\\; |001\\rangle \\;\\; |010\\rangle \\;\\; |011\\rangle, \\;\\; \\dots\n   \\f]\n   understood in a state-vector \\p qureg \\f$|\\psi\\rangle\\f$ as\n   \\f[\n      |\\psi\\rangle = \\sum\\limits_i^{\\text{numQubits}} \\alpha_i \\; |\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}\\rangle_i\n        \\; \\otimes \\; |\\phi\\rangle_i,\n   \\f]\n   or in a density matrix \\p qureg \\f$\\rho\\f$ as\n   \\f[\n      \\begin{aligned}\n      \\rho &= \\sum\\limits_{i,j}^{\\text{numQubits}} \\; \\beta_{ij} \\; |\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}\\rangle_i\\,\\langle\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}|_j\n            \\; \\otimes \\; \\mu_{ij} \\\\\n           &= \\sum\\limits_i^{\\text{numQubits}} \\; |\\alpha_i|^2 \\;  |\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}\\rangle\\langle\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}|_i  \\;\\; + \\,\n            \\sum\\limits_{i \\ne j}^{\\text{numQubits}} \\; \\beta_{ij} \\; |\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}\\rangle_i\\,\\langle\\dots\\textbf{c}\\,\\textbf{b}\\,\\textbf{a}|_j\n            \\; \\otimes \\; \\mu_{ij},\n       \\end{aligned}\n   \\f]\n   where \\f$|\\phi\\rangle_i\\f$ and \\f$\\mu_{ij}\\f$ are understood to be the separated states of the remaining qubits.\n\n > \\p outcomeProbs must be a pre-allocated array of length \\f$2^{\\text{numQubits}}\\f$,\n > which is equivalent to <b>1<<</b>\\p numQubits. In distributed mode, every node receives\n > the full list of outcome probabilities.\n\n - Note that the indices in \\p qubits need not be adjacent nor ordered. The order of\n   \\p qubits determines the order of \\p outcomeProbs, whereby \\p qubits are treated\n   as <em>increasing</em> significance.\n   \\n\\n\n\n - For example, given a \\p qureg initialised into state-vector\n   \\f[\n      |\\psi\\rangle =\n          \\alpha_0 |000\\rangle \\;+\\; \\alpha_1 |001\\rangle \\;+\\;\n          \\alpha_2 |010\\rangle \\;+\\; \\alpha_3 |011\\rangle \\;+\\;\n          \\alpha_4 |100\\rangle \\;+\\; \\alpha_5 |101\\rangle \\;+\\;\n          \\alpha_6 |110\\rangle \\;+\\; \\alpha_7 |111\\rangle,\n   \\f]\n   then executing\n   ```\n   int qubits[] = {2, 0};\n   int numQubits = 2;\n\n   qreal outcomeProbs[1<<numQubits];\n   calcProbOfAllOutcomes(outcomeProbs, qureg, qubits, numQubits);\n   ```\n   would populate \\p outcomeProbs with\n   \\f[\n      \\text{outcomeProbs} = \\{ \\;\\; |\\alpha_0|^2+|\\alpha_2|^2, \\;\\; |\\alpha_4|^2+|\\alpha_6|^2, \\;\\;\n                                 |\\alpha_1|^2+|\\alpha_3|^2, \\;\\; |\\alpha_5|^2+|\\alpha_7|^2  \\;\\; \\}.\n   \\f]\n\n > Since all probability amplitudes of a state-vector are ultimately involved in\n > the output probabilities, calcProbOfAllOutcomes() works as expected for\n > un-normalised states. This is similarly true for density matrices, where all\n > diagonal elements are involved, although only the real values of the diagonal elements\n > will be consulted.\n\n @see\n - calcProbOfOutcome()\n\n @ingroup calc\n @param[out] outcomeProbs a pre-allocated array of length <b>1<<</b>\\p numQubits,\n      which will be modified to contain all outcome probabilities\n @param[in] qureg a state-vector or density matrix to study\n @param[in] qubits a list of qubits to study\n @param[in] numQubits the length of list \\p qubits\n @throws invalidQuESTInputError()\n - if \\p numQubits <= 0\n - if any index in \\p qubits is invalid, i.e. outside <b>[0,</b> \\p qureg.numQubitsRepresented <b>)</b>\n - if \\p qubits contains any repetitions\n @throws segmentation-fault\n - if \\p outcomeProbs is not pre-allocated\n - if \\p outcomeProbs contains space for fewer than <b>1<<</b>\\p numQubits elements\n @author Tyson Jones"]
914    pub fn calcProbOfAllOutcomes(
915        outcomeProbs: *mut f64,
916        qureg: Qureg,
917        qubits: *mut ::std::os::raw::c_int,
918        numQubits: ::std::os::raw::c_int,
919    );
920}
921extern "C" {
922    #[doc = " Measures a single qubit, collapsing it randomly to 0 or 1.\n\n Outcome probabilities are weighted by the state vector, which is irreversibly\n changed after collapse to be consistent with the outcome.\n\n > The random outcome generator is seeded by seedQuESTDefault() within\n > createQuESTEnv(), unless later overridden by seedQuEST().\n\n @see\n - measureWithStats()\n - collapseToOutcome()\n - seedQuEST()\n - seedQuESTDefault()\n\n @ingroup normgate\n @param[in, out] qureg object representing the set of all qubits\n @param[in] measureQubit qubit to measure\n @return the measurement outcome, 0 or 1\n @throws invalidQuESTInputError()\n - if \\p measureQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Ania Brown (state-vector)\n @author Tyson Jones (density matrix)"]
923    pub fn measure(qureg: Qureg, measureQubit: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
924}
925extern "C" {
926    #[doc = " Computes the inner product \\f$ \\langle \\text{bra} | \\text{ket} \\rangle \\f$ of two\n equal-size state vectors, given by\n \\f[\n\\langle \\text{bra} | \\text{ket} \\rangle = \\sum_i {\\text{bra}_i}^* \\; \\times \\; \\text{ket}_i\n \\f]\n The same \\p qureg may be passed as both \\p bra and \\p ket,\n though we recommend users check state-vector normalisation with \\p calcTotalProb which\n employs Kahan summation for greater accuracy.\n Neither state-vector is modified.\n\n This function returns the correct inner product even if \\p bra and \\p ket are\n not correctly normalised states.\n\n @see\n - calcDensityInnerProduct()\n\n @ingroup calc\n @param[in] bra qureg to be the 'bra' (i.e. have its values conjugate transposed) in the inner product\n @param[in] ket qureg to be the 'ket' in the inner product\n @return the complex inner product of \\p bra and \\p ket\n @throws invalidQuESTInputError()\n - if either \\p bra and \\p ket are not both state-vectors\n - if \\p bra and \\p ket do not have equal dimensions\n @author Tyson Jones"]
927    pub fn calcInnerProduct(bra: Qureg, ket: Qureg) -> Complex;
928}
929extern "C" {
930    #[doc = " Computes the Hilbert-Schmidt scalar product\n (which is equivalent to the Frobenius inner product of matrices)\n of two density matrices \\p rho1 and \\p rho2 of equivalent size.\n That is, we define the Hilbert-Schmidt scalar product\n \\f[\n((\\rho_1, \\rho_2))_{HS} := \\text{Tr}[ \\rho_1^\\dagger \\rho_2 ],\n \\f]\n which is equivalent to the sum of products of matrix elemets, i.e.,\n \\f[\n((\\rho_1, \\rho_2))_{HS} = \\sum\\limits_i \\sum\\limits_j  (\\rho_1)_{ij}^* (\\rho_2)_{ij}\n \\f]\n Assuming that both density matrices are Hermitian,\n the resulting scalar product is real and invariant under\n reordering its arguments as\n \\f[\n((\\rho_1, \\rho_2))_{HS} = ((\\rho_2, \\rho_1))_{HS} = \\text{Tr}[\\rho_1 \\rho_2]\n \\f]\n If both \\p rho1 and \\p rho2 are density matrices of pure states\n \\p bra and \\p ket, then the equality holds\n \\f[\n((\\rho_1, \\rho_2))_{HS} = |\\langle \\text{bra} | \\text{ket} \\rangle|^2.\n \\f]\n If either or both of \\p rho1 and \\p rho2 are non Hermitian (i.e. invalid density\n matrices), then this function returns the real component of the scalar product,\n and discards the imaginary component. That is, it returns\n \\f[\n\\text{Re}\\{ \\text{Tr}[ \\rho_1^\\dagger \\rho_2 ] \\} = \\text{Re}\\{ \\text{Tr}[ \\rho_2^\\dagger \\rho_1 ] \\}.\n \\f]\n This is still sometimes useful, e.g. in calculating the inner product with an\n anti-commutator, e.g. (for Hermitian \\f$ \\sigma \\f$, \\f$ \\rho \\f$, \\f$ H \\f$)\n \\f[\n      ((\\sigma, H \\rho + \\rho H))_{HS} = 2 \\; \\text{Re} \\{ ((\\sigma, H \\rho))_{HS} \\}\n \\f]\n where \\f$ H \\rho \\f$ could be a weighted sum of Pauli products applied to \\f$ \\rho \\f$\n through applyPauliSum().\n\n @see\n - calcInnerProduct()\n - calcHilbertSchmidtDistance()\n\n @ingroup calc\n @param[in] rho1 qureg as a density matrix (to have its values conjugate transposed)\n @param[in] rho2 qureg as a density matrix\n @returns the real Hilbert-Schmidt scalar product of density matrices\n\\p rho1 and \\p rho2 (assuming Hermiticity)\n @throws invalidQuESTInputError()\n - if \\p rho1 and \\p rho2 are not both density matrices\n - if \\p rho1 and \\p rho2 have mismatching dimensions\n @author Balint Koczor (CPU)\n @author Tyson Jones (GPU)"]
931    pub fn calcDensityInnerProduct(rho1: Qureg, rho2: Qureg) -> f64;
932}
933extern "C" {
934    #[doc = " Seeds the random number generator with a custom array of key(s), overriding the\n default keys.\n\n This determines the sequence of outcomes in functions like measure() and measureWithStats().\n\n In distributed mode, the key(s) passed to the master node will be broadcast to all\n other nodes, such that every node generates the same sequence of pseudorandom numbers.\n\n This function will copy the contents of \\p seedArray into a permanent array\n `env.seeds`, so \\p seedArray is afterward safe to free.\n\n > QuEST uses the\n > <a href=\"http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\">Mersenne Twister</a>\n > for random number generation.\n\n @see\n - Use seedQuESTDefault() to seed via the current timestamp and process id.\n - Use getQuESTSeeds() to obtain the seeds currently being used for RNG.\n\n @ingroup debug\n @param[in] env a pointer to the ::QuESTEnv runtime environment\n @param[in] seedArray Array of integers to use as seed.\n  This allows the MT to be initialised with more than a 32-bit integer if required\n @param[in] numSeeds Length of seedArray\n @author Ania Brown\n @author Tyson Jones (doc)"]
935    pub fn seedQuEST(
936        env: *mut QuESTEnv,
937        seedArray: *mut ::std::os::raw::c_ulong,
938        numSeeds: ::std::os::raw::c_int,
939    );
940}
941extern "C" {
942    #[doc = " Obtain the seeds presently used in random number generation.\n\n This function sets argument \\p seeds to the address of the array of keys\n which have seeded QuEST's\n <a href=\"http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html\">Mersenne Twister</a>\n random number generator. \\p numSeeds is set to the length of \\p seeds.\n These are the seeds which inform the outcomes of random functions like\n measure(), and are set using seedQuEST() and seedQuESTDefault().\n\n > The output \\p seeds array <b>must not</b> be freed, and should not be modified.\n\n Obtaining QuEST's seeds is useful for seeding your own random number generators,\n so that a simulation (with random QuEST measurements, and your own random decisions)\n can be precisely repeated later, just by calling seedQuEST().\n\n Note this function merely sets the arguments to the attributes for \\p env.\n I.e.\n ```\n     unsigned long int* seeds;\n     int numSeeds;\n     getQuESTSeeds(env, &seeds, &numSeeds);\n\n     func(seeds, numSeeds);\n ```\n is equivalent to\n ```\n     func(env.seeds, env.numSeeds);\n ```\n However, one should not rely upon their local pointer from getQuESTSeeds() to be\n automatically updated after a subsequent call to seedQuEST() or seedQuESTDefault().\n Instead, getQuESTSeeds() should be recalled.\n\n @see\n - seedQuEST()\n - seedQuESTDefault()\n\n @ingroup debug\n @param[in] env the ::QuESTEnv runtime environment\n @param[in] seeds a pointer to an unitialised array to be modified\n @param[in] numSeeds a pointer to an integer to be modified\n @author Tyson Jones"]
943    pub fn getQuESTSeeds(
944        env: QuESTEnv,
945        seeds: *mut *mut ::std::os::raw::c_ulong,
946        numSeeds: *mut ::std::os::raw::c_int,
947    );
948}
949extern "C" {
950    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit dephasing noise.\n With probability \\p prob, applies Pauli Z to \\p targetQubit.\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\n (1 - \\text{prob}) \\, \\rho + \\text{prob} \\; Z_q \\, \\rho \\, Z_q\n \\f]\n where q = \\p targetQubit.\n \\p prob cannot exceed 1/2, which maximally mixes \\p targetQubit.\n\n @see\n - mixTwoQubitDephasing()\n - mixDamping()\n - mixDepolarising()\n - mixKrausMap()\n - mixPauli()\n - mixDensityMatrix()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] targetQubit qubit upon which to induce dephasing noise\n @param[in] prob the probability of the phase error occuring\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p prob is not in [0, 1/2]\n @author Tyson Jones (GPU, doc)\n @author Ania Brown (CPU, distributed)"]
951    pub fn mixDephasing(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
952}
953extern "C" {
954    #[doc = " Mixes a density matrix \\p qureg to induce two-qubit dephasing noise.\n With probability \\p prob, applies Pauli Z to either or both qubits.\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\n (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{3} \\; \\left(\n      Z_a \\, \\rho \\, Z_a +\n      Z_b \\, \\rho \\, Z_b +\n      Z_a Z_b \\, \\rho \\, Z_a Z_b\n \\right)\n \\f]\n where a = \\p qubit1, b = \\p qubit2.\n \\p prob cannot exceed 3/4, at which maximal mixing occurs.\n\n @see\n - mixDephasing()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] qubit1 qubit upon which to induce dephasing noise\n @param[in] qubit2 qubit upon which to induce dephasing noise\n @param[in] prob the probability of the phase error occuring\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if either \\p qubit1 or \\p qubit2 is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p qubit1 = \\p qubit2\n - if \\p prob is not in [0, 3/4]\n @author Tyson Jones (GPU, doc)\n @author Ania Brown (CPU, distributed)"]
955    pub fn mixTwoQubitDephasing(
956        qureg: Qureg,
957        qubit1: ::std::os::raw::c_int,
958        qubit2: ::std::os::raw::c_int,
959        prob: f64,
960    );
961}
962extern "C" {
963    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit homogeneous depolarising noise.\n This is equivalent to, with probability \\p prob, uniformly randomly applying\n either Pauli X, Y, or Z to \\p targetQubit.\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\n (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{3} \\; \\left(\n      X_q \\, \\rho \\, X_q +\n      Y_q \\, \\rho \\, Y_q +\n      Z_q \\, \\rho \\, Z_q\n \\right)\n \\f]\n where q = \\p targetQubit.\n \\p prob cannot exceed 3/4, at which maximal mixing occurs.\n The produced state is equivalently expressed as\n \\f[\n      \\left( 1 - \\frac{4}{3} \\text{prob} \\right) \\rho +\n      \\left( \\frac{4}{3} \\text{prob} \\right) \\frac{\\vec{\\bf{1}}}{2}\n \\f]\n where \\f$ \\frac{\\vec{\\bf{1}}}{2} \\f$ is the maximally mixed state of the target\n qubit.\n\n @see\n - mixTwoQubitDepolarising()\n - mixDephasing()\n - mixDamping()\n - mixKrausMap()\n - mixPauli()\n - mixDensityMatrix()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] targetQubit qubit upon which to induce depolarising noise\n @param[in] prob the probability of the depolarising error occuring\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p prob is not in [0, 3/4]\n @author Tyson Jones (GPU, doc)\n @author Ania Brown (CPU, distributed)"]
964    pub fn mixDepolarising(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
965}
966extern "C" {
967    #[doc = " Mixes a density matrix \\p qureg to induce single-qubit amplitude damping (decay to 0 state).\n With probability \\p prob, applies damping (transition from 1 to 0 state).\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\nK_0 \\rho K_0^\\dagger + K_1 \\rho K_1^\\dagger\n \\f]\n where q = \\p targetQubit and \\f$K_0\\f$ and \\f$K_1\\f$ are Kraus operators\n \\f[\nK_0 = \\begin{pmatrix} 1 & 0 \\\\ 0 & \\sqrt{1-\\text{prob}} \\end{pmatrix}, \\;\\;\nK_1 = \\begin{pmatrix} 0 & \\sqrt{\\text{prob}} \\\\ 0 & 0 \\end{pmatrix}.\n \\f]\n \\p prob cannot exceed 1, at which total damping/decay occurs. Note that unlike\n mixDephasing() and mixDepolarising(), this function can increase the purity of a\n mixed state (by, as \\p prob becomes 1, gaining certainty that the qubit is in\n the 0 state).\n\n @see\n - mixDephasing()\n - mixDepolarising()\n - mixKrausMap()\n - mixPauli()\n - mixDensityMatrix()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] targetQubit qubit upon which to induce amplitude damping\n @param[in] prob the probability of the damping\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p prob is not in [0, 1]\n @author Nicolas Vogt of HQS (local CPU)\n @author Ania Brown (GPU, patched local CPU)\n @author Tyson Jones (distributed, doc)"]
968    pub fn mixDamping(qureg: Qureg, targetQubit: ::std::os::raw::c_int, prob: f64);
969}
970extern "C" {
971    #[doc = " Mixes a density matrix \\p qureg to induce two-qubit homogeneous depolarising noise.\n With probability \\p prob, applies to \\p qubit1 and \\p qubit2 any operator of the set\n \\f$\\{ IX, IY, IZ, XI, YI, ZI, XX, XY, XZ, YX, YY, YZ, ZX, ZY, ZZ \\}\\f$.\n Note this is the set of all two-qubit Pauli gates excluding \\f$II\\f$.\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\n (1 - \\text{prob}) \\, \\rho \\; + \\; \\frac{\\text{prob}}{15} \\; \\left(\n      \\sum \\limits_{\\sigma_a \\in \\{X_a,Y_a,Z_a,I_a\\}}\n      \\sum \\limits_{\\sigma_b \\in \\{X_b,Y_b,Z_b,I_b\\}}\n      \\sigma_a \\sigma_b \\; \\rho \\; \\sigma_a \\sigma_b\n \\right)\n - \\frac{\\text{prob}}{15} I_a I_b \\; \\rho \\; I_a I_b\n \\f]\n or verbosely\n \\f[\n (1 - \\text{prob}) \\, \\rho + \\frac{\\text{prob}}{15} \\; \\left(\n \\begin{aligned}\n      &X_a \\, \\rho \\, X_a +\n      X_b \\, \\rho \\, X_b +\n      Y_a \\, \\rho \\, Y_a +\n      Y_b \\, \\rho \\, Y_b +\n      Z_a \\, \\rho \\, Z_a +\n      Z_b \\, \\rho \\, Z_b\n   \\\\\n    + &X_a X_b \\, \\rho \\, X_a X_b +\n      X_a Y_b \\, \\rho \\, X_a Y_b +\n      X_a Z_b \\, \\rho \\, X_a Z_b +\n      Y_a X_b \\, \\rho \\, Y_a X_b\n \\\\\n   + &Y_a Y_b \\, \\rho \\, Y_a Y_b +\n      Y_a Z_b \\, \\rho \\, Y_a Z_b +\n      Z_a X_b \\, \\rho \\, Z_a X_b +\n      Z_a Y_b \\, \\rho \\, Z_a Y_b +\n      Z_a Z_b \\, \\rho \\, Z_a Z_b\n \\end{aligned}\n \\right)\n \\f]\n where a = \\p qubit1, b = \\p qubit2.\n\n \\p prob cannot exceed 15/16, at which maximal mixing occurs.\n\n The produced state is equivalently expressed as\n \\f[\n      \\left( 1 - \\frac{16}{15} \\text{prob} \\right) \\rho + \\left( \\frac{16}{15} \\text{prob} \\right) \\frac{\\vec{\\bf{1}}}{2}\n \\f]\n where \\f$ \\frac{\\vec{\\bf{1}}}{2} \\f$ is the maximally mixed state of the two\n target qubits.\n\n @see\n - mixDepolarising()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] qubit1 qubit upon which to induce depolarising noise\n @param[in] qubit2 qubit upon which to induce depolarising noise\n @param[in] prob the probability of the depolarising error occuring\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if either \\p qubit1 or \\p qubit2 is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p qubit1 = \\p qubit2\n - if \\p prob is not in [0, 15/16]\n @author Tyson Jones (GPU, doc)\n @author Ania Brown (CPU, distributed)"]
972    pub fn mixTwoQubitDepolarising(
973        qureg: Qureg,
974        qubit1: ::std::os::raw::c_int,
975        qubit2: ::std::os::raw::c_int,
976        prob: f64,
977    );
978}
979extern "C" {
980    #[doc = " Mixes a density matrix \\p qureg to induce general single-qubit Pauli noise.\n With probabilities \\p probX, \\p probY and \\p probZ, applies Pauli X, Y, and Z\n respectively to \\p targetQubit.\n\n This transforms \\p qureg = \\f$\\rho\\f$ into the mixed state\n \\f[\n (1 - \\text{probX} - \\text{probY} - \\text{probZ}) \\, \\rho + \\;\\;\\;\n      (\\text{probX})\\; X_q \\, \\rho \\, X_q + \\;\\;\\;\n      (\\text{probY})\\; Y_q \\, \\rho \\, Y_q + \\;\\;\\;\n      (\\text{probZ})\\; Z_q \\, \\rho \\, Z_q\n \\f]\n where q = \\p targetQubit.\n Each of \\p probX, \\p probY and \\p probZ cannot exceed the chance of no error:\n 1 - \\p probX - \\p probY - \\p probZ\n\n This function operates by first converting the given Pauli probabilities into\n a single-qubit Kraus map (four 2x2 operators).\n\n @see\n - mixDephasing()\n - mixDepolarising()\n - mixDamping()\n - mixKrausMap()\n - mixDensityMatrix()\n\n @ingroup decoherence\n @param[in,out] qureg a density matrix\n @param[in] targetQubit qubit to decohere\n @param[in] probX the probability of inducing an X error\n @param[in] probY the probability of inducing an Y error\n @param[in] probZ the probability of inducing an Z error\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n - if any of \\p probX, \\p probY or \\p probZ are not in [0, 1]\n - if any of p in {\\p probX, \\p probY or \\p probZ} don't satisfy p <= (1 - \\p probX - \\p probY - \\p probZ)\n @author Balint Koczor\n @author Tyson Jones (refactored, doc)"]
981    pub fn mixPauli(
982        qureg: Qureg,
983        targetQubit: ::std::os::raw::c_int,
984        probX: f64,
985        probY: f64,
986        probZ: f64,
987    );
988}
989extern "C" {
990    #[doc = " Modifies combineQureg to become (1-\\p prob)\\p combineProb + \\p prob \\p otherQureg.\n Both registers must be equal-dimension density matrices, and prob must be in [0, 1].\n\n @see\n - mixDephasing()\n - mixDepolarising()\n - mixDamping()\n - mixKrausMap()\n - mixPauli()\n\n @ingroup decoherence\n @param[in,out] combineQureg a density matrix to be modified\n @param[in] prob the probability of \\p otherQureg in the modified \\p combineQureg\n @param[in] otherQureg a density matrix to be mixed into \\p combineQureg\n @throws invalidQuESTInputError()\n - if either \\p combineQureg or \\p otherQureg are not density matrices\n - if the dimensions of \\p combineQureg and \\p otherQureg do not match\n - if \\p prob is not in [0, 1]\n @author Tyson Jones"]
991    pub fn mixDensityMatrix(combineQureg: Qureg, prob: f64, otherQureg: Qureg);
992}
993extern "C" {
994    #[doc = " Calculates the purity of a density matrix, by the trace of the density matrix squared.\n Returns \\f$\\text{Tr}(\\rho^2)\\f$.\n For a pure state, this =1.\n For a mixed state, the purity is less than 1 and is lower bounded by 1/2^n, where\n n is the number of qubits. The minimum purity is achieved for the maximally mixed state identity/2^n.\n\n This function does not accept state-vectors, which clearly have purity 1.\n\n Note this function will give incorrect results for non-Hermitian Quregs (i.e.\n invalid density matrices), which will disagree with \\f$\\text{Tr}(\\rho^2)\\f$.\n Instead, this function returns \\f$\\sum_{ij} |\\rho_{ij}|^2 \\f$.\n\n @see\n - calcFidelity()\n - calcHilbertSchmidtDistance()\n - calcTotalProb()\n\n @ingroup calc\n @param[in] qureg a density matrix of which to measure the purity\n @return the purity\n @throws invalidQuESTInputError()\n - if either \\p combineQureg or \\p otherQureg are not density matrices\n - if the dimensions of \\p combineQureg and \\p otherQureg do not match\n - if \\p prob is not in [0, 1]\n @author Tyson Jones"]
995    pub fn calcPurity(qureg: Qureg) -> f64;
996}
997extern "C" {
998    #[doc = " Calculates the fidelity of \\p qureg (a state-vector or density matrix) against\n a reference pure state (necessarily a state-vector).\n If \\p qureg is a state-vector, this function computes\n \\f[\n|\\langle \\text{qureg} | \\text{pureState} \\rangle|^2\n \\f]\n If \\p qureg is a density matrix, this function computes\n \\f[\n\\langle \\text{pureState} | \\text{qureg} | \\text{pureState} \\rangle\n \\f]\n In either case, the returned fidelity lies in [0, 1] (assuming both input\n states have valid normalisation). If any of the input \\p Quregs are not\n normalised, this function will return the real component of the correct\n linear algebra calculation.\n\n The number of qubits represented in \\p qureg and \\p pureState must match.\n\n > In the GPU-accelerated cuQuantum backend, this function further assumes that\n > the density matrix \\p qureg is correctly normalised, and otherwise returns the\n > fidelity of the conjugate-transpose of \\p qureg.\n\n @see\n - calcHilbertSchmidtDistance()\n - calcPurity()\n\n @ingroup calc\n @param[in] qureg a density matrix or state vector\n @param[in] pureState a state vector\n @return the fidelity between the input registers\n @throws invalidQuESTInputError()\n - if the second argument (\\p pureState) is not a state-vector\n - if the number of qubits in \\p qureg and \\p pureState do not match\n @author Tyson Jones"]
999    pub fn calcFidelity(qureg: Qureg, pureState: Qureg) -> f64;
1000}
1001extern "C" {
1002    #[doc = " Performs a SWAP gate between \\p qubit1 and \\p qubit2.\n This effects\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & & 1 \\\\\\\n &  1 \\\\\n & & & 1\n \\end{pmatrix}\n \\f]\n on the designated qubits, though is performed internally by three CNOT gates.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 2) {qubit1};\n\\node[draw=none] at (-3.5, 0) {qubit2};\n\n\\draw (-2, 2) -- (2, 2);\n\\draw (0, 2) -- (0, 0);\n\\draw (-2,0) -- (2, 0);\n\n\\draw (-.35,-.35) -- (.35,.35);\n\\draw (-.35,.35) -- (.35,-.35);\n\n\\draw (-.35,-.35 + 2) -- (.35,.35 + 2);\n\\draw (-.35,.35 + 2) -- (.35,-.35 + 2);\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n @see\n - sqrtSwapGate()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] qubit1 qubit to swap\n @param[in] qubit2 other qubit to swap\n @throws invalidQuESTInputError()\n - if either \\p qubit1 or \\p qubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p qubit1 and \\p qubit2 are equal\n @author Tyson Jones"]
1003    pub fn swapGate(qureg: Qureg, qubit1: ::std::os::raw::c_int, qubit2: ::std::os::raw::c_int);
1004}
1005extern "C" {
1006    #[doc = " Apply a multi-controlled multi-target Z rotation, also known as a controlled phase gadget.\n This is the unitary\n \\f[\n    |1\\rangle\\langle 1|^{\\otimes\\, \\text{numControls}} \\; \\otimes \\,\n     \\exp \\left( - i \\, \\frac{\\theta}{2} \\; \\bigotimes_{j}^{\\text{numTargets}} Z_j\\right)\n     \\;\\;+\\;\\; \\sum\\limits_{k=0}^{2^{\\,\\text{numControls}} - 2} |k\\rangle\\langle k| \\otimes \\text{I}\n \\f]\n where the Pauli Z gates operate upon the qubits in `targetQubits`, and cause\n rotations of \\f$\\theta =\\f$ \\p angle.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-4, 1) {targets};\n\\node[draw=none] at (-4, 5) {controls};\n\n\\node[draw=none] at (0, 8) {$\\vdots$};\n\\draw (0, 7) -- (0, 6);\n\n\\draw (-2.5, 6) -- (2.5, 6);\n\\draw[fill=black] (0, 6) circle (.2);\n\\draw (0, 6) -- (0, 4);\n\n\\draw (-2.5, 4) -- (2.5, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2.5,0) -- (-1.5, 0);\n\\draw (1.5, 0) -- (2.5, 0);\n\\draw (-2.5,2) -- (-1.5, 2);\n\\draw (1.5, 2) -- (2.5, 2);\n\\draw (-1.5,-1)--(-1.5,3)--(1.5,3)--(1.5,-1);\n\\node[draw=none] at (0, -1) {$\\vdots$};\n\n% below is broken in Tikzjax rendering...\n%    \\node[draw=none] at (0, 1) {$e^{-i\\frac{\\theta}{2}Z^{\\otimes}}$};\n% so we sadly replace it with:\n\\node[draw=none] at (0, 1) {$\\exp(\\dots)$};\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n > All qubits not appearing in \\p targetQubits and \\p controlQubits are assumed to receive the identity operator.\n\n This has the effect of premultiplying all amplitudes (for which the control qubits are `1`)\n with \\f$\\exp(\\pm i \\theta/2)\\f$, where the sign is determined by the parity of\n the target qubits for that amplitude.\n\n @see\n - multiControlledMultiRotatePauli()\n - multiRotatePauli()\n - multiRotateZ()\n - controlledRotateZ()\n - rotateZ()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits list of the indices of qubits to control upon\n @param[in] numControls length of length `controlQubits`\n @param[in] targetQubits a list of the indices of the target qubits\n @param[in] numTargets length of list `targetQubits`\n @param[in] angle the angle by which the multi-qubit state is rotated around the Z axis\n @throws invalidQuESTInputError()\n - if any qubit in \\p controlQubits and \\p targetQubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p controlQubits or \\p targetQubits contain any repetitions\n - if any qubit in \\p controlQubits is also in \\p targetQubits (and vice versa)\n - if \\p numTargets <b>< 1</b>\n - if \\p numControls <b>< 1</b> (use multiRotateZ() for no controls)\n @throws segmentation-fault\n - if \\p controlQubits contains fewer elements than \\p numControls\n - if \\p targetQubits contains fewer elements than \\p numTargets\n @author Tyson Jones"]
1007    pub fn multiControlledMultiRotateZ(
1008        qureg: Qureg,
1009        controlQubits: *mut ::std::os::raw::c_int,
1010        numControls: ::std::os::raw::c_int,
1011        targetQubits: *mut ::std::os::raw::c_int,
1012        numTargets: ::std::os::raw::c_int,
1013        angle: f64,
1014    );
1015}
1016extern "C" {
1017    #[doc = " Apply a multi-controlled multi-target multi-Pauli rotation, also known as a\n controlled Pauli gadget.\n This is the unitary\n \\f[\n    |1\\rangle\\langle 1|^{\\otimes\\, \\text{numControls}} \\; \\otimes \\,\n     \\exp \\left( - i \\, \\frac{\\theta}{2} \\; \\bigotimes_{j}^{\\text{numTargets}} \\hat{\\sigma}_j\\right)\n     \\;\\;+\\;\\; \\sum\\limits_{k=0}^{2^{\\,\\text{numControls}} - 2} |k\\rangle\\langle k| \\otimes \\text{I}\n \\f]\n where \\f$\\hat{\\sigma}_j\\f$ are the Pauli operators (::pauliOpType) in `targetPaulis`, which operate\n upon the corresponding qubits in `targetQubits`.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-4, 1) {targets};\n\\node[draw=none] at (-4, 5) {controls};\n\n\\node[draw=none] at (0, 8) {$\\vdots$};\n\\draw (0, 7) -- (0, 6);\n\n\\draw (-2.5, 6) -- (2.5, 6);\n\\draw[fill=black] (0, 6) circle (.2);\n\\draw (0, 6) -- (0, 4);\n\n\\draw (-2.5, 4) -- (2.5, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2.5,0) -- (-1.5, 0);\n\\draw (1.5, 0) -- (2.5, 0);\n\\draw (-2.5,2) -- (-1.5, 2);\n\\draw (1.5, 2) -- (2.5, 2);\n\\draw (-1.5,-1)--(-1.5,3)--(1.5,3)--(1.5,-1);\n\n\\node[draw=none] at (0, -1) {$\\vdots$};\n\n% below is broken in Tikzjax rendering\n%    \\node[draw=none] at (0, 1) {$e^{-i\\frac{\\theta}{2} \\bigotimes\\limits_j \\hat{\\sigma}_j}$};\n% so we sadly replace it with:\n\\node[draw=none] at (0, 1) {$\\exp(\\dots)$};\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n > All qubits not appearing in \\p targetQubits and \\p controlQubits are assumed to receive the identity operator.\n\n For example:\n ```\n     int numCtrls = 1;\n     int numTargs = 4;\n     int ctrls[] = {4};\n     int targs[] = {0,1,2,3};\n\n     pauliOpType paulis[] = {PAULI_X, PAULI_Y, PAULI_Z, PAULI_I};\n\n     multiControlledMultiRotatePauli(\n         qureg, ctrls, numCtrls, targs, paulis, numTargs, 0.1);\n ```\n effects\n \\f[\n    |1\\rangle\\langle 1 | \\otimes \\exp\\left( -i \\, (0.1/2) \\, X_0 \\, Y_1 \\, Z_2 \\right) \\, \\text{I}_3\n    \\;\\; + \\;\\; |0\\rangle\\langle 0| \\otimes \\text{I}^{\\otimes 4}\n \\f]\n on \\p qureg, where unspecified qubits (along with those targeted by `PAULI_I`) are\n assumed to receive the identity operator (excluded from exponentiation).\n\n > This means specifying `PAULI_I` does *not* induce a global phase factor \\f$\\exp(-i \\theta/2)\\f$.\n > Hence, if all \\p targetPaulis are identity, then this function does nothing to \\p qureg.\n > Specifying `PAULI_I` on a qubit is superfluous but allowed for convenience.\n\n This function effects the controlled Pauli gadget by first (controlled)\n rotating the qubits which are targeted with either `X` or `Y` into alternate basis,\n performing multiControlledMultiRotateZ() on all target qubits, then restoring\n the original basis.\n\n @see\n - multiControlledMultiRotateZ()\n - multiRotatePauli()\n - multiRotateZ()\n - rotateX()\n - rotateY()\n - rotateZ()\n - rotateAroundAxis()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits list of the indices of qubits to control upon\n @param[in] numControls length of length `controlQubits`\n @param[in] targetQubits a list of the indices of the target qubits\n @param[in] targetPaulis a list of the Pauli operators around which to rotate the target qubits\n @param[in] numTargets length of list `targetQubits`\n @param[in] angle the angle by which the multi-qubit state is rotated around the Z axis\n @throws invalidQuESTInputError()\n - if any qubit in \\p controlQubits and \\p targetQubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p controlQubits or \\p targetQubits contain any repetitions\n - if any qubit in \\p controlQubits is also in \\p targetQubits (and vice versa)\n - if \\p numTargets <b>< 1</b>\n - if \\p numControls <b>< 1</b> (use multiRotateZ() for no controls)\n - if any element of \\p targetPaulis is not one of `PAULI_I`, `PAULI_X`, `PAULI_Y`, `PAULI_Z`\n @throws segmentation-fault\n - if \\p controlQubits contains fewer elements than \\p numControls\n - if \\p targetQubits contains fewer elements than \\p numTargets\n - if \\p targetPaulis contains fewer elements than \\p numTargets\n @author Tyson Jones"]
1018    pub fn multiControlledMultiRotatePauli(
1019        qureg: Qureg,
1020        controlQubits: *mut ::std::os::raw::c_int,
1021        numControls: ::std::os::raw::c_int,
1022        targetQubits: *mut ::std::os::raw::c_int,
1023        targetPaulis: *mut pauliOpType,
1024        numTargets: ::std::os::raw::c_int,
1025        angle: f64,
1026    );
1027}
1028extern "C" {
1029    #[doc = " Computes the expected value of a product of Pauli operators.\n Letting \\f$ \\sigma = \\otimes_j \\hat{\\sigma}_j \\f$ be the operators indicated by \\p pauliCodes\n and acting on qubits \\p targetQubits, this function computes \\f$ \\langle \\psi | \\sigma | \\psi \\rangle \\f$\n if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(\\sigma \\rho) \\f$\n if \\p qureg = \\f$ \\rho \\f$ is a density matrix.\n\n \\p pauliCodes is an array of length \\p numTargets which specifies which Pauli operators to\n enact on the corresponding qubits in \\p targetQubits, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,\n 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. The target qubits must be unique, and at most \\p qureg.numQubitsRepresented\n may be specified. For example, on a 7-qubit state-vector,\n ```\n     calcExpecPauliProd(qureg, {4,5,6}, {PAULI_X, PAULI_I, PAULI_Z}, 3, workspace);\n ```\n will compute \\f$ \\langle \\psi | I I I I X I Z | \\psi \\rangle \\f$ (where in this notation, the left-most operator\n applies to the least-significant qubit, i.e. that with index 0).\n\n \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions\n (number of represented qubits) as \\p qureg, and is used as working space. When this function returns, \\p qureg\n will be unchanged and \\p workspace will be set to \\f$ \\sigma | \\psi \\rangle \\f$ (if \\p qureg is a state-vector)\n or \\f$ \\sigma \\rho \\f$ (if \\p qureg is a density matrix). NOTE that this last quantity is NOT the result of applying\n the paulis as unitaries, \\f$ \\sigma^\\dagger \\rho \\sigma \\f$, but is instead the result of their direct\n multiplication with the density matrix. It is therefore itself not a valid density matrix.\n\n This function works by cloning the \\p qureg state into \\p workspace, applying the specified\n Pauli operators to \\p workspace then computing its inner product with \\p qureg (for state-vectors)\n or its trace (for density matrices). It therefore should scale linearly in time with the number of\n specified non-identity Pauli operators, which is bounded by the number of represented qubits.\n\n @see\n - calcExpecDiagonalOp()\n - calcExpecPauliSum()\n - calcExpecPauliHamil()\n\n @ingroup calc\n @param[in] qureg the register of which to find the expected value, which is unchanged by this function\n @param[in] targetQubits a list of the indices of the target qubits\n @param[in] pauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)\n      to apply to the corresponding qubits in \\p targetQubits\n @param[in] numTargets number of target qubits, i.e. the length of \\p targetQubits and \\p pauliCodes\n @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified\n      to be the result of multiplying the state with the pauli operators\n @throws invalidQuESTInputError()\n - if \\p numTargets is outside [1, \\p qureg.numQubitsRepresented])\n - if any qubit in \\p targetQubits is outside [0, \\p qureg.numQubitsRepresented))\n - if any qubit in \\p targetQubits is repeated\n - if any code in \\p pauliCodes is not in {0,1,2,3}\n - if \\p workspace is not of the same type and dimensions as \\p qureg\n @author Tyson Jones"]
1030    pub fn calcExpecPauliProd(
1031        qureg: Qureg,
1032        targetQubits: *mut ::std::os::raw::c_int,
1033        pauliCodes: *mut pauliOpType,
1034        numTargets: ::std::os::raw::c_int,
1035        workspace: Qureg,
1036    ) -> f64;
1037}
1038extern "C" {
1039    #[doc = " Computes the expected value of a sum of products of Pauli operators.\n Let \\f$ H = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$ be\n the operators indicated by \\p allPauliCodes (where \\f$ c_i \\in \\f$ \\p termCoeffs\n and \\f$ N = \\f$ \\p qureg.numQubitsRepresented).\n This function computes \\f$ \\langle \\psi | H | \\psi \\rangle \\f$\n if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(H \\rho) =\\text{Trace}(\\rho H) \\f$\n if \\p qureg = \\f$ \\rho \\f$ is a density matrix.\n\n \\p allPauliCodes is an array of length \\p numSumTerms*\\p qureg.numQubitsRepresented\n which specifies which Pauli operators to apply, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,\n 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. For each sum term, a Pauli operator must be specified for\n EVERY qubit in \\p qureg; each set of \\p numSumTerms operators will be grouped into a product.\n \\p termCoeffs is an arrray of length \\p numSumTerms containing the term coefficients.\n For example, on a 3-qubit state-vector,\n ```\n     int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};\n     qreal coeffs[2] = {1.5, -3.6};\n     calcExpecPauliSum(qureg, paulis, coeffs, 2, workspace);\n ```\n 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\n applies to the least-significant qubit, i.e. that with index 0).\n\n \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions\n (number of represented qubits) as \\p qureg, and is used as working space. When this function returns, \\p qureg\n will be unchanged and \\p workspace will be set to \\p qureg pre-multiplied with the final Pauli product.\n NOTE that if \\p qureg is a density matrix, \\p workspace will become \\f$ \\hat{\\sigma} \\rho \\f$\n which is itself not a density matrix (it is distinct from \\f$ \\hat{\\sigma} \\rho \\hat{\\sigma}^\\dagger \\f$).\n\n This function works by cloning the \\p qureg state into \\p workspace, applying each of the specified\n Pauli products to \\p workspace (one Pauli operation at a time), then computing its inner product with \\p qureg (for state-vectors)\n or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions.\n It therefore should scale linearly in time with the total number of non-identity specified Pauli operators.\n\n @see\n - calcExpecDiagonalOp()\n - calcExpecPauliProd()\n - calcExpecPauliHamil()\n\n @ingroup calc\n @param[in] qureg the register of which to find the expected value, which is unchanged by this function\n @param[in] allPauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)\n      of all Paulis involved in the products of terms. A Pauli must be specified for each qubit\n      in the register, in every term of the sum.\n @param[in] termCoeffs The coefficients of each term in the sum of Pauli products\n @param[in] numSumTerms The total number of Pauli products specified\n @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified\n      to be the result of multiplying the state with the final specified Pauli product\n @throws invalidQuESTInputError()\n - if any code in \\p allPauliCodes is not in {0,1,2,3}\n - if \\p numSumTerms <= 0,\n - if \\p workspace is not of the same type and dimensions as \\p qureg\n @author Tyson Jones"]
1040    pub fn calcExpecPauliSum(
1041        qureg: Qureg,
1042        allPauliCodes: *mut pauliOpType,
1043        termCoeffs: *mut f64,
1044        numSumTerms: ::std::os::raw::c_int,
1045        workspace: Qureg,
1046    ) -> f64;
1047}
1048extern "C" {
1049    #[doc = " Computes the expected value of \\p qureg under Hermitian operator \\p hamil.\n Represent \\p hamil as \\f$ H = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$\n  (where \\f$ c_i \\in \\f$ \\p hamil.termCoeffs and \\f$ N = \\f$ \\p hamil.numQubits).\n This function computes \\f$ \\langle \\psi | H | \\psi \\rangle \\f$\n if \\p qureg = \\f$ \\psi \\f$ is a state-vector, and computes \\f$ \\text{Trace}(H \\rho) =\\text{Trace}(\\rho H) \\f$\n if \\p qureg = \\f$ \\rho \\f$ is a density matrix.\n\n This function is merely an encapsulation of calcExpecPauliSum() - refer to the doc\n there for an elaboration.\n\n \\p workspace must be a register with the same type (state-vector vs density matrix) and dimensions\n (number of represented qubits) as \\p qureg and \\p hamil, and is used as working space.\n When this function returns, \\p qureg  will be unchanged and \\p workspace will be set to\n \\p qureg pre-multiplied with the final Pauli product in \\p hamil.\n NOTE that if \\p qureg is a density matrix, \\p workspace will become \\f$ \\hat{\\sigma} \\rho \\f$\n which is itself not a density matrix (it is distinct from \\f$ \\hat{\\sigma} \\rho \\hat{\\sigma}^\\dagger \\f$).\n\n This function works by cloning the \\p qureg state into \\p workspace, applying each of the specified\n 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)\n or its trace (for density matrices) multiplied with the corresponding coefficient, and summing these contributions.\n It therefore should scale linearly in time with the total number of non-identity specified Pauli operators.\n\n @see\n - createPauliHamil()\n - calcExpecDiagonalOp()\n - calcExpecPauliSum()\n - calcExpecPauliProd()\n\n @ingroup calc\n @param[in] qureg the register of which to find the expected value, which is unchanged by this function\n @param[in] hamil a \\p PauliHamil created with createPauliHamil() or createPauliHamilFromFile()\n @param[in,out] workspace a working-space qureg with the same dimensions as \\p qureg, which is modified\n      to be the result of multiplying the state with the final specified Pauli product\n @throws invalidQuESTInputError()\n - if any code in \\p hamil.pauliCodes is not a valid Pauli code\n - if \\p hamil.numSumTerms <= 0\n - if \\p workspace is not of the same type and dimensions as \\p qureg and \\p hamil\n @author Tyson Jones"]
1050    pub fn calcExpecPauliHamil(qureg: Qureg, hamil: PauliHamil, workspace: Qureg) -> f64;
1051}
1052extern "C" {
1053    #[doc = " Apply a general two-qubit unitary (including a global phase factor).\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target2};\n\\node[draw=none] at (-3.5, 2) {target1};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;\n\\node[draw=none] at (0, 1) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that\n a row in \\p u is dotted with the vector\n \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$\n\n For example,\n ```\n     twoQubitUnitary(qureg, a, b, u);\n ```\n will invoke multiplication\n \\f[\n \\begin{pmatrix}\n u_{00} & u_{01} & u_{02} & u_{03} \\\\\n u_{10} & u_{11} & u_{12} & u_{13} \\\\\n u_{20} & u_{21} & u_{22} & u_{23} \\\\\n u_{30} & u_{31} & u_{32} & u_{33}\n \\end{pmatrix}\n \\begin{pmatrix}\n |ba\\rangle = |00\\rangle \\\\\n |ba\\rangle = |01\\rangle \\\\\n |ba\\rangle = |10\\rangle \\\\\n |ba\\rangle = |11\\rangle\n \\end{pmatrix}\n \\f]\n\n The passed ::ComplexMatrix4 must be unitary, otherwise an error is thrown.\n > Use applyMatrix4() to left-multiply a non-unitary ::ComplexMatrix4.\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q/4 nodes.\n\n @see\n - ::ComplexMatrix4\n - controlledTwoQubitUnitary()\n - multiControlledTwoQubitUnitary()\n - multiQubitUnitary()\n - applyMatrix4()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u\n @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p targetQubit1 equals \\p targetQubit2\n - if matrix \\p u is not unitary\n - if each node cannot fit 4 amplitudes in distributed mode\n @author Tyson Jones"]
1054    pub fn twoQubitUnitary(
1055        qureg: Qureg,
1056        targetQubit1: ::std::os::raw::c_int,
1057        targetQubit2: ::std::os::raw::c_int,
1058        u: ComplexMatrix4,
1059    );
1060}
1061extern "C" {
1062    #[doc = " Apply a general controlled two-qubit unitary (including a global phase factor).\n The given unitary is applied to the target amplitudes where the control qubit has value 1.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\n & & 1 \\\\\n & & & 1 \\\\\n & & & & u_{00} & u_{01} & u_{02} & u_{03} \\\\\n & & & & u_{10} & u_{11} & u_{12} & u_{13} \\\\\n & & & & u_{20} & u_{21} & u_{22} & u_{23} \\\\\n & & & & u_{30} & u_{31} & u_{32} & u_{33}\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that\n a row in \\p u is dotted with the vector\n \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$\n\n The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target1};\n\\node[draw=none] at (-3.5, 2) {target2};\n\\node[draw=none] at (-3.5, 4) {control};\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;\n\\node[draw=none] at (0, 1) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q/4 nodes.\n\n @see\n - ::ComplexMatrix4\n - multiControlledTwoQubitUnitary()\n - multiQubitUnitary()\n - unitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubit the control qubit which must be in state 1 to effect the given unitary\n @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u\n @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p controlQubit, \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if any of \\p controlQubit, \\p targetQubit1 and \\p targetQubit2 are equal\n - if matrix \\p u is not unitary\n  - if each node cannot fit 4 amplitudes in distributed mode.\n @author Tyson Jones"]
1063    pub fn controlledTwoQubitUnitary(
1064        qureg: Qureg,
1065        controlQubit: ::std::os::raw::c_int,
1066        targetQubit1: ::std::os::raw::c_int,
1067        targetQubit2: ::std::os::raw::c_int,
1068        u: ComplexMatrix4,
1069    );
1070}
1071extern "C" {
1072    #[doc = " Apply a general multi-controlled two-qubit unitary (including a global phase factor).\n Any number of control qubits can be specified, and if all have value 1,\n the given unitary is applied to the target qubit.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & u_{00} & u_{01} & u_{02} & u_{03} \\\\\n & & & u_{10} & u_{11} & u_{12} & u_{13} \\\\\n & & & u_{20} & u_{21} & u_{22} & u_{23} \\\\\n & & & u_{30} & u_{31} & u_{32} & u_{33}\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that\n a row in \\p u is dotted with the vector\n \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$\n\n The passed 4x4 ComplexMatrix must be unitary, otherwise an error is thrown.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 0) {target1};\n\\node[draw=none] at (-3.5, 2) {target2};\n\\node[draw=none] at (-3.5, 5) {controls};\n\n\\node[draw=none] at (0, 8) {$\\vdots$};\n\\draw (0, 7) -- (0, 6);\n\n\\draw (-2, 6) -- (2, 6);\n\\draw[fill=black] (0, 6) circle (.2);\n\\draw (0, 6) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1)--cycle;\n\\node[draw=none] at (0, 1) {U};\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q/4 nodes.\n\n @see\n - ::ComplexMatrix4\n - twoQubitUnitary()\n - controlledTwoQubitUnitary()\n - multiQubitUnitary()\n - unitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] controlQubits the control qubits which all must be in state 1 to effect the given unitary\n @param[in] numControlQubits the number of control qubits\n @param[in] targetQubit1 first target qubit, treated as least significant in \\p u\n @param[in] targetQubit2 second target qubit, treated as most significant in \\p u\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p targetQubit1 equals \\p targetQubit2\n - if any qubit in \\p controlQubits is outside [0, \\p qureg.numQubitsRepresented)\n - if \\p controlQubits are not unique\n - if either \\p targetQubit1 and \\p targetQubit2 are in \\p controlQubits\n - if matrix \\p u is not unitary\n - if each node cannot fit 4 amplitudes in distributed mode\n @author Tyson Jones"]
1073    pub fn multiControlledTwoQubitUnitary(
1074        qureg: Qureg,
1075        controlQubits: *mut ::std::os::raw::c_int,
1076        numControlQubits: ::std::os::raw::c_int,
1077        targetQubit1: ::std::os::raw::c_int,
1078        targetQubit2: ::std::os::raw::c_int,
1079        u: ComplexMatrix4,
1080    );
1081}
1082extern "C" {
1083    #[doc = " Apply a general multi-qubit unitary (including a global phase factor) with any number of target qubits.\n\n The first target qubit in \\p targs is treated as \\b least significant in \\p u.\n For example,\n ```\n     multiQubitUnitary(qureg, (int []) {a, b, c}, 3, u);\n ```\n will invoke multiplication\n \\f[\n \\begin{pmatrix}\n u_{00} & u_{01} & u_{02} & u_{03} & u_{04} & u_{05} & u_{06} & u_{07} \\\\\n u_{10} & u_{11} & u_{12} & u_{13} & u_{14} & u_{15} & u_{16} & u_{17} \\\\\n u_{20} & u_{21} & u_{22} & u_{23} & u_{24} & u_{25} & u_{26} & u_{27} \\\\\n u_{30} & u_{31} & u_{32} & u_{33} & u_{34} & u_{35} & u_{36} & u_{37} \\\\\n u_{40} & u_{41} & u_{42} & u_{43} & u_{44} & u_{45} & u_{46} & u_{47} \\\\\n u_{50} & u_{51} & u_{52} & u_{53} & u_{54} & u_{55} & u_{56} & u_{57} \\\\\n u_{60} & u_{61} & u_{62} & u_{63} & u_{64} & u_{65} & u_{66} & u_{67} \\\\\n u_{70} & u_{71} & u_{72} & u_{73} & u_{74} & u_{75} & u_{76} & u_{77} \\\\\n \\end{pmatrix}\n \\begin{pmatrix}\n |cba\\rangle = |000\\rangle \\\\\n |cba\\rangle = |001\\rangle \\\\\n |cba\\rangle = |010\\rangle \\\\\n |cba\\rangle = |011\\rangle \\\\\n |cba\\rangle = |100\\rangle \\\\\n |cba\\rangle = |101\\rangle \\\\\n |cba\\rangle = |110\\rangle \\\\\n |cba\\rangle = |111\\rangle\n \\end{pmatrix}\n \\f]\n\n The passed ComplexMatrix must be unitary and be a compatible size with the specified number of\n target qubits, otherwise an error is thrown.\n > To effect a non-unitary ::ComplexMatrixN, use applyGateMatrixN().\n\n > To left-multiply a non-unitary ::ComplexMatrixN, use applyMatrixN().\n\n > To specify only the diagonal elements of the matrix, use diagonalUnitary().\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 1) {targets};\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);\n\\node[draw=none] at (0, 1) {U};\n\\node[draw=none] at (0, -1) {$\\vdots$};\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,\n and store these in the runtime stack.\n Using t threads, the total memory overhead of this function is t*2^\\p numTargs.\n For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault\n (e.g. on a 1 MiB stack).\n\n Note too that in distributed mode, this routine requires that each node contains\n at least 2^\\p numTargs amplitudes in the register. This means an q-qubit register (state vector or density matrix)\n can be distributed by at most 2^q / 2^\\p numTargs nodes.\n\n @see\n - createComplexMatrixN()\n - controlledMultiQubitUnitary()\n - multiControlledMultiQubitUnitary()\n - applyGateMatrixN()\n - applyMatrixN()\n - twoQubitUnitary()\n - unitary()\n - compactUnitary()\n - diagonalUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targs a list of the target qubits, ordered least significant to most in \\p u\n @param[in] numTargs the number of target qubits\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p targs are not unique\n - if matrix \\p u is not unitary\n - if \\p u is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @author Tyson Jones"]
1084    pub fn multiQubitUnitary(
1085        qureg: Qureg,
1086        targs: *mut ::std::os::raw::c_int,
1087        numTargs: ::std::os::raw::c_int,
1088        u: ComplexMatrixN,
1089    );
1090}
1091extern "C" {
1092    #[doc = " Apply a general controlled multi-qubit unitary (including a global phase factor).\n One control and any number of target qubits can be specified.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & 1 \\\\\n & & & 1 \\\\\n & & & & u_{00} & u_{01} & \\dots  \\\\\n & & & & u_{10} & u_{11} & \\dots \\\\\n & & & & \\vdots & \\vdots & \\ddots\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n The target qubits in \\p targs are treated as ordered least significant\n to most significant in \\p u.\n\n The passed ComplexMatrix must be unitary and be a compatible size with the specified number of\n target qubits, otherwise an error is thrown.\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 1) {targets};\n\\node[draw=none] at (-3.5, 4) {control};\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);\n\\node[draw=none] at (0, 1) {U};\n\\node[draw=none] at (0, -1) {$\\vdots$};\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,\n and store these in the runtime stack.\n Using t threads, the total memory overhead of this function is t*2^\\p numTargs.\n For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault\n (e.g. on a 1 MiB stack).\n\n Note too that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q / 2^\\p numTargs nodes.\n\n @see\n - createComplexMatrixN()\n - multiQubitUnitary()\n - multiControlledMultiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] ctrl the control qubit\n @param[in] targs a list of the target qubits, ordered least to most significant\n @param[in] numTargs the number of target qubits\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if \\p ctrl or any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p targs are not unique\n - if \\p targs contains \\p ctrl\n - if matrix \\p u is not unitary\n - if matrix \\p u is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @author Tyson Jones"]
1093    pub fn controlledMultiQubitUnitary(
1094        qureg: Qureg,
1095        ctrl: ::std::os::raw::c_int,
1096        targs: *mut ::std::os::raw::c_int,
1097        numTargs: ::std::os::raw::c_int,
1098        u: ComplexMatrixN,
1099    );
1100}
1101extern "C" {
1102    #[doc = " Apply a general multi-controlled multi-qubit unitary (including a global phase factor).\n Any number of control and target qubits can be specified.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & u_{00} & u_{01} & \\dots  \\\\\n & & & u_{10} & u_{11} & \\dots \\\\\n & & & \\vdots & \\vdots & \\ddots\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n The target qubits in \\p targs are treated as ordered least significant\n to most significant in \\p u.\n\n The passed ::ComplexMatrixN must be unitary and be a compatible size with the specified number of\n target qubits, otherwise an error is thrown.\n > To left-multiply a non-unitary ::ComplexMatrixN, including control qubits,\n > use applyMultiControlledMatrixN()\n\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\node[draw=none] at (-3.5, 1) {targets};\n\\node[draw=none] at (-3.5, 5) {controls};\n\n\\node[draw=none] at (0, 8) {$\\vdots$};\n\\draw (0, 7) -- (0, 6);\n\n\\draw (-2, 6) -- (2, 6);\n\\draw[fill=black] (0, 6) circle (.2);\n\\draw (0, 6) -- (0, 4);\n\n\\draw (-2, 4) -- (2, 4);\n\\draw[fill=black] (0, 4) circle (.2);\n\\draw(0, 4) -- (0, 3);\n\n\\draw (-2,0) -- (-1, 0);\n\\draw (1, 0) -- (2, 0);\n\\draw (-2,2) -- (-1, 2);\n\\draw (1, 2) -- (2, 2);\n\\draw (-1,-1)--(-1,3)--(1,3)--(1,-1);\n\\node[draw=none] at (0, 1) {U};\n\\node[draw=none] at (0, -1) {$\\vdots$};\n\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n\n Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,\n and store these in the runtime stack.\n Using t threads, the total memory overhead of this function is t*2^\\p numTargs.\n For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault\n (e.g. on a 1 MiB stack).\n\n Note that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q / 2^\\p numTargs nodes.\n\n @see\n - createComplexMatrixN()\n - applyMultiControlledGateMatrixN()\n - applyMultiControlledMatrixN()\n - multiControlledMultiQubitNot()\n - controlledMultiQubitUnitary()\n - multiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] ctrls a list of the control qubits\n @param[in] numCtrls the number of control qubits\n @param[in] targs a list of the target qubits, ordered least to most significant\n @param[in] numTargs the number of target qubits\n @param[in] u unitary matrix to apply\n @throws invalidQuESTInputError()\n - if any qubit in \\p ctrls and \\p targs is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p ctrls or \\p targs contain any repetitions\n - if any qubit in \\p ctrls is also in \\p targs (and vice versa)\n - if \\p numTargs <b>< 1</b>\n - if \\p numCtrls <b>< 1</b> (use multiQubitUnitary() for no controls)\n - if matrix \\p u is not unitary\n - if matrix \\p u is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @throws segmentation-fault\n - if \\p ctrls contains fewer elements than \\p numCtrls\n - if \\p targs contains fewer elements than \\p numTargs\n @author Tyson Jones"]
1103    pub fn multiControlledMultiQubitUnitary(
1104        qureg: Qureg,
1105        ctrls: *mut ::std::os::raw::c_int,
1106        numCtrls: ::std::os::raw::c_int,
1107        targs: *mut ::std::os::raw::c_int,
1108        numTargs: ::std::os::raw::c_int,
1109        u: ComplexMatrixN,
1110    );
1111}
1112extern "C" {
1113    #[doc = " Apply a general single-qubit Kraus map to a density matrix, as specified by at most\n four Kraus operators, \\f$K_i\\f$ (\\p ops). A Kraus map is also referred to as\n a \"operator-sum representation\" of a quantum channel, and enables the simulation of\n general single-qubit noise process,\n by effecting\n \\f[\n\\rho \\to \\sum\\limits_i^{\\text{numOps}} K_i \\rho K_i^\\dagger\n \\f]\n\n The Kraus map must be completely positive and trace preserving, which constrains each\n \\f$ K_i \\f$ in \\p ops by\n \\f[\n\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I\n \\f]\n where \\f$ I \\f$ is the identity matrix. Use mixNonTPKrausMap() to relax this condition.\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-2) numTargs nodes.\n\n @see\n - ::ComplexMatrix2\n - mixNonTPKrausMap()\n - mixTwoQubitKrausMap()\n - mixMultiQubitKrausMap()\n - mixDephasing()\n - mixDepolarising()\n - mixDamping()\n - mixPauli()\n - mixDensityMatrix()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] target the target qubit of the map\n @param[in] ops an array of at most 4 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= 4.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p target is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p numOps is outside [1, 4]\n - if \\p ops do not create a completely positive, trace preserving map\n - if a node cannot fit 4 amplitudes in distributed mode\n @author Balint Koczor\n @author Tyson Jones (refactored, doc)"]
1114    pub fn mixKrausMap(
1115        qureg: Qureg,
1116        target: ::std::os::raw::c_int,
1117        ops: *mut ComplexMatrix2,
1118        numOps: ::std::os::raw::c_int,
1119    );
1120}
1121extern "C" {
1122    #[doc = " Apply a general two-qubit Kraus map to a density matrix, as specified by at most\n sixteen Kraus operators. A Kraus map is also referred to as a \"operator-sum representation\"\n of a quantum channel. This allows one to simulate a general two-qubit noise process.\n\n The Kraus map must be completely positive and trace preserving, which constrains each\n \\f$ K_i \\f$ in \\p ops by\n \\f[\n\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I\n \\f]\n where \\f$ I \\f$ is the identity matrix. Use mixNonTPTwoQubitKrausMap() to relax this\n this condition.\n\n \\p targetQubit1 is treated as the \\p least significant qubit in each op in \\p ops.\n\n Note that in distributed mode, this routine requires that each node contains at least 16 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-4) numTargs nodes.\n\n @see\n - ::ComplexMatrix4\n - mixNonTPTwoQubitKrausMap()\n - mixMultiQubitKrausMap()\n - mixKrausMap()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] target1 the least significant target qubit in \\p ops\n @param[in] target2 the most significant target qubit in \\p ops\n @param[in] ops an array of at most 16 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= 16.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if either \\p target1 or \\p target2 is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p target1 = \\p target2\n - if \\p numOps is outside [1, 16]\n - if \\p ops do not create a completely positive, trace preserving map\n - if a node cannot fit 16 amplitudes in distributed mode\n @author Balint Koczor\n @author Tyson Jones (refactored, doc)"]
1123    pub fn mixTwoQubitKrausMap(
1124        qureg: Qureg,
1125        target1: ::std::os::raw::c_int,
1126        target2: ::std::os::raw::c_int,
1127        ops: *mut ComplexMatrix4,
1128        numOps: ::std::os::raw::c_int,
1129    );
1130}
1131extern "C" {
1132    #[doc = " Apply a general N-qubit Kraus map to a density matrix, as specified by at most (2N)^2\n Kraus operators. This allows one to simulate a general noise process.\n\n The Kraus map must be completely positive and trace preserving, which constrains each\n \\f$ K_i \\f$ in \\p ops by\n \\f[\n\\sum \\limits_i^{\\text{numOps}} K_i^\\dagger K_i = I\n \\f]\n where \\f$ I \\f$ is the identity matrix. Use mixNonTPMultiQubitKrausMap() to relax\n this condition.\n\n The first qubit in \\p targets is treated as the \\p least significant qubit in each op in \\p ops.\n\n Note that in distributed mode, this routine requires that each node contains at least (2N)^2 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-2)/N^2 nodes.\n\n Note too that this routine internally creates a 'superoperator'; a complex matrix of dimensions\n 2^(2*numTargets) by 2^(2*numTargets). Therefore, invoking this function incurs,\n for numTargs={1,2,3,4,5, ...}, an additional memory overhead of (at double-precision)\n {0.25 KiB, 4 KiB, 64 KiB, 1 MiB, 16 MiB, ...} (respectively).\n At quad precision (usually 10 B per number, but possibly 16 B due to alignment),\n this costs at most double the amount of memory.\n For numTargets < 4, this superoperator will be created in the runtime\n stack. For numTargs >= 4, the superoperator will be allocated in the heap and\n therefore this routine may suffer an anomalous slowdown.\n\n @see\n - createComplexMatrixN()\n - initComplexMatrixN()\n - mixNonTPMultiQubitKrausMap()\n - mixKrausMap()\n - mixTwoQubitKrausMap()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] targets a list of target qubit indices, the first of which is treated as least significant in each op in \\p ops\n @param[in] numTargets the length of \\p targets\n @param[in] ops an array of at most (2N)^2 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= (2N)^2.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if any target in \\p targets is outside of [0, \\p qureg.numQubitsRepresented)\n - if any qubit in \\p targets is repeated\n - if \\p numOps is outside [1, (2 \\p numTargets)^2]\n - if any ComplexMatrixN in \\p ops does not have op.numQubits == \\p numTargets\n - if \\p ops do not create a completely positive, trace preserving map\n - if a node cannot fit (2N)^2 amplitudes in distributed mode\n @author Tyson Jones\n @author Balint Koczor"]
1133    pub fn mixMultiQubitKrausMap(
1134        qureg: Qureg,
1135        targets: *mut ::std::os::raw::c_int,
1136        numTargets: ::std::os::raw::c_int,
1137        ops: *mut ComplexMatrixN,
1138        numOps: ::std::os::raw::c_int,
1139    );
1140}
1141extern "C" {
1142    #[doc = " Apply a general non-trace-preserving single-qubit Kraus map to a density matrix,\n as specified by at most four operators, \\f$K_i\\f$ (\\p ops).\n This effects\n \\f[\n\\rho \\to \\sum\\limits_i^{\\text{numOps}} K_i \\rho K_i^\\dagger\n \\f]\n where \\f$K_i\\f$ are permitted to be any matrix. This means the density matrix\n can enter a non-physical state.\n\n Use mixKrausMap() to enforce that the channel is trace preserving and completely positive.\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-2) numTargs nodes.\n\n @see\n - ::ComplexMatrix2\n - mixKrausMap()\n - mixNonTPTwoQubitKrausMap()\n - mixNonTPMultiQubitKrausMap()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] target the target qubit of the map\n @param[in] ops an array of at most 4 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= 4.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if \\p target is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p numOps is outside [1, 4]\n - if a node cannot fit 4 amplitudes in distributed mode\n @author Tyson Jones\n @author Balint Koczor (backend code)"]
1143    pub fn mixNonTPKrausMap(
1144        qureg: Qureg,
1145        target: ::std::os::raw::c_int,
1146        ops: *mut ComplexMatrix2,
1147        numOps: ::std::os::raw::c_int,
1148    );
1149}
1150extern "C" {
1151    #[doc = " Apply a general non-trace-preserving two-qubit Kraus map to a density matrix,\n as specified by at most sixteen operators, \\f$K_i\\f$ (\\p ops).\n\n This effects\n \\f[\n\\rho \\to \\sum\\limits_i^{\\text{numOps}} K_i \\rho K_i^\\dagger\n \\f]\n where the matrices \\f$K_i\\f$ are unconstrained, and hence the effective map is permitted\n to be non-completely-positive and non-trace-preserving.\n Use mixTwoQubitKrausMap() to enforce that the map be completely positive.\n\n \\p targetQubit1 is treated as the \\p least significant qubit in each op in \\p ops.\n\n Note that in distributed mode, this routine requires that each node contains at least 16 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-4) numTargs nodes.\n\n @see\n - ::ComplexMatrix4\n - mixTwoQubitKrausMap()\n - mixNonTPKrausMap()\n - mixNonTPMultiQubitKrausMap()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] target1 the least significant target qubit in \\p ops\n @param[in] target2 the most significant target qubit in \\p ops\n @param[in] ops an array of at most 16 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= 16.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if either \\p target1 or \\p target2 is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p target1 = \\p target2\n - if \\p numOps is outside [1, 16]\n - if a node cannot fit 16 amplitudes in distributed mode\n @author Tyson Jones\n @author Balint Koczor (backend code)"]
1152    pub fn mixNonTPTwoQubitKrausMap(
1153        qureg: Qureg,
1154        target1: ::std::os::raw::c_int,
1155        target2: ::std::os::raw::c_int,
1156        ops: *mut ComplexMatrix4,
1157        numOps: ::std::os::raw::c_int,
1158    );
1159}
1160extern "C" {
1161    #[doc = " Apply a general N-qubit non-trace-preserving Kraus map to a density matrix,\n as specified by at most (2N)^2 operators.\n\n This effects\n \\f[\n\\rho \\to \\sum\\limits_i^{\\text{numOps}} K_i \\rho K_i^\\dagger\n \\f]\n where the matrices \\f$ K_i \\f$ are unconstrained, and hence the effective map is permitted\n to be non-completely-positive and non-trace-preserving.\n Use mixMultiQubitKrausMap() to enforce that the map be completely positive.\n\n The first qubit in \\p targets is treated as the \\p least significant qubit in each op in \\p ops.\n\n Note that in distributed mode, this routine requires that each node contains at least (2N)^2 amplitudes.\n This means an q-qubit register can be distributed by at most 2^(q-2)/N^2 nodes.\n\n Note too that this routine internally creates a 'superoperator'; a complex matrix of dimensions\n 2^(2*numTargets) by 2^(2*numTargets). Therefore, invoking this function incurs,\n for numTargs={1,2,3,4,5, ...}, an additional memory overhead of (at double-precision)\n {0.25 KiB, 4 KiB, 64 KiB, 1 MiB, 16 MiB, ...} (respectively).\n At quad precision (usually 10 B per number, but possibly 16 B due to alignment),\n this costs at most double the amount of memory.\n For numTargets < 4, this superoperator will be created in the runtime\n stack. For numTargs >= 4, the superoperator will be allocated in the heap and\n therefore this routine may suffer an anomalous slowdown.\n\n @see\n - createComplexMatrixN()\n - initComplexMatrixN()\n - mixMultiQubitKrausMap()\n - mixNonTPKrausMap()\n - mixNonTPTwoQubitKrausMap()\n\n @ingroup decoherence\n @param[in,out] qureg the density matrix to which to apply the map\n @param[in] targets a list of target qubit indices, the first of which is treated as least significant in each op in \\p ops\n @param[in] numTargets the length of \\p targets\n @param[in] ops an array of at most (2N)^2 Kraus operators\n @param[in] numOps the number of operators in \\p ops which must be >0 and <= (2N)^2.\n @throws invalidQuESTInputError()\n - if \\p qureg is not a density matrix\n - if any target in \\p targets is outside of [0, \\p qureg.numQubitsRepresented)\n - if any qubit in \\p targets is repeated\n - if \\p numOps is outside [1, (2 \\p numTargets)^2]\n - if any ComplexMatrixN in \\p ops does not have op.numQubits == \\p numTargets\n - if a node cannot fit (2N)^2 amplitudes in distributed mode\n @author Tyson Jones\n @author Balint Koczor (backend code)"]
1162    pub fn mixNonTPMultiQubitKrausMap(
1163        qureg: Qureg,
1164        targets: *mut ::std::os::raw::c_int,
1165        numTargets: ::std::os::raw::c_int,
1166        ops: *mut ComplexMatrixN,
1167        numOps: ::std::os::raw::c_int,
1168    );
1169}
1170extern "C" {
1171    #[doc = " Computes the Hilbert Schmidt distance between two density matrices \\p a and \\p b,\n defined as the Frobenius norm of the difference between them.\n That is, we define the Hilbert Schmidt distance\n \\f[\nD(a, b) = \\| a - b \\|_F = \\sqrt{  \\text{Tr}[ (a-b)(a-b)^\\dagger ]   }\n \\f]\n This is equivalent to the square-root of the sum of the absolute value squared of the\n element-differences of the matrices, i.e.\n \\f[\nD(a, b) = \\sqrt{ \\sum\\limits_i \\sum\\limits_j | a_{ij} - b_{ij} |^2 }\n \\f]\n We caution this may differ by some definitions of the Hilbert Schmidt distance\n by a square-root.\n\n This function correctly returns the result of the above formulations even when\n \\p a and \\p b are incorrectly normalised (i.e. are general matrices).\n\n @see\n - calcDensityInnerProduct()\n - calcFidelity()\n - calcPurity()\n\n @ingroup calc\n @param[in] a a density matrix\n @param[in] b an equally-sized density matrix\n @throws invalidQuESTInputError()\n - if either \\p a or \\p b are not density matrices\n - if \\p a and \\p have mismatching dimensions\n @author Balint Koczor\n @author Tyson Jones (refactored, doc)"]
1172    pub fn calcHilbertSchmidtDistance(a: Qureg, b: Qureg) -> f64;
1173}
1174extern "C" {
1175    #[doc = " Modifies qureg \\p out to the result of (\\p facOut \\p out + \\p fac1 \\p qureg1 + \\p fac2 \\p qureg2),\n imposing no constraints on normalisation. Works for both state-vectors and density matrices.\n Note that afterward, \\p out may not longer be normalised and ergo no longer a valid\n state-vector or density matrix. Users must therefore be careful passing \\p out to\n other QuEST functions which assume normalisation in order to function correctly.\n\n \\p qureg1, \\p qureg2 and \\p out must be all state-vectors, or all density matrices,\n of equal dimensions. \\p out can be one (or both) of \\p qureg1 and \\p qureg2.\n\n @ingroup init\n @param[in] fac1 the complex number by which to scale \\p qureg1 in the output state\n @param[in] qureg1 the first qureg to add to \\p out, which is itself unmodified\n @param[in] fac2 the complex number by which to scale \\p qureg2 in the output state\n @param[in] qureg2 the second qureg to add to \\p out, which is itself unmodified\n @param[in] facOut the complex factor by which to multiply the current elements of \\p out.\n      \\p out is completely overwritten if \\p facOut is set to (Complex) {.real=0,.imag=0}\n @param[in,out] out the qureg to be modified, to be scaled by \\p facOut then have \\p fac1 \\p qureg1 and\n      \\p fac2 \\p qureg2 added to it.\n @throws invalidQuESTInputError()\n - if \\p qureg1, \\p qureg2 and \\p aren't all state-vectors or all density matrices\n - if the dimensions of \\p qureg1, \\p qureg2 and \\p aren't equal\n @author Tyson Jones"]
1176    pub fn setWeightedQureg(
1177        fac1: Complex,
1178        qureg1: Qureg,
1179        fac2: Complex,
1180        qureg2: Qureg,
1181        facOut: Complex,
1182        out: Qureg,
1183    );
1184}
1185extern "C" {
1186    #[doc = " Modifies \\p outQureg to be the result of applying the weighted sum of Pauli products (a Hermitian but not\n necessarily unitary operator) to \\p inQureg. Note that afterward, \\p outQureg may no longer be normalised and ergo not a\n state-vector or density matrix. Users must therefore be careful passing \\p outQureg to\n other QuEST functions which assume normalisation in order to function correctly.\n\n Letting \\f$ \\alpha = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$ be\n the operators indicated by \\p allPauliCodes (where \\f$ c_i \\in \\f$ \\p termCoeffs and \\f$ N = \\f$ \\p qureg.numQubitsRepresented),\n this function effects \\f$ \\alpha | \\psi \\rangle \\f$ on state-vector \\f$ |\\psi\\rangle \\f$\n and \\f$\\alpha \\rho\\f$ (left matrix multiplication) on density matrix \\f$ \\rho \\f$.\n\n \\p allPauliCodes is an array of length \\p numSumTerms*\\p qureg.numQubitsRepresented\n  which specifies which Pauli operators to apply, where 0 = \\p PAULI_I, 1 = \\p PAULI_X,\n 2 = \\p PAULI_Y, 3 = \\p PAULI_Z. For each sum term, a Pauli operator must be specified for\n EVERY qubit in \\p qureg; each set of \\p numSumTerms operators will be grouped into a product.\n \\p termCoeffs is an arrray of length \\p numSumTerms containing the term coefficients.\n For example, on a 3-qubit state-vector,\n ```\n     int paulis[6] = {PAULI_X, PAULI_I, PAULI_I,  PAULI_X, PAULI_Y, PAULI_Z};\n     qreal coeffs[2] = {1.5, -3.6};\n     applyPauliSum(inQureg, paulis, coeffs, 2, outQureg);\n ```\n will apply Hermitian operation \\f$ (1.5 X I I - 3.6 X Y Z) \\f$\n (where in this notation, the left-most operator applies to the least-significant qubit, i.e. that with index 0).\n\n In theory, \\p inQureg is unchanged though its state is temporarily\n modified and is reverted by re-applying Paulis (XX=YY=ZZ=I), so may see a change by small numerical errors.\n The initial state in \\p outQureg is not used.\n\n \\p inQureg and \\p outQureg must both be state-vectors, or both density matrices,\n of equal dimensions. \\p inQureg cannot be \\p outQureg.\n\n This function works by applying each Pauli product to \\p inQureg in turn,\n and adding the resulting state (weighted by a coefficient in \\p termCoeffs)\n to the initially-blanked \\p outQureg. Ergo it should scale with the total number\n of Pauli operators specified (excluding identities), and the qureg dimension.\n\n @see\n - calcExpecPauliSum()\n - applyPauliHamil()\n\n @ingroup operator\n @param[in] inQureg the register containing the state which \\p outQureg will be set to, under\n      the action of the Hermitiain operator specified by the Pauli codes. \\p inQureg should be\n      unchanged, though may vary slightly due to numerical error.\n @param[in] allPauliCodes a list of the Pauli codes (0=PAULI_I, 1=PAULI_X, 2=PAULI_Y, 3=PAULI_Z)\n      of all Paulis involved in the products of terms. A Pauli must be specified for each qubit\n      in the register, in every term of the sum.\n @param[in] termCoeffs The coefficients of each term in the sum of Pauli products\n @param[in] numSumTerms The total number of Pauli products specified\n @param[out] outQureg the qureg to modify to be the result of applyling the weighted Pauli sum operator\n      to the state in \\p inQureg\n @throws invalidQuESTInputError()\n - if any code in \\p allPauliCodes is not in {0,1,2,3}\n - if numSumTerms <= 0\n - if \\p inQureg is not of the same type and dimensions as \\p outQureg\n @author Tyson Jones"]
1187    pub fn applyPauliSum(
1188        inQureg: Qureg,
1189        allPauliCodes: *mut pauliOpType,
1190        termCoeffs: *mut f64,
1191        numSumTerms: ::std::os::raw::c_int,
1192        outQureg: Qureg,
1193    );
1194}
1195extern "C" {
1196    #[doc = " Modifies \\p outQureg to be the result of applying \\p PauliHamil (a Hermitian but not\n necessarily unitary operator) to \\p inQureg. Note that afterward, \\p outQureg may no longer be normalised and ergo not a\n state-vector or density matrix. Users must therefore be careful passing \\p outQureg to\n other QuEST functions which assume normalisation in order to function correctly.\n\n This is merely an encapsulation of applyPauliSum(), which can refer to for elaborated doc.\n\n Letting \\p hamil be expressed as \\f$ \\alpha = \\sum_i c_i \\otimes_j^{N} \\hat{\\sigma}_{i,j} \\f$\n (where \\f$ c_i \\in \\f$ \\p hamil.termCoeffs and \\f$ N = \\f$ \\p hamil.numQubits),\n this function effects \\f$ \\alpha | \\psi \\rangle \\f$ on state-vector \\f$ |\\psi\\rangle \\f$\n and \\f$\\alpha \\rho\\f$ (left matrix multiplication) on density matrix \\f$ \\rho \\f$.\n\n In theory, \\p inQureg is unchanged though its state is temporarily\n modified and is reverted by re-applying Paulis (XX=YY=ZZ=I), so may see a change by small numerical errors.\n The initial state in \\p outQureg is not used.\n\n \\p inQureg and \\p outQureg must both be state-vectors, or both density matrices,\n of equal dimensions to \\p hamil.\n \\p inQureg cannot be \\p outQureg.\n\n This function works by applying each Pauli product in \\p hamil to \\p inQureg in turn,\n and adding the resulting state (weighted by a coefficient in \\p termCoeffs)\n to the initially-blanked \\p outQureg. Ergo it should scale with the total number\n of Pauli operators specified (excluding identities), and the qureg dimension.\n\n @see\n - createPauliHamil()\n - createPauliHamilFromFile()\n - calcExpecPauliHamil()\n - applyTrotterCircuit()\n\n @ingroup operator\n @param[in] inQureg the register containing the state which \\p outQureg will be set to, under\n      the action of \\p hamil. \\p inQureg should be unchanged, though may vary slightly due to numerical error.\n @param[in] hamil a weighted sum of products of pauli operators\n @param[out] outQureg the qureg to modify to be the result of applyling \\p hamil to the state in \\p inQureg\n @throws invalidQuESTInputError()\n - if any code in \\p hamil.pauliCodes is not a valid Pauli code\n - if \\p numSumTerms <= 0\n - if \\p inQureg is not of the same type and dimensions as \\p outQureg and \\p hamil\n @author Tyson Jones"]
1197    pub fn applyPauliHamil(inQureg: Qureg, hamil: PauliHamil, outQureg: Qureg);
1198}
1199extern "C" {
1200    #[doc = " Applies a trotterisation of unitary evolution \\f$ \\exp(-i \\, \\text{hamil} \\, \\text{time}) \\f$\n to \\p qureg. This is a sequence of unitary operators, effected by multiRotatePauli(),\n which together approximate the action of full unitary-time evolution under the given Hamiltonian.\n\n Notate \\f$ \\text{hamil} = \\sum_j^N c_j \\, \\hat \\sigma_j \\f$ where \\f$c_j\\f$ is a real\n coefficient in \\p hamil, \\f$\\hat \\sigma_j\\f$ is the corresponding product of Pauli operators,\n of which there are a total \\f$N\\f$.\n Then, \\p order=1 performs first-order Trotterisation, whereby\n \\f[\n   \\exp(-i \\, \\text{hamil} \\, \\text{time})\n      \\approx\n    \\prod\\limits^{\\text{reps}} \\prod\\limits_{j=1}^{N} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / \\text{reps})\n \\f]\n \\p order=2 performs the lowest order \"symmetrized\" Suzuki decomposition, whereby\n \\f[\n   \\exp(-i \\, \\text{hamil} \\, \\text{time})\n      \\approx\n    \\prod\\limits^{\\text{reps}} \\left[\n         \\prod\\limits_{j=1}^{N} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / (2 \\, \\text{reps}))\n          \\prod\\limits_{j=N}^{1} \\exp(-i \\, c_j \\, \\text{time} \\, \\hat\\sigma_j / (2 \\, \\text{reps}))\n     \\right]\n \\f]\n Greater even values of \\p order specify higher-order symmetrized decompositions\n \\f$ S[\\text{time}, \\text{order}, \\text{reps}] \\f$ which satisfy\n \\f[\n      S[\\text{time}, \\text{order}, 1] =\n          \\left( \\prod\\limits^2 S[p \\, \\text{time}, \\text{order}-2, 1] \\right)\n          S[ (1-4p)\\,\\text{time}, \\text{order}-2, 1]\n          \\left( \\prod\\limits^2 S[p \\, \\text{time}, \\text{order}-2, 1] \\right)\n \\f]\n and\n \\f[\n      S[\\text{time}, \\text{order}, \\text{reps}] =\n          \\prod\\limits^{\\text{reps}} S[\\text{time}/\\text{reps}, \\text{order}, 1]\n \\f]\n where \\f$ p = \\left( 4 - 4^{1/(\\text{order}-1)} \\right)^{-1} \\f$.\n\n These formulations are taken from 'Finding Exponential Product Formulas\n of Higher Orders', Naomichi Hatano and Masuo Suzuki (2005) (<a href=\"https://arxiv.org/abs/math-ph/0506007\">arXiv</a>).\n\n Note that the applied Trotter circuit is captured by QASM, if QASM logging is enabled\n on \\p qureg. \\n\n For example:\n ```\n startRecordingQASM(qureg);\n applyTrotterCircuit(qureg, hamil, 1, 2, 1);\n printRecordedQASM(qureg);\n ```\n may show\n ```\n // Beginning of Trotter circuit (time 1, order 2, 1 repetitions).\n // Here, a multiRotatePauli with angle 0.5 and paulis X Y I  was applied.\n // Here, a multiRotatePauli with angle -0.5 and paulis I Z X  was applied.\n // Here, a multiRotatePauli with angle -0.5 and paulis I Z X  was applied.\n // Here, a multiRotatePauli with angle 0.5 and paulis X Y I  was applied.\n // End of Trotter circuit\n ```\n \\n\n\n\n @see\n - createPauliHamil()\n\n @ingroup operator\n @param[in,out] qureg the register to modify under the approximate unitary-time evolution\n @param[in] hamil the hamiltonian under which to approxiamte unitary-time evolution\n @param[in] time the target evolution time, which is permitted to be both positive and negative.\n @param[in] order the order of Trotter-Suzuki decomposition to use. Higher orders (necessarily even)\n      are more accurate but prescribe an exponentially increasing number of gates.\n @param[in] reps the number of repetitions of the decomposition of the given order. This\n      improves the accuracy but prescribes a linearly increasing number of gates.\n @throws invalidQuESTInputError()\n - if \\p qureg.numQubitsRepresented != \\p hamil.numQubits\n - if \\p hamil contains invalid parameters or Pauli codes,\n - if \\p order is not in {1, 2, 4, 6, ...}\n - or if \\p reps <= 0\n @author Tyson Jones"]
1201    pub fn applyTrotterCircuit(
1202        qureg: Qureg,
1203        hamil: PauliHamil,
1204        time: f64,
1205        order: ::std::os::raw::c_int,
1206        reps: ::std::os::raw::c_int,
1207    );
1208}
1209extern "C" {
1210    #[doc = " Apply a general 2-by-2 matrix, which may be non-unitary. The matrix is\n left-multiplied onto the state, for both state-vectors and density matrices.\n\n Note this differs from the action of unitary() on a density matrix.\n\n This function may leave \\p qureg is an unnormalised state.\n\n @see\n - ::ComplexMatrix2\n - unitary()\n\n @ingroup operator\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit qubit to operate \\p u upon\n @param[in] u matrix to apply\n @throws invalidQuESTInputError()\n - if \\p targetQubit is outside [0, \\p qureg.numQubitsRepresented)\n @author Tyson Jones"]
1211    pub fn applyMatrix2(qureg: Qureg, targetQubit: ::std::os::raw::c_int, u: ComplexMatrix2);
1212}
1213extern "C" {
1214    #[doc = " Apply a general 4-by-4 matrix, which may be non-unitary. The matrix is\n left-multiplied onto the state, for both state-vectors and density matrices.\n\n Note this differs from the action of twoQubitUnitary() on a density matrix.\n\n \\p targetQubit1 is treated as the \\p least significant qubit in \\p u, such that\n a row in \\p u is dotted with the vector\n \\f$ |\\text{targetQubit2} \\;\\; \\text{targetQubit1}\\rangle : \\{ |00\\rangle, |01\\rangle, |10\\rangle, |11\\rangle \\} \\f$\n\n For example,\n ```\n     applyMatrix4(qureg, a, b, u);\n ```\n will invoke multiplication\n \\f[\n \\begin{pmatrix}\n u_{00} & u_{01} & u_{02} & u_{03} \\\\\n u_{10} & u_{11} & u_{12} & u_{13} \\\\\n u_{20} & u_{21} & u_{22} & u_{23} \\\\\n u_{30} & u_{31} & u_{32} & u_{33}\n \\end{pmatrix}\n \\begin{pmatrix}\n |ba\\rangle = |00\\rangle \\\\\n |ba\\rangle = |01\\rangle \\\\\n |ba\\rangle = |10\\rangle \\\\\n |ba\\rangle = |11\\rangle\n \\end{pmatrix}\n \\f]\n\n This function may leave \\p qureg is an unnormalised state.\n\n Note that in distributed mode, this routine requires that each node contains at least 4 amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q/4 nodes.\n\n @see\n - ::ComplexMatrix4\n - twoQubitUnitary()\n\n @ingroup operator\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targetQubit1 first qubit to operate on, treated as least significant in \\p u\n @param[in] targetQubit2 second qubit to operate on, treated as most significant in \\p u\n @param[in] u matrix to apply\n @throws invalidQuESTInputError()\n - if \\p targetQubit1 or \\p targetQubit2 are outside [0, \\p qureg.numQubitsRepresented)\n - if \\p targetQubit1 equals \\p targetQubit2\n - if each node cannot fit 4 amplitudes in distributed mode\n @author Tyson Jones"]
1215    pub fn applyMatrix4(
1216        qureg: Qureg,
1217        targetQubit1: ::std::os::raw::c_int,
1218        targetQubit2: ::std::os::raw::c_int,
1219        u: ComplexMatrix4,
1220    );
1221}
1222extern "C" {
1223    #[doc = " Apply a general N-by-N matrix, which may be non-unitary, on any number of target qubits.\n The matrix is left-multiplied onto the state, for both state-vectors and density matrices.\n Note this differs from the action of multiQubitUnitary() on a density matrix.\n\n The first target qubit in \\p targs is treated as \\b least significant in \\p u.\n For example,\n ```\n     applyMatrixN(qureg, (int []) {a, b, c}, 3, u);\n ```\n will invoke multiplication\n \\f[\n \\begin{pmatrix}\n u_{00} & u_{01} & u_{02} & u_{03} & u_{04} & u_{05} & u_{06} & u_{07} \\\\\n u_{10} & u_{11} & u_{12} & u_{13} & u_{14} & u_{15} & u_{16} & u_{17} \\\\\n u_{20} & u_{21} & u_{22} & u_{23} & u_{24} & u_{25} & u_{26} & u_{27} \\\\\n u_{30} & u_{31} & u_{32} & u_{33} & u_{34} & u_{35} & u_{36} & u_{37} \\\\\n u_{40} & u_{41} & u_{42} & u_{43} & u_{44} & u_{45} & u_{46} & u_{47} \\\\\n u_{50} & u_{51} & u_{52} & u_{53} & u_{54} & u_{55} & u_{56} & u_{57} \\\\\n u_{60} & u_{61} & u_{62} & u_{63} & u_{64} & u_{65} & u_{66} & u_{67} \\\\\n u_{70} & u_{71} & u_{72} & u_{73} & u_{74} & u_{75} & u_{76} & u_{77} \\\\\n \\end{pmatrix}\n \\begin{pmatrix}\n |cba\\rangle = |000\\rangle \\\\\n |cba\\rangle = |001\\rangle \\\\\n |cba\\rangle = |010\\rangle \\\\\n |cba\\rangle = |011\\rangle \\\\\n |cba\\rangle = |100\\rangle \\\\\n |cba\\rangle = |101\\rangle \\\\\n |cba\\rangle = |110\\rangle \\\\\n |cba\\rangle = |111\\rangle\n \\end{pmatrix}\n \\f]\n\n This function may leave \\p qureg is an unnormalised state.\n\n The passed ComplexMatrix must be a compatible size with the specified number of\n target qubits, otherwise an error is thrown.\n\n Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,\n and store these in the runtime stack.\n Using t threads, the total memory overhead of this function is t*2^\\p numTargs.\n For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault\n (e.g. on a 1 MiB stack).\n\n Note too that in distributed mode, this routine requires that each node contains\n at least 2^\\p numTargs amplitudes in the register. This means an q-qubit register (state vector or density matrix)\n can be distributed by at most 2^q / 2^\\p numTargs nodes.\n\n @see\n - applyGateMatrixN()\n - createComplexMatrixN()\n - getStaticComplexMatrixN()\n - applyMultiControlledMatrixN()\n - multiQubitUnitary()\n\n @ingroup operator\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targs a list of the target qubits, ordered least significant to most in \\p u\n @param[in] numTargs the number of target qubits\n @param[in] u matrix to apply\n @throws invalidQuESTInputError()\n - if any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p targs are not unique\n - if \\p u is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @author Tyson Jones"]
1224    pub fn applyMatrixN(
1225        qureg: Qureg,
1226        targs: *mut ::std::os::raw::c_int,
1227        numTargs: ::std::os::raw::c_int,
1228        u: ComplexMatrixN,
1229    );
1230}
1231extern "C" {
1232    #[doc = " Apply a gate specified by a general N-by-N matrix, which may be non-unitary, on any number of target qubits.\n This function applies the given matrix to both statevector and density matrices\n as if it were a valid unitary gate.\n Hence this function is equivalent to multiQubitUnitary(), albeit the unitarity\n of \\p u is not checked nor enforced.\n This function differs from applyMatrixN() on density matrices.\n\n This function may leave \\p qureg is an unnormalised state.\n\n @see\n - applyMultiControlledGateMatrixN()\n - applyMatrixN()\n - createComplexMatrixN()\n - getStaticComplexMatrixN()\n - multiQubitUnitary()\n\n @ingroup operator\n @param[in,out] qureg object representing the set of all qubits\n @param[in] targs a list of the target qubits, ordered least significant to most in \\p u\n @param[in] numTargs the number of target qubits\n @param[in] u matrix to apply, which need not be unitary\n @throws invalidQuESTInputError()\n - if any index in \\p targs is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p targs are not unique\n - if \\p u is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @author Tyson Jones"]
1233    pub fn applyGateMatrixN(
1234        qureg: Qureg,
1235        targs: *mut ::std::os::raw::c_int,
1236        numTargs: ::std::os::raw::c_int,
1237        u: ComplexMatrixN,
1238    );
1239}
1240extern "C" {
1241    #[doc = " Apply a general multi-controlled multi-qubit gate specified as an (possibly non-unitary)\n arbitrary complex matrix.\n This is equivalent to multiControlledMultiQubitUnitary() but does not check nor enforce\n unitary of the given matrix \\p m.\n This differs from applyMultiControlledMatrixN(), because the latter only left-applies\n the matrix upon density matrices.\n\n Any number of control and target qubits can be specified.\n This effects the many-qubit unitary\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & m_{00} & m_{01} & \\dots  \\\\\n & & & m_{10} & m_{11} & \\dots \\\\\n & & & \\vdots & \\vdots & \\ddots\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n Besides unitarity, the inputs and their preconditions are the same as for\n multiControlledMultiQubitUnitary().\n\n @see\n - createComplexMatrixN()\n - applyMultiControlledMatrixN()\n - multiControlledMultiQubitUnitary()\n\n @ingroup unitary\n @param[in,out] qureg object representing the set of all qubits\n @param[in] ctrls a list of the control qubits\n @param[in] numCtrls the number of control qubits\n @param[in] targs a list of the target qubits, ordered least to most significant\n @param[in] numTargs the number of target qubits\n @param[in] m arbitrary matrix to apply as if it were a unitary gate\n @throws invalidQuESTInputError()\n - if any qubit in \\p ctrls and \\p targs is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p ctrls or \\p targs contain any repetitions\n - if any qubit in \\p ctrls is also in \\p targs (and vice versa)\n - if \\p numTargs <b>< 1</b>\n - if \\p numCtrls <b>< 1</b> (use multiQubitUnitary() for no controls)\n - if matrix \\p m is not of a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @throws segmentation-fault\n - if \\p ctrls contains fewer elements than \\p numCtrls\n - if \\p targs contains fewer elements than \\p numTargs\n @author Tyson Jones"]
1242    pub fn applyMultiControlledGateMatrixN(
1243        qureg: Qureg,
1244        ctrls: *mut ::std::os::raw::c_int,
1245        numCtrls: ::std::os::raw::c_int,
1246        targs: *mut ::std::os::raw::c_int,
1247        numTargs: ::std::os::raw::c_int,
1248        m: ComplexMatrixN,
1249    );
1250}
1251extern "C" {
1252    #[doc = " Apply a general N-by-N matrix, which may be non-unitary, with additional controlled qubits.\n The matrix is left-multiplied onto the state, for both state-vectors and density matrices.\n Hence, this function differs from multiControlledMultiQubitUnitary() by more than just permitting a non-unitary\n matrix.\n\n This function may leave \\p qureg is an unnormalised state.\n\n Any number of control and target qubits can be specified.\n This effects the many-qubit matrix\n \\f[\n \\begin{pmatrix}\n 1 \\\\\n & 1 \\\\\\\n & & \\ddots \\\\\n & & & u_{00} & u_{01} & \\dots  \\\\\n & & & u_{10} & u_{11} & \\dots \\\\\n & & & \\vdots & \\vdots & \\ddots\n \\end{pmatrix}\n \\f]\n on the control and target qubits.\n\n The target qubits in \\p targs are treated as ordered least significant\n to most significant in \\p u.\n\n The passed ComplexMatrix must be a compatible size with the specified number of\n target qubits, otherwise an error is thrown.\n\n Note that in multithreaded mode, each thread will clone 2^\\p numTargs amplitudes,\n and store these in the runtime stack.\n Using t threads, the total memory overhead of this function is t*2^\\p numTargs.\n For many targets (e.g. 16 qubits), this may cause a stack-overflow / seg-fault\n (e.g. on a 1 MiB stack).\n\n Note that in distributed mode, this routine requires that each node contains at least 2^\\p numTargs amplitudes.\n This means an q-qubit register (state vector or density matrix) can be distributed\n by at most 2^q / 2^\\p numTargs nodes.\n\n @ingroup operator\n @param[in,out] qureg object representing the set of all qubits\n @param[in] ctrls a list of the control qubits\n @param[in] numCtrls the number of control qubits\n @param[in] targs a list of the target qubits, ordered least to most significant\n @param[in] numTargs the number of target qubits\n @param[in] u matrix to apply\n @throws invalidQuESTInputError()\n - if any index in \\p ctrls and \\p targs is outside of [0, \\p qureg.numQubitsRepresented)\n - if \\p ctrls and \\p targs are not unique\n - if matrix \\p u is not a compatible size with \\p numTargs\n - if a node cannot fit the required number of target amplitudes in distributed mode\n @author Tyson Jones"]
1253    pub fn applyMultiControlledMatrixN(
1254        qureg: Qureg,
1255        ctrls: *mut ::std::os::raw::c_int,
1256        numCtrls: ::std::os::raw::c_int,
1257        targs: *mut ::std::os::raw::c_int,
1258        numTargs: ::std::os::raw::c_int,
1259        u: ComplexMatrixN,
1260    );
1261}
1262extern "C" {
1263    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by the passed\n exponential polynomial \"phase function\". This effects a diagonal unitary of unit complex scalars,\n targeting the nominated \\p qubits.\n\n - Arguments \\p coeffs and \\p exponents together specify a real exponential polynomial \\f$f(r)\\f$\n   with \\p numTerms terms, of the form\n   \\f[\n    f(r) = \\sum\\limits_{i}^{\\text{numTerms}} \\text{coeffs}[i] \\; r^{\\, \\text{exponents}[i]}\\,,\n   \\f]\n   where both \\p coeffs and \\p exponents can be negative, positive and fractional.\n   For example,\n   ```\n      qreal coeffs[] = {1, -3.14};\n      qreal exponents[] = {2, -5.5};\n      int numTerms = 2;\n   ```\n   constitutes the function\n   \\f[\n       f(r) =  1 \\, r^2 - 3.14 \\, r^{-5.5}.\n   \\f]\n   Note you cannot use fractional exponents with \\p encoding <b>=</b> ::TWOS_COMPLEMENT,\n   since the negative indices would generate (illegal) complex phases, and must\n   be overriden with applyPhaseFuncOverrides(). \\n\n > If your function \\f$f(r)\\f$ diverges at one or more \\f$r\\f$ values, you must instead\n > use applyPhaseFuncOverrides() and specify explicit phase changes for these values.\n > Otherwise, the corresponding amplitudes of the state-vector will become indeterminate (like `NaN`).\n > Note that use of any negative exponent will result in divergences at \\f$r=0\\f$.\n\n - The function \\f$f(r)\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$\n   of computational basis state with index \\f$r\\f$, such that\n   \\f[\n    \\alpha \\, |r\\rangle \\rightarrow \\, \\exp(i f(r)) \\; \\alpha \\, |r\\rangle.\n   \\f]\n   The index \\f$r\\f$ associated with each computational basis state is determined by\n   the binary value of the specified \\p qubits (ordered least to most significant),\n   interpreted under the given ::bitEncoding \\p encoding. \\n\\n\n   For example, under \\p encoding <b>=</b> \\p UNSIGNED and \\p qubits <b>= {0,1}</b>,\n   \\f[\n   \\begin{aligned}\n     |0\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|0\\mathbf{00}\\rangle \\\\\n     |0\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|0\\mathbf{01}\\rangle \\\\\n     |0\\mathbf{10}\\rangle & \\rightarrow \\, e^{i f(2)}\\,|0\\mathbf{10}\\rangle \\\\\n     |0\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|0\\mathbf{11}\\rangle \\\\\n     |1\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|1\\mathbf{00}\\rangle \\\\\n     |1\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|1\\mathbf{01}\\rangle \\\\\n     |1\\mathbf{10}\\rangle & \\rightarrow \\, e^{i f(2)}\\,|1\\mathbf{10}\\rangle \\\\\n     |1\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|1\\mathbf{11}\\rangle\n   \\end{aligned}\n   \\f]\n\n - If \\p qureg is a density matrix \\f$\\rho\\f$, this function modifies \\p qureg to\n   \\f[\n      \\rho \\rightarrow \\hat{D} \\, \\rho \\, \\hat{D}^\\dagger\n   \\f]\n   where \\f$\\hat{D}\\f$ is the diagonal unitary operator\n   \\f[\n      \\hat{D} = \\text{diag} \\, \\{ \\; e^{i f(r_0)}, \\; e^{i f(r_1)}, \\;  \\dots \\; \\}.\n   \\f]\n   This means element \\f$\\rho_{jk}\\f$ is modified to\n   \\f[\n      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\; e^{i (f(r_j) - f(r_k))} \\; \\alpha \\, |j\\rangle\\langle k|\n   \\f]\\n\n\n - The interpreted phase function can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyPhaseFunc(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyPhaseFunc() multiplied a complex scalar of the form\n   //     exp(i (1 x^3))\n   //   upon every substate |x>, informed by qubits (under an unsigned binary encoding)\n   //     {4, 1, 2, 0}\n   ```\n\n > This function may become numerically imprecise for quickly growing phase functions\n > which admit very large phases, for example of 10^10.\n\n @see\n - applyPhaseFuncOverrides() to override the phase function for specific states.\n - applyMultiVarPhaseFunc() for multi-variable exponential polynomial phase functions.\n - applyNamedPhaseFunc() for a set of specific phase functions.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density matrix to be modified\n @param[in] qubits a list of the indices of the qubits which will inform \\f$r\\f$ for each amplitude in \\p qureg\n @param[in] numQubits the length of list \\p qubits\n @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\n @param[in] coeffs the coefficients of the exponential polynomial phase function \\f$f(r)\\f$\n @param[in] exponents the exponents of the exponential polynomial phase function \\f$f(r)\\f$\n @param[in] numTerms the length of list \\p coeffs, which must be the same as that of \\p exponents\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique\n - if \\p numQubits < 0 or \\p numQubits >= `qureg.numQubitsRepresented`\n - if \\p encoding is not a valid ::bitEncoding\n - if \\p encoding is not compatible with \\p numQubits (e.g. \\p TWOS_COMPLEMENT with only 1 qubit)\n - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT (you must instead use applyPhaseFuncOverrides() and override all negative indices)\n - if \\p exponents contains a negative power (you must instead use applyPhaseFuncOverrides() and override the zero index)\n - if \\p numTerms <= 0\n @author Tyson Jones"]
1264    pub fn applyPhaseFunc(
1265        qureg: Qureg,
1266        qubits: *mut ::std::os::raw::c_int,
1267        numQubits: ::std::os::raw::c_int,
1268        encoding: bitEncoding,
1269        coeffs: *mut f64,
1270        exponents: *mut f64,
1271        numTerms: ::std::os::raw::c_int,
1272    );
1273}
1274extern "C" {
1275    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by the passed\n exponential polynomial \"phase function\", and an explicit set of 'overriding' values at specific\n state indices.\n\n See applyPhaseFunc() first for a full description.\n\n - As in applyPhaseFunc(), the arguments \\p coeffs and \\p exponents specify a phase\n   function \\f$f(r)\\f$, where \\f$r\\f$ is determined by \\p qubits and \\p encoding for\n   each basis state of \\p qureg.\\n\\n\n - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies\n   the values of \\f$r\\f$ for which to explicitly set the induced phase change.\\n\n   The overriding phase changes are specified in the corresponding elements of \\p overridePhases.\\n\\n\n   For example,\n   ```\n      int qubits[] = {0,1};\n      enum bitEncoding encoding = UNSIGNED;\n\n      long long int overrideInds[] = {2};\n      qreal overridePhases[] = {M_PI};\n\n      applyPhaseFuncOverrides(...);\n   ```\n   would effect the same diagonal unitary of applyPhaseFunc(), <em>except</em> that all\n   instance of \\f$f(r=2)\\f$ are overriden with phase \\f$\\pi\\f$. \\n I.e.\n   \\f[\n   \\begin{aligned}\n     |0\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|0\\mathbf{00}\\rangle \\\\\n     |0\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|0\\mathbf{01}\\rangle \\\\\n     |0\\mathbf{10}\\rangle & \\rightarrow \\, e^{i \\pi} \\hspace{12pt} |0\\mathbf{10}\\rangle \\\\\n     |0\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|0\\mathbf{11}\\rangle \\\\\n     |1\\mathbf{00}\\rangle & \\rightarrow \\, e^{i f(0)}\\,|1\\mathbf{00}\\rangle \\\\\n     |1\\mathbf{01}\\rangle & \\rightarrow \\, e^{i f(1)}\\,|1\\mathbf{01}\\rangle \\\\\n     |1\\mathbf{10}\\rangle & \\rightarrow \\, e^{i \\pi} \\hspace{12pt} |1\\mathbf{10}\\rangle \\\\\n     |1\\mathbf{11}\\rangle & \\rightarrow \\, e^{i f(3)}\\,|1\\mathbf{11}\\rangle\n   \\end{aligned}\n   \\f]\n   Note that if \\p encoding <b>=</b> ::TWOS_COMPLEMENT, \\a and \\f$f(r)\\f$ features a\n   fractional exponent, then every negative phase index must be overriden. This\n   is checked and enforced by QuEST's validation, \\a unless there are more than\n   16 targeted qubits, in which case valid input is assumed (due to an otherwise\n   prohibitive performance overhead).\n   \\n\n > Overriding phases are checked at each computational basis state of \\p qureg <em>before</em>\n > evaluating the phase function \\f$f(r)\\f$, and hence are useful for avoiding\n > singularities or errors at diverging values of \\f$r\\f$.\n\n - If \\p qureg is a density matrix \\f$\\rho\\f$, the overrides determine the diagonal unitary matrix\n   \\f$\\hat{D}\\f$, which is then applied to \\p qureg as\n   \\f[\n      \\rho \\; \\rightarrow \\; \\hat{D} \\, \\rho \\hat{D}^\\dagger.\n   \\f]\n   This means that with overrides \\f$f(r_j) \\rightarrow \\theta\\f$ and \\f$f(r_k) \\rightarrow \\phi\\f$,\n   element \\f$\\rho_{jk}\\f$ is modified to\n   \\f[\n      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;\n          \\exp(\\, i \\, (\\theta - \\phi) \\, ) \\; \\alpha \\, |j\\rangle\\langle k|.\n   \\f]\\n\n\n - The interpreted phase function and list of overrides can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyPhaseFunc(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyPhaseFunc() multiplied a complex scalar of the form\n   //     exp(i (0.3 x^(-5) + 4 x^1 + 1 x^3))\n   //   upon every substate |x>, informed by qubits (under a two's complement binary encoding)\n   //     {4, 1, 2, 0}\n   //   though with overrides\n   //     |0> -> exp(i 3.14159)\n   //     |1> -> exp(i (-3.14159))\n   //     |2> -> exp(i 0)\n   ```\n \\n\n\n\n @see\n - applyPhaseFunc() for full doc on how \\f$f(r)\\f$ is evaluated.\n - applyMultiVarPhaseFunc() for multi-variable exponential polynomial phase functions.\n - applyNamedPhaseFunc() for a set of specific phase functions.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density matrix to be modified\n @param[in] qubits a list of the indices of the qubits which will inform \\f$r\\f$ for each amplitude in \\p qureg\n @param[in] numQubits the length of list \\p qubits\n @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\n @param[in] coeffs the coefficients of the exponential polynomial phase function \\f$f(r)\\f$\n @param[in] exponents the exponents of the exponential polynomial phase function \\f$f(r)\\f$\n @param[in] numTerms the length of list \\p coeffs, which must be the same as that of \\p exponents\n @param[in] overrideInds a list of sub-state indices (values of \\f$r\\f$) of which to explicit set the phase change\n @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$r\\f$ values in \\p overrideInds (one to one)\n @param[in] numOverrides the lengths of lists \\p overrideInds and \\p overridePhases\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique\n - if \\p numQubits < 0 or \\p numQubits >= `qureg.numQubitsRepresented`\n - if \\p encoding is not a valid ::bitEncoding\n - if \\p encoding is not compatible with \\p numQubits (i.e. \\p TWOS_COMPLEMENT with 1 qubit)\n - if \\p numTerms <= 0\n - 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)\n - if \\p numOverrides < 0\n - if \\p exponents contains a negative power and the (consequently diverging) zero index is not contained in \\p overrideInds\n - 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)\n @author Tyson Jones"]
1276    pub fn applyPhaseFuncOverrides(
1277        qureg: Qureg,
1278        qubits: *mut ::std::os::raw::c_int,
1279        numQubits: ::std::os::raw::c_int,
1280        encoding: bitEncoding,
1281        coeffs: *mut f64,
1282        exponents: *mut f64,
1283        numTerms: ::std::os::raw::c_int,
1284        overrideInds: *mut ::std::os::raw::c_longlong,
1285        overridePhases: *mut f64,
1286        numOverrides: ::std::os::raw::c_int,
1287    );
1288}
1289extern "C" {
1290    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n multi-variable exponential polynomial \"phase function\".\n\n This is a multi-variable extension of applyPhaseFunc(), whereby multiple sub-registers inform\n separate variables in the exponential polynomial function, and effects a diagonal unitary\n operator.\n\n - Arguments \\p coeffs, \\p exponents and \\p numTermsPerReg together specify a real\n   exponential polynomial \\f$f(\\vec{r})\\f$ of the form\n   \\f[\n    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}}\\,,\n   \\f]\n   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.\n   \\n\\n\n   While \\p coeffs and \\p exponents are flat lists, they should be considered grouped into\n   #`numRegs` sublists with lengths given by \\p numTermsPerReg (which itself has length \\p numRegs). \\n\\n\n   For example,\n   ```\n      int numRegs = 3;\n      qreal coeffs[] =        {1,  2, 4,  -3.14};\n      qreal exponents[] =     {2,  1, 5,   0.5 };\n      int numTermsPerReg[] =  {1,  2,      1   };\n   ```\n   constitutes the function\n   \\f[\n      f(\\vec{r}) =  1 \\, {r_1}^2 + 2 \\, {r_2} + 4 \\, {r_2}^{5} - 3.14 \\, {r_3}^{0.5}.\n   \\f] \\n\n   > This means lists \\p coeffs and \\p exponents should both be of length equal to the sum of \\p numTermsPerReg.\n   Unlike applyPhaseFunc(), applyMultiVarPhaseFunc() places additional constraints on the\n   exponents in \\f$f(\\vec{r})\\f$, due to the exponentially growing costs of overriding\n   diverging indices. Namely:\\n\n   -# \\p exponents must not contain a negative number, since this would result in a divergence\n         when that register is zero, which would need to be overriden for every other register\n         basis state. If \\f$f(\\vec{r})\\f$ must contain a negative exponent, you should instead\n         call applyPhaseFuncOverrides() once for each register/variable, and override the\n         zero index for the relevant variable. This works, because\n         \\f[  \\exp( i \\sum_j f_j(r_j) ) = \\prod_j \\exp(i f_j(r_j) ). \\f]\n   -# \\p exponents must not contain a fractional number if \\p endoding <b>=</b> ::TWOS_COMPLEMENT,\n         because such a term would produce illegal complex values at negative register indices.\n         Similar to the problem above, each negative register index would require overriding at\n         every index of the other registers, and hence require an exponential number of overrides.\n         Therefore, if \\f$f(\\vec{r})\\f$ must contain a negative exponent, you should instead\n         call applyPhaseFuncOverrides() once for each register/variable, and override every\n         negative index of each register in turn.\n \\n\\n\n - Lists \\p qubits and \\p numQubitsPerReg together describe #`numRegs` sub-registers of \\p qureg,\n   which can each contain a different number of qubits. \\n\n   Although \\p qubits is a flat list of unique qubit indices, it should be imagined grouped into #`numRegs` sub-lists,\n   of lengths given by \\p numQubitsPerReg. \\n\\n\n   For example,\n   ```\n      int qubits[] =          {0,1,  3,4,5,  7}\n      int numQubitsPerReg[] = {2,    3,      1};\n      int numRegs = 3;\n   ```\n   describes three sub-registers, which are bolded below in an eight-qubit zero-state.\n   \\f[\n      |r_3\\rangle \\; |0\\rangle \\; |r_2\\rangle \\; |0\\rangle \\; |r_1\\rangle =\n      |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle\n   \\f]\n   Note that the qubits need not be ordered increasing, and qubits within each sub-register\n   are assumed ordered least to most significant in that sub-register.\\n\\n\n   > List \\p qubits should have length equal to the sum of elements in \\p numQubitsPerReg.\n\n - Each sub-register is associated with a variable \\f$r_j\\f$ in phase function \\f$f(\\vec{r})\\f$. \\n\n   For a given computational basis state of \\p qureg, the value of each variable is determined\n   by the binary value in the corresponding sub-register, when intepreted with ::bitEncoding \\p encoding. \\n\n   See ::bitEncoding for more information.\\n\\n\n\n - The function \\f$f(\\vec{r})\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$\n   of computational basis state with the nominated sub-registers encoding values \\f$r_1, \\; \\dots\\f$.\n   \\f[\n    \\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.\n   \\f]\n   For example, using the sub-registers in the previous example and \\p encoding <b>=</b> \\p UNSIGNED, the\n   following states receive amplitude factors:\n   \\f[\n   \\begin{aligned}\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=1)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{10}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=2)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=3)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |1\\rangle \\; |\\mathbf{00}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\\n   & \\;\\;\\;\\vdots \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=7,r_1=1)} \\\\\n   & \\;\\;\\;\\vdots \\\\\n     |\\mathbf{1}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=1,r_2=7,r_1=3)}\n   \\end{aligned}\n   \\f]\n\n - If \\p qureg is a density matrix \\f$\\rho\\f$, then its elements are modified as\n   \\f[\n      \\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;\n          \\exp(i \\, (f(\\vec{r}_j) - f(\\vec{r}_k)) \\, ) \\; \\alpha \\, |j\\rangle\\langle k|,\n   \\f]\n   where \\f$f(\\vec{r}_j)\\f$ and \\f$f(\\vec{r}_k)\\f$ are determined as above.\\n\\n\n\n - The interpreted phase function can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyMultiVarPhaseFunc(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   would show, for the above example,\n   ```\n   // Here, applyMultiVarPhaseFunc() multiplied a complex scalar of the form\n   //     exp(i (\n   //          + 1 x^2\n   //          + 2 y + 4 y^(-1)\n   //          - 3.14 z^0.5 ))\n   //   upon substates informed by qubits (under an unsigned binary encoding)\n   //     |x> = {0, 1}\n   //     |y> = {3, 4, 5}\n   //     |z> = {7}\n   ```\n \\n\n\n\n @see\n - applyMultiVarPhaseFuncOverrides() to additionally specify explicit phases for specific sub-register values.\n - applyNamedPhaseFunc() for a set of specific and potentially multi-variable phase functions.\n - applyPhaseFunc() for a single-variable polynomial exponential phase function, which is approximately twice as fast.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] coeffs the coefficients of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$\n @param[in] exponents the exponents of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$\n @param[in] numTermsPerReg a list of the number of \\p coeff and \\p exponent terms supplied for each variable/sub-register\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if any element of \\p numTermsPerReg is < 1\n - if \\p exponents contains a negative number\n - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT\n @author Tyson Jones"]
1291    pub fn applyMultiVarPhaseFunc(
1292        qureg: Qureg,
1293        qubits: *mut ::std::os::raw::c_int,
1294        numQubitsPerReg: *mut ::std::os::raw::c_int,
1295        numRegs: ::std::os::raw::c_int,
1296        encoding: bitEncoding,
1297        coeffs: *mut f64,
1298        exponents: *mut f64,
1299        numTermsPerReg: *mut ::std::os::raw::c_int,
1300    );
1301}
1302extern "C" {
1303    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n multi-variable exponential polynomial \"phase function\", and an explicit set of 'overriding'\n values at specific state indices.\n\n See applyMultiVarPhaseFunc() first for a full description.\n\n - As in applyMultiVarPhaseFunc(), the arguments \\p coeffs and \\p exponents specify a\n   multi-variable phase function \\f$f(\\vec{r})\\f$, where \\f$\\vec{r}\\f$ is determined by\n   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n\n\n - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies\n   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n\n   While flat, \\p overrideInds should be imagined grouped into sub-lists of length\n   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n\n   Each sublist corresponds to a single element of \\p overridePhases. \\n\n   For example,\n   ```\n   int numRegs = 3;\n   int numOverrides = 2;\n   long long int overrideInds[] = { 0,0,0,   1,2,3  };\n   qreal overridePhases[]       = { M_PI,   - M_PI };\n   ```\n   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$\n   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)\n   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0))\\f$.\\n\\n\n   > Note that you cannot use applyMultiVarPhaseFuncOverrides() to override divergences\n   > in \\f$f(\\vec{r})\\f$, since each diverging value \\f$r_j\\f$ would need to be overriden\n   > as an \\f$\\vec{r}\\f$ coordinate for every basis state of the other registers; the number\n   > of overrides grows exponentially. Ergo, if \\p exponents contains a negative number\n   > (diverging at \\f$r_j=0\\f$), or \\p exponents contains a fractional number despite\n   > \\p encoding <b>=</b> ::TWOS_COMPLEMENT (producing complex phases at negative indices),\n   > you must instead call applyPhaseFuncOverrides() for each variable in turn and\n   > override the diverging \\f$r_j\\f$ (each independently of the other registers).\n\n - The interpreted overrides can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyMultiVarPhaseFuncOverrides(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyMultiVarPhaseFunc() multiplied ...\n   //   though with overrides\n   //     |x=0, y=0, z=0> -> exp(i 3.14159)\n   //     |x=1, y=2, z=3> -> exp(i (-3.14159))\n   ```\n \\n\n\n\n @see\n - applyNamedPhaseFunc() for a set of specific and potentially multi-variable phase functions.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density-matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] coeffs the coefficients of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$\n @param[in] exponents the exponents of all terms of the exponential polynomial phase function \\f$f(\\vec{r})\\f$\n @param[in] numTermsPerReg a list of the number of \\p coeff and \\p exponent terms supplied for each variable/sub-register\n @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change\n @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds\n @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if any element of \\p numTermsPerReg is < 1\n - if \\p exponents contains a negative number\n - if \\p exponents contains a fractional number despite \\p encoding <b>=</b> ::TWOS_COMPLEMENT\n - 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)\n - if \\p numOverrides < 0\n @author Tyson Jones"]
1304    pub fn applyMultiVarPhaseFuncOverrides(
1305        qureg: Qureg,
1306        qubits: *mut ::std::os::raw::c_int,
1307        numQubitsPerReg: *mut ::std::os::raw::c_int,
1308        numRegs: ::std::os::raw::c_int,
1309        encoding: bitEncoding,
1310        coeffs: *mut f64,
1311        exponents: *mut f64,
1312        numTermsPerReg: *mut ::std::os::raw::c_int,
1313        overrideInds: *mut ::std::os::raw::c_longlong,
1314        overridePhases: *mut f64,
1315        numOverrides: ::std::os::raw::c_int,
1316    );
1317}
1318extern "C" {
1319    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n named (and potentially multi-variable) phase function.\n\n This effects a diagonal unitary operator, with a phase function \\f$f(\\vec{r})\\f$ which may not be\n simply expressible as an exponential polynomial in functions applyPhaseFunc() and applyMultiVarPhaseFunc().\n\n Arguments \\p qubits and \\p numQubitsPerReg encode sub-registers of \\p qureg in the same\n manner as in applyMultiVarPhaseFunc():\n - Lists \\p qubits and \\p numQubitsPerReg together describe #`numRegs` sub-registers of \\p qureg,\n   which can each contain a different number of qubits. \\n\n   Although \\p qubits is a flat list of unique qubit indices, it should be imagined grouped into #`numRegs` sub-lists,\n   of lengths given by \\p numQubitsPerReg. \\n\\n\n   For example,\n   ```\n      int qubits[] =          {0,1,  3,4,5,  7}\n      int numQubitsPerReg[] = {2,    3,      1};\n      int numRegs = 3;\n   ```\n   describes three sub-registers, which are bolded below in an eight-qubit zero-state.\n   \\f[\n      |r_3\\rangle \\; |0\\rangle \\; |r_2\\rangle \\; |0\\rangle \\; |r_1\\rangle =\n      |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle\n   \\f]\n   Note that the qubits need not be ordered increasing, and qubits within each sub-register\n   are assumed ordered least to most significant in that sub-register.\\n\\n\n   > List \\p qubits should have length equal to the sum of elements in \\p numQubitsPerReg.\n\n - Each sub-register is associated with a variable \\f$r_j\\f$ in phase function \\f$f(\\vec{r})\\f$. \\n\n   For a given computational basis state of \\p qureg, the value of each variable is determined\n   by the binary value in the corresponding sub-register, when intepreted with ::bitEncoding \\p encoding. \\n\n   See ::bitEncoding for more information.\\n\\n\n\n - Argument \\p functionNameCode determines the phase function \\f$f(\\vec{r})\\f$.\\n\n   For example,\n   ```\n   int numRegs = 3;\n   enum phaseFunc functionNameCode = NORM;\n   ```\n   describes phase function\n   \\f[\n      f(\\vec{r}) = \\sqrt{ {r_1}^2 + {r_2}^2 + {r_3} ^2 }.\n   \\f]\n   See ::phaseFunc for a list and description of all named phase functions. \\n\n   Some phase functions, like \\p SCALED_NORM, require passing additional parameters, through\n   the function applyParamNamedPhaseFunc().\\n\\n\n   > If the phase function \\f$f(\\vec{r})\\f$ diverges at one or more \\f$\\vec{r}\\f$ values, you should instead\n   > use applyNamedPhaseFuncOverrides() and specify explicit phase changes for these coordinates.\n   > Otherwise, the corresponding amplitudes of \\p qureg will become indeterminate (like `NaN`). \\n\n\n - The function \\f$f(\\vec{r})\\f$ specifies the phase change to induce upon amplitude \\f$\\alpha\\f$\n   of computational basis state with the nominated sub-registers encoding values \\f$r_1, \\; \\dots\\f$.\n   \\f[\n    \\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.\n   \\f]\n   For example, using the sub-registers in the above example and \\p encoding <b>=</b> \\p UNSIGNED, the\n   following states receive amplitude factors:\n   \\f[\n   \\begin{aligned}\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{00}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=1)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{10}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=2)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=3)} \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{000}\\rangle \\; |1\\rangle \\; |\\mathbf{00}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=0,r_1=0)} \\\\\n   & \\;\\;\\;\\vdots \\\\\n     |\\mathbf{0}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{01}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=0,r_2=7,r_1=1)} \\\\\n   & \\;\\;\\;\\vdots \\\\\n     |\\mathbf{1}\\rangle \\; |0\\rangle \\; |\\mathbf{111}\\rangle \\; |0\\rangle \\; |\\mathbf{11}\\rangle &\n        \\rightarrow \\,\n            e^{i f(r_3=1,r_2=7,r_1=3)}\n   \\end{aligned}\n   \\f]\\n\n\n - If \\p qureg is a density matrix, its elements are modified to\n   \\f[\n\\alpha \\, |j\\rangle\\langle k| \\; \\rightarrow \\;\n\\exp(i (f(\\vec{r}_j) \\, - \\, f(\\vec{r}_k))) \\; \\alpha \\, |j\\rangle\\langle k|\n   \\f]\n   where \\f$f(\\vec{r}_j)\\f$ and \\f$f(\\vec{r}_k)\\f$ are determined as above. This is equivalent\n   to modification\n   \\f[\n          \\rho \\; \\rightarrow \\; \\hat{D} \\, \\rho \\, \\hat{D}^\\dagger\n   \\f]\n   where \\f$\\hat{D}\\f$ is the diagonal unitary\n   \\f[\n      \\hat{D} = \\text{diag}\\, \\{ \\; e^{i f(\\vec{r_0})}, \\; e^{i f(\\vec{r_1})}, \\; \\dots \\; \\}.\n   \\f]\\n\n\n - The interpreted phase function can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyNamedPhaseFunc(qureg, ..., INVERSE_DISTANCE, ... );\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyNamedPhaseFunc() multiplied a complex scalar of form\n   //     exp(i 1 / sqrt((x-y)^2 + (z-t)^2))\n   ```\n \\n\n\n\n @see\n - applyNamedPhaseFuncOverrides() to additionally specify phase values for specific sub-register indices.\n - applyParamNamedPhaseFunc() to specify named phase functions which require additional parameters.\n - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function.\n - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density-matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r})\\f$\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if \\p functionNameCode is not a valid ::phaseFunc\n - if \\p functionNameCode requires additional parameters, which must instead be passed with applyParamNamedPhaseFunc()\n @author Tyson Jones"]
1320    pub fn applyNamedPhaseFunc(
1321        qureg: Qureg,
1322        qubits: *mut ::std::os::raw::c_int,
1323        numQubitsPerReg: *mut ::std::os::raw::c_int,
1324        numRegs: ::std::os::raw::c_int,
1325        encoding: bitEncoding,
1326        functionNameCode: phaseFunc,
1327    );
1328}
1329extern "C" {
1330    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n named (and potentially multi-variable) phase function, and an explicit set of 'overriding'\n values at specific state indices.\n\n See applyNamedPhaseFunc() first for a full description.\n\n - As in applyNamedPhaseFunc(), \\p functionNameCode specifies a\n   multi-variable phase function \\f$f(\\vec{r})\\f$, where \\f$\\vec{r}\\f$ is determined by\n   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n\n\n - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies\n   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n\n   While flat, \\p overrideInds should be imagined grouped into sub-lists of length\n   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n\n   Each sublist corresponds to a single element of \\p overridePhases. \\n\n   For example,\n   ```\n   int numRegs = 3;\n   int numOverrides = 2;\n   long long int overrideInds[] = { 0,0,0,   1,2,3  };\n   qreal overridePhases[]       = { M_PI,   - M_PI };\n   ```\n   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$\n   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)\n   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0))\\f$.\\n\\n\n\n - The interpreted overrides can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyNamedPhaseFuncOverrides(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyNamedPhaseFunc() multiplied ...\n   //   though with overrides\n   //     |x=0, y=0, z=0> -> exp(i 3.14159)\n   //     |x=1, y=2, z=3> -> exp(i (-3.14159))\n   ```\n \\n\n\n\n @see\n - applyParamNamedPhaseFuncOverrides() to specify <em>parameterised</em> named phase functions, with phase overrides.\n - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function.\n - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector pr density-matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r})\\f$\n @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change\n @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds\n @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if \\p functionNameCode is not a valid ::phaseFunc\n - if \\p functionNameCode requires additional parameters, which must instead be passed with applyParamNamedPhaseFunc()\n - 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)\n - if \\p numOverrides < 0\n @author Tyson Jones"]
1331    pub fn applyNamedPhaseFuncOverrides(
1332        qureg: Qureg,
1333        qubits: *mut ::std::os::raw::c_int,
1334        numQubitsPerReg: *mut ::std::os::raw::c_int,
1335        numRegs: ::std::os::raw::c_int,
1336        encoding: bitEncoding,
1337        functionNameCode: phaseFunc,
1338        overrideInds: *mut ::std::os::raw::c_longlong,
1339        overridePhases: *mut f64,
1340        numOverrides: ::std::os::raw::c_int,
1341    );
1342}
1343extern "C" {
1344    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n named, paramaterized (and potentially multi-variable) phase function.\n\n See applyNamedPhaseFunc() for full documentation. \\n\n This function merely accepts additional ::phaseFunc names which accept one (or more) parameters.\n\n - Argument \\p functionNameCode, which determines the phase function \\f$f(\\vec{r}, \\vec{\\theta})\\f$,\n   can include parameterised ::phaseFunc names like \\p SCALED_NORM, which require additional\n   parameters \\f$\\vec{\\theta}\\f$ passed via list \\p params.\\n\n   For example,\n   ```\n   enum phaseFunc functionNameCode = SCALED_PRODUCT;\n   qreal params[] = {0.5};\n   int numParams = 1;\n   applyParamNamedPhaseFunc(..., functionNameCode, params, numParams);\n   ```\n   invokes phase function\n   \\f[\n      f(\\vec{r}, \\theta)|_{\\theta=0.5} \\; = \\; 0.5 \\prod_j^{\\text{numRegs}} \\; r_j\\,.\n   \\f]\n   See ::phaseFunc for all named phased functions.\n\n - Functions with divergences, like \\p INVERSE_NORM and \\p SCALED_INVERSE_DISTANCE, must accompany\n   an extra parameter to specify an overriding phase at the divergence. For example,\n   ```\n   enum phaseFunc functionNameCode = SCALED_INVERSE_NORM;\n   qreal params[] = {0.5, M_PI};\n   int numParams = 2;\n   applyParamNamedPhaseFunc(..., functionNameCode, params, numParams);\n   ```\n   invokes phase function\n   \\f[\n      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}.\n   \\f]\n   Notice the order of the parameters matches the order of the words in the \\p phaseFunc.\n   > Functions \\p SCALED_INVERSE_SHIFTED_NORM and \\p SCALED_INVERSE_SHIFTED_DISTANCE,\n   > which can have denominators arbitrarily close to zero, will invoke the\n   > divergence parameter whenever the denominator is smaller than (or equal to)\n   > machine precision `REAL_EPS`.\n\n - Functions allowing the shifting of unweighted sub-register values, which are \\p SCALED_INVERSE_SHIFTED_NORM,\n   and \\p SCALED_INVERSE_SHIFTED_DISTANCE, need these shift values to be passed in the \\p params\n   argument _after_ the scaling and divergence override parameters listed above. The function\n   \\p SCALED_INVERSE_SHIFTED_NORM needs as many extra parameters, as there are sub-registers;\n   \\p SCALED_INVERSE_SHIFTED_DISTANCE needs one extra parameter for each pair of sub-registers.\n   For example,\n   ```\n   enum phaseFunc functionNameCode = SCALED_INVERSE_SHIFTED_NORM;\n   int qubits[] = {0,1,2,3, 4,5,6,7};\n   int qubitsPerReg[] = {4, 4};\n   qreal params[] = {0.5, M_PI, 0.8, -0.3};\n   int numParams = 4;\n   applyParamNamedPhaseFunc(..., qubits, qubitsPerReg, 2, ..., functionNameCode, params, numParams);\n   ```\n   invokes phase function\n   \\f[\n      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}.\n   \\f]\n   and\n   ```\n   enum phaseFunc functionNameCode = SCALED_INVERSE_SHIFTED_DISTANCE;\n   int qubits[] = {0,1, 2,3, 4,5, 6,7};\n   int qubitsPerReg[] = {2, 2, 2, 2};\n   qreal params[] = {0.5, M_PI, 0.8, -0.3};\n   int numParams = 4;\n   applyParamNamedPhaseFunc(..., qubits, qubitsPerReg, 4, ..., functionNameCode, params, numParams);\n   ```\n   invokes phase function\n   \\f[\n      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}.\n   \\f]\n\n - Function \\p SCALED_INVERSE_SHIFTED_WEIGHTED_DISTANCE, which effects phase\n   \\f[\n      \\text{coeff}/\\sqrt{f_x \\, (x_1-x_2-\\Delta_x)^2 + f_y \\; (y_1-y_2-\\Delta_y)^2 + \\dots}\n   \\f]\n   (and phase \\f$\\phi\\f$ at divergences)\n   accepts parameters in the following order:\n   \\f[\n      \\{  \\; \\text{coeff}, \\; \\phi, \\; f_x, \\; \\Delta x, \\; f_y, \\; \\Delta y, \\; \\dots \\;   \\}\n   \\f]\n   > Note that where the denominator's \\f$\\text{sqrt}\\f$ argument would be negative (and the resulting\n   > phase function _complex_), the phase is instead set to the divergence parameter \\f$\\phi\\f$.\n\n > You can further override \\f$f(\\vec{r}, \\vec{\\theta})\\f$ at one or more \\f$\\vec{r}\\f$ values\n > via applyParamNamedPhaseFuncOverrides().\n\n - The interpreted parameterised phase function can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyParamNamedPhaseFunc(...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyNamedPhaseFunc() multiplied a complex scalar of form\n   //     exp(i (-0.5) / (x y z))\n   ```\n \\n\n\n\n @see\n - applyParamNamedPhaseFuncOverrides() to additionally specify phase values for specific sub-register indices.\n - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function.\n - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density-matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r}, \\vec{\\theta})\\f$\n @param[in] params a list of any additional parameters needed by the ::phaseFunc \\p functionNameCode\n @param[in] numParams the length of list \\p params\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if \\p functionNameCode is not a valid ::phaseFunc\n - if \\p numParams is incompatible with \\p functionNameCode (for example, no parameters were passed to \\p SCALED_PRODUCT)\n @author Tyson Jones\n @author Richard Meister (shifted functions)"]
1345    pub fn applyParamNamedPhaseFunc(
1346        qureg: Qureg,
1347        qubits: *mut ::std::os::raw::c_int,
1348        numQubitsPerReg: *mut ::std::os::raw::c_int,
1349        numRegs: ::std::os::raw::c_int,
1350        encoding: bitEncoding,
1351        functionNameCode: phaseFunc,
1352        params: *mut f64,
1353        numParams: ::std::os::raw::c_int,
1354    );
1355}
1356extern "C" {
1357    #[doc = " Induces a phase change upon each amplitude of \\p qureg, determined by a\n named, parameterised (and potentially multi-variable) phase function, and an explicit set of 'overriding'\n values at specific state indices.\n\n See applyParamNamedPhaseFunc() and applyNamedPhaseFunc() first for a full description.\n\n - As in applyParamNamedPhaseFunc(), \\p functionNameCode specifies a parameterised\n   multi-variable phase function \\f$f(\\vec{r}, \\vec{\\theta})\\f$, where \\f$\\vec{\\theta}\\f$ is\n   passed in list \\p params, and \\f$\\vec{r}\\f$ is determined both by\n   the sub-registers in \\p qubits, and ::bitEncoding \\p encoding for each basis state of \\p qureg.\\n\\n\n\n - Additionally, \\p overrideInds is a list of length \\p numOverrides which specifies\n   the values of \\f$\\vec{r}\\f$ for which to explicitly set the induced phase change.\\n\n   While flat, \\p overrideInds should be imagined grouped into sub-lists of length\n   \\p numRegs, which specify the full \\f$\\{r_1,\\; \\dots \\;r_{\\text{numRegs}} \\} \\f$ coordinate to override. \\n\n   Each sublist corresponds to a single element of \\p overridePhases. \\n\n   For example,\n   ```\n   int numRegs = 3;\n   int numOverrides = 2;\n   long long int overrideInds[] = { 0,0,0,   1,2,3  };\n   qreal overridePhases[]       = { M_PI,   - M_PI };\n   ```\n   denotes that any basis state of \\p qureg with sub-register values \\f$\\{r_3,r_2,r_1\\} = \\{0, 0, 0\\}\\f$\n   (or \\f$\\{r_3,r_2,r_1\\} = \\{1,2,3\\}\\f$) should receive phase change \\f$\\pi\\f$ (or \\f$-\\pi\\f$)\n   in lieu of \\f$\\exp(i f(r_3=0,r_2=0,r_1=0, \\vec{\\theta}))\\f$.\\n\\n\n\n - The interpreted overrides can be previewed in the QASM log, as a comment. \\n\n   For example:\n   ```\n   startRecordingQASM(qureg);\n   applyParamNamedPhaseFuncOverrides(qureg, ...);\n   printRecordedQASM(qureg);\n   ```\n   may show\n   ```\n   // Here, applyParamNamedPhaseFunc() multiplied ...\n   //   though with overrides\n   //     |x=0, y=0, z=0> -> exp(i 3.14159)\n   //     |x=1, y=2, z=3> -> exp(i (-3.14159))\n   ```\n \\n\n\n\n @see\n - applyPhaseFunc() to specify a general single-variable exponential polynomial phase function.\n - applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function.\n - applyDiagonalOp() to apply a non-unitary diagonal operator.\n\n @ingroup operator\n @param[in,out] qureg the state-vector or density-matrix to be modified\n @param[in] qubits a list of all the qubit indices contained in each sub-register\n @param[in] numQubitsPerReg a list of the lengths of each sub-list in \\p qubits\n @param[in] numRegs the number of sub-registers, which is the length of both \\p numQubitsPerReg and \\p numTermsPerReg\n @param[in] encoding the ::bitEncoding under which to infer the binary value \\f$r_j\\f$ from the bits of a sub-register\n @param[in] functionNameCode the ::phaseFunc \\f$f(\\vec{r}, \\vec{\\theta})\\f$\n @param[in] params a list of any additional parameters \\f$\\vec{\\theta}\\f$ needed by the ::phaseFunc \\p functionNameCode\n @param[in] numParams the length of list \\p params\n @param[in] overrideInds a flattened list of sub-register coordinates (values of \\f$\\vec{r}\\f$) of which to explicit set the phase change\n @param[in] overridePhases a list of replacement phase changes, for the corresponding \\f$\\vec{r}\\f$ values in \\p overrideInds\n @param[in] numOverrides the lengths of list \\p overridePhases (but not necessarily of \\p overrideInds)\n @exception invalidQuESTInputError()\n - if any qubit in \\p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < `qureg.numQubitsRepresented`)\n - if the elements of \\p qubits are not unique (including if sub-registers overlap)\n - if \\p numRegs <= 0 or \\p numRegs > 100 (constrained by `MAX_NUM_REGS_APPLY_ARBITRARY_PHASE` in QuEST_precision.h)\n - if \\p encoding is not a valid ::bitEncoding\n - 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)\n - if \\p functionNameCode is not a valid ::phaseFunc\n - if \\p numParams is incompatible with \\p functionNameCode (for example, no parameters were passed to \\p SCALED_PRODUCT)\n - 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)\n - if \\p numOverrides < 0\n @author Tyson Jones"]
1358    pub fn applyParamNamedPhaseFuncOverrides(
1359        qureg: Qureg,
1360        qubits: *mut ::std::os::raw::c_int,
1361        numQubitsPerReg: *mut ::std::os::raw::c_int,
1362        numRegs: ::std::os::raw::c_int,
1363        encoding: bitEncoding,
1364        functionNameCode: phaseFunc,
1365        params: *mut f64,
1366        numParams: ::std::os::raw::c_int,
1367        overrideInds: *mut ::std::os::raw::c_longlong,
1368        overridePhases: *mut f64,
1369        numOverrides: ::std::os::raw::c_int,
1370    );
1371}
1372extern "C" {
1373    #[doc = " Applies the quantum Fourier transform (QFT) to the entirety of \\p qureg.\n The effected unitary circuit (shown here for 4 qubits, bottom qubit is <b>0</b>) resembles\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\draw (-2, 5) -- (23, 5);\n\\draw (-2, 3) -- (23, 3);\n\\draw (-2, 1) -- (23, 1);\n\\draw (-2, -1) -- (23, -1);\n\n\\draw[fill=white] (-1, 4) -- (-1, 6) -- (1, 6) -- (1,4) -- cycle;\n\\node[draw=none] at (0, 5) {H};\n\n\\draw(2, 5) -- (2, 3);\n\\draw[fill=black] (2, 5) circle (.2);\n\\draw[fill=black] (2, 3) circle (.2);\n\\draw(4, 5) -- (4, 1);\n\\draw[fill=black] (4, 5) circle (.2);\n\\draw[fill=black] (4, 1) circle (.2);\n\\draw(6, 5) -- (6, -1);\n\\draw[fill=black] (6, 5) circle (.2);\n\\draw[fill=black] (6, -1) circle (.2);\n\n\\draw[fill=white] (-1+8, 4-2) -- (-1+8, 6-2) -- (1+8, 6-2) -- (1+8,4-2) -- cycle;\n\\node[draw=none] at (8, 5-2) {H};\n\n\\draw(10, 5-2) -- (10, 3-2);\n\\draw[fill=black] (10, 5-2) circle (.2);\n\\draw[fill=black] (10, 3-2) circle (.2);\n\\draw(12, 5-2) -- (12, 3-4);\n\\draw[fill=black] (12, 5-2) circle (.2);\n\\draw[fill=black] (12, 3-4) circle (.2);\n\n\\draw[fill=white] (-1+8+6, 4-4) -- (-1+8+6, 6-4) -- (1+8+6, 6-4) -- (1+8+6,4-4) -- cycle;\n\\node[draw=none] at (8+6, 5-4) {H};\n\n\\draw(16, 5-2-2) -- (16, 3-4);\n\\draw[fill=black] (16, 5-2-2) circle (.2);\n\\draw[fill=black] (16, 3-4) circle (.2);\n\n\\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;\n\\node[draw=none] at (8+6+4, 5-4-2) {H};\n\n\\draw (20, 5) -- (20, -1);\n\\draw (20 - .35, 5 + .35) -- (20 + .35, 5 - .35);\n\\draw (20 - .35, 5 - .35) -- (20 + .35, 5 + .35);\n\\draw (20 - .35, -1 + .35) -- (20 + .35, -1 - .35);\n\\draw (20 - .35, -1 - .35) -- (20 + .35, -1 + .35);\n\\draw (22, 3) -- (22, 1);\n\\draw (22 - .35, 3 + .35) -- (22 + .35, 3 - .35);\n\\draw (22 - .35, 3 - .35) -- (22 + .35, 3 + .35);\n\\draw (22 - .35, 1 + .35) -- (22 + .35, 1 - .35);\n\\draw (22 - .35, 1 - .35) -- (22 + .35, 1 + .35);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n though is performed more efficiently.\n\n - If \\p qureg is a state-vector, the output amplitudes are the discrete Fourier\n   transform (DFT) of the input amplitudes, in the exact ordering. This is true\n   even if \\p qureg is unnormalised. \\n\n   Precisely,\n   \\f[\n      \\text{QFT} \\, \\left(  \\sum\\limits_{x=0}^{2^N-1} \\alpha_x |x\\rangle \\right)\n      =\n      \\frac{1}{\\sqrt{2^N}}\n       \\sum\\limits_{x=0}^{2^N-1} \\left(\n           \\sum\\limits_{y=0}^{2^N-1} e^{2 \\pi \\, i \\, x \\, y / 2^N} \\; \\alpha_y\n       \\right) |x\\rangle\n   \\f]\n\n - If \\p qureg is a density matrix \\f$\\rho\\f$, it will be changed under the unitary action\n   of the QFT. This can be imagined as each mixed state-vector undergoing the DFT\n   on its amplitudes. This is true even if \\p qureg is unnormalised.\n   \\f[\n      \\rho \\; \\rightarrow \\; \\text{QFT} \\; \\rho \\; \\text{QFT}^{\\dagger}\n   \\f]\n\n > This function merges contiguous controlled-phase gates into single invocations\n > of applyNamedPhaseFunc(), and hence is significantly faster than performing\n > the QFT circuit directly.\n\n > Furthermore, in distributed mode, this function requires only \\f$\\log_2(\\text{\\#nodes})\\f$\n > rounds of pair-wise\n > communication, and hence is exponentially faster than directly performing the\n > DFT on the amplitudes of \\p qureg.\n\n @see\n - applyQFT() to apply the QFT to a sub-register of \\p qureg.\n\n @ingroup operator\n @param[in,out] qureg a state-vector or density matrix to modify\n @author Tyson Jones"]
1374    pub fn applyFullQFT(qureg: Qureg);
1375}
1376extern "C" {
1377    #[doc = " Applies the quantum Fourier transform (QFT) to a specific subset of qubits\n of the register \\p qureg.\n\n The order of \\p qubits affects the ultimate unitary.\n The canonical full-state QFT (applyFullQFT()) is achieved by targeting every\n qubit in increasing order.\n\n The effected unitary circuit (shown here for \\p numQubits <b>= 4</b>) resembles\n@htmlonly\n<center>\n<script type=\"text/tikz\">\n\\begin{tikzpicture}[scale=.5]\n\\draw (-2, 5) -- (23, 5);    \\node[draw=none] at (-4,5) {qubits[3]};\n\\draw (-2, 3) -- (23, 3);    \\node[draw=none] at (-4,3) {qubits[2]};\n\\draw (-2, 1) -- (23, 1);     \\node[draw=none] at (-4,1) {qubits[1]};\n\\draw (-2, -1) -- (23, -1);  \\node[draw=none] at (-4,-1) {qubits[0]};\n\n\\draw[fill=white] (-1, 4) -- (-1, 6) -- (1, 6) -- (1,4) -- cycle;\n\\node[draw=none] at (0, 5) {H};\n\n\\draw(2, 5) -- (2, 3);\n\\draw[fill=black] (2, 5) circle (.2);\n\\draw[fill=black] (2, 3) circle (.2);\n\\draw(4, 5) -- (4, 1);\n\\draw[fill=black] (4, 5) circle (.2);\n\\draw[fill=black] (4, 1) circle (.2);\n\\draw(6, 5) -- (6, -1);\n\\draw[fill=black] (6, 5) circle (.2);\n\\draw[fill=black] (6, -1) circle (.2);\n\n\\draw[fill=white] (-1+8, 4-2) -- (-1+8, 6-2) -- (1+8, 6-2) -- (1+8,4-2) -- cycle;\n\\node[draw=none] at (8, 5-2) {H};\n\n\\draw(10, 5-2) -- (10, 3-2);\n\\draw[fill=black] (10, 5-2) circle (.2);\n\\draw[fill=black] (10, 3-2) circle (.2);\n\\draw(12, 5-2) -- (12, 3-4);\n\\draw[fill=black] (12, 5-2) circle (.2);\n\\draw[fill=black] (12, 3-4) circle (.2);\n\n\\draw[fill=white] (-1+8+6, 4-4) -- (-1+8+6, 6-4) -- (1+8+6, 6-4) -- (1+8+6,4-4) -- cycle;\n\\node[draw=none] at (8+6, 5-4) {H};\n\n\\draw(16, 5-2-2) -- (16, 3-4);\n\\draw[fill=black] (16, 5-2-2) circle (.2);\n\\draw[fill=black] (16, 3-4) circle (.2);\n\n\\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;\n\\node[draw=none] at (8+6+4, 5-4-2) {H};\n\n\\draw (20, 5) -- (20, -1);\n\\draw (20 - .35, 5 + .35) -- (20 + .35, 5 - .35);\n\\draw (20 - .35, 5 - .35) -- (20 + .35, 5 + .35);\n\\draw (20 - .35, -1 + .35) -- (20 + .35, -1 - .35);\n\\draw (20 - .35, -1 - .35) -- (20 + .35, -1 + .35);\n\\draw (22, 3) -- (22, 1);\n\\draw (22 - .35, 3 + .35) -- (22 + .35, 3 - .35);\n\\draw (22 - .35, 3 - .35) -- (22 + .35, 3 + .35);\n\\draw (22 - .35, 1 + .35) -- (22 + .35, 1 - .35);\n\\draw (22 - .35, 1 - .35) -- (22 + .35, 1 + .35);\n\\end{tikzpicture}\n</script>\n</center>\n@endhtmlonly\n though is performed more efficiently.\n\n - If \\p qureg is a state-vector, the output amplitudes are a kronecker product of\n   the discrete Fourier transform (DFT) acting upon the targeted amplitudes, and the\n   remaining. \\n\n   Precisely,\n   - let \\f$|x,r\\rangle\\f$ represent a computational basis state where\n     \\f$x\\f$ is the binary value of the targeted qubits, and \\f$r\\f$ is the binary value\n     of the remaining qubits.\n   - let \\f$|x_j,r_j\\rangle\\f$ be the \\f$j\\text{th}\\f$ such state.\n   - let \\f$n =\\f$ \\p numQubits, and \\f$N =\\f$ `qureg.numQubitsRepresented`.\\n\n Then, this function effects\n   \\f[\n      (\\text{QFT}\\otimes 1) \\, \\left(  \\sum\\limits_{j=0}^{2^N-1} \\alpha_j \\, |x_j,r_j\\rangle \\right)\n      =\n      \\frac{1}{\\sqrt{2^n}}\n       \\sum\\limits_{j=0}^{2^N-1} \\alpha_j \\left(\n           \\sum\\limits_{y=0}^{2^n-1} e^{2 \\pi \\, i \\, x_j \\, y / 2^n} \\;\n           |y,r_j \\rangle\n       \\right)\n   \\f]\n\n - If \\p qureg is a density matrix \\f$\\rho\\f$, it will be changed under the unitary action\n   of the QFT. This can be imagined as each mixed state-vector undergoing the DFT\n   on its amplitudes. This is true even if \\p qureg is unnormalised.\n   \\f[\n      \\rho \\; \\rightarrow \\; \\text{QFT} \\; \\rho \\; \\text{QFT}^{\\dagger}\n   \\f]\n\n > This function merges contiguous controlled-phase gates into single invocations\n > of applyNamedPhaseFunc(), and hence is significantly faster than performing\n > the QFT circuit directly.\n\n > Furthermore, in distributed mode, this function requires only \\f$\\log_2(\\text{\\#nodes})\\f$\n > rounds of pair-wise\n > communication, and hence is exponentially faster than directly performing the\n > DFT on the amplitudes of \\p qureg.\n\n @see\n - applyFullQFT() to apply the QFT to the entirety of \\p qureg.\n\n @ingroup operator\n @param[in,out] qureg a state-vector or density matrix to modify\n @param[in] qubits a list of the qubits to operate the QFT upon\n @param[in] numQubits the length of list \\p qubits\n @throws invalidQuESTInputError()\n - if any qubit in \\p qubits is invalid, i.e. outside <b>[0, </b>`qureg.numQubitsRepresented`<b>)</b>\n - if \\p qubits contain any repetitions\n - if \\p numQubits <b>< 1</b>\n - if \\p numQubits <b>></b>`qureg.numQubitsRepresented`\n @throws segmentation-fault\n - if \\p qubits contains fewer elements than \\p numQubits\n @author Tyson Jones"]
1378    pub fn applyQFT(
1379        qureg: Qureg,
1380        qubits: *mut ::std::os::raw::c_int,
1381        numQubits: ::std::os::raw::c_int,
1382    );
1383}
1384extern "C" {
1385    #[doc = " Force the target \\p qubit of \\p qureg into the given classical \\p outcome, via a\n non-renormalising projection.\n\n This function zeroes all amplitudes in the state-vector or density-matrix which\n correspond to the opposite \\p outcome given. Unlike collapseToOutcome(), it does\n not thereafter normalise \\p qureg, and hence may leave it in a non-physical state.\n\n Note there is no requirement that the \\p outcome state has a non-zero proability, and hence\n this function may leave \\p qureg in a blank state, like that produced by initBlankState().\n\n @see\n - collapseToOutcome() for a norm-preserving equivalent, like a forced measurement\n\n @ingroup operator\n @param[in,out] qureg a state-vector or density matrix to modify\n @param[in] qubit the qubit to which to apply the projector\n @param[in] outcome the single-qubit outcome (`0` or `1`) to project \\p qubit into\n @throws invalidQuESTInputError()\n - if \\p qubit is outside [0, `qureg.numQubitsRepresented`)\n - if \\p outcome is not in {0,1}\n @author Tyson Jones"]
1386    pub fn applyProjector(
1387        qureg: Qureg,
1388        qubit: ::std::os::raw::c_int,
1389        outcome: ::std::os::raw::c_int,
1390    );
1391}
1392extern "C" {
1393    pub fn statevec_twoQubitUnitary(
1394        qureg: Qureg,
1395        targetQubit1: ::std::os::raw::c_int,
1396        targetQubit2: ::std::os::raw::c_int,
1397        u: ComplexMatrix4,
1398    );
1399}