Skip to content

Commit 738ca89

Browse files
added postMultiply functions (#657)
For every existing multiply*() function, such as multiplyCompMatr(), this commit adds a corresponding postMultiply*() function which operates upon a density matrix from the right-hand side. This is useful for preparing density matrices in non-physical states which appear as sub-expressions within things like commutators and the Linbladian. Implementing these functions involved: - updating the templating of "any target dense matrix" function, inadvertently simplifying the associated instantiation and dispatch macros by re-using those for the "any target diagonal matrix" function - adding new utilities and logic for obtaining/effecting the transpose of a function, to undo the transpose effected via operation upon the bra-qubits of a vectorised density matrix - extending and refactoring the unit tests with postMultiply references We additionally added the below expected but missing functions from the API: - multiplyPauliX - multiplyPauliY - multiplyPauliZ
1 parent aa11c23 commit 738ca89

19 files changed

+1078
-267
lines changed

quest/include/operations.h

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,65 @@ extern "C" {
8989
* - getCompMatr1()
9090
* - getInlineCompMatr1()
9191
* - applyCompMatr1()
92+
* - postMultiplyCompMatr1()
9293
* - applyQubitProjector()
9394
* - multiplyCompMatr()
9495
* @author Tyson Jones
9596
*/
9697
void multiplyCompMatr1(Qureg qureg, int target, CompMatr1 matrix);
9798

9899

100+
/** @notyettested
101+
*
102+
* Multiplies a general one-qubit dense @p matrix upon the specified @p target
103+
* qubit of the density matrix @p qureg, from the right-hand side.
104+
*
105+
* @formulae
106+
* Let @f$ \dmrho = @f$ @p qureg, @f$ \hat{M} = @f$ @p matrix and @f$ t = @f$ @p target,
107+
* and notate @f$\hat{M}_t@f$ as per applyCompMatr1(). Unlike applyCompMatr1() however,
108+
* this function only ever right-multiplies @p matrix upon @p qureg.
109+
*
110+
* Explicitly
111+
* @f[
112+
\dmrho \rightarrow \dmrho \, \hat{M}_t
113+
* @f]
114+
* where @f$ \hat{M} @f$ is not conjugated nor transposed, and there are no additional
115+
* constraints like unitarity.
116+
*
117+
* In general, this function will break the normalisation of @p qureg and result in a
118+
* non-physical state, and is useful for preparing sub-expressions of formulae like
119+
* the Linbladian.
120+
*
121+
* @myexample
122+
* ```
123+
Qureg qureg = createDensityQureg(5);
124+
125+
CompMatr1 matrix = getInlineCompMatr1({
126+
{0.1, 0.2},
127+
{0.3i, 0.4i}
128+
});
129+
130+
postMultiplyCompMatr1(qureg, 2, matrix);
131+
* ```
132+
*
133+
* @param[in,out] qureg the state to modify.
134+
* @param[in] target the index of the target qubit.
135+
* @param[in] matrix the Z-basis matrix to post-multiply.
136+
* @throws @validationerror
137+
* - if @p qureg or @p matrix are uninitialised.
138+
* - if @p qureg is not a density matrix.
139+
* - if @p target is an invalid qubit index.
140+
* @see
141+
* - getCompMatr1()
142+
* - getInlineCompMatr1()
143+
* - applyCompMatr1()
144+
* - multiplyCompMatr1()
145+
* - multiplyCompMatr()
146+
* @author Tyson Jones
147+
*/
148+
void postMultiplyCompMatr1(Qureg qureg, int target, CompMatr1 matrix);
149+
150+
99151
/** Applies a general one-qubit dense unitary @p matrix to the specified @p target
100152
* qubit of @p qureg.
101153
*
@@ -162,6 +214,7 @@ digraph {
162214
* - getCompMatr1()
163215
* - getInlineCompMatr1()
164216
* - multiplyCompMatr1()
217+
* - postMultiplyCompMatr1()
165218
* - applyControlledCompMatr1()
166219
* - applyCompMatr2()
167220
* - applyCompMatr()
@@ -346,6 +399,14 @@ extern "C" {
346399
void multiplyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matr);
347400

348401

402+
/// @notyetdoced
403+
/// @notyettested
404+
/// @notyetvalidated
405+
/// @see
406+
/// - postMultiplyCompMatr1
407+
void postMultiplyCompMatr2(Qureg qureg, int target1, int target2, CompMatr2 matrix);
408+
409+
349410
/** @notyetdoced
350411
*
351412
* Applies a general two-qubit dense unitary @p matrix to qubits @p target1 and
@@ -557,6 +618,14 @@ extern "C" {
557618
void multiplyCompMatr(Qureg qureg, int* targets, int numTargets, CompMatr matrix);
558619

559620

621+
/// @notyetdoced
622+
/// @notyettested
623+
/// @notyetvalidated
624+
/// @see
625+
/// - postMultiplyCompMatr1
626+
void postMultiplyCompMatr(Qureg qureg, int* targets, int numTargets, CompMatr matrix);
627+
628+
560629
/** @notyetdoced
561630
*
562631
* @formulae
@@ -612,6 +681,14 @@ void applyMultiStateControlledCompMatr(Qureg qureg, int* controls, int* states,
612681
void multiplyCompMatr(Qureg qureg, std::vector<int> targets, CompMatr matr);
613682

614683

684+
/// @notyettested
685+
/// @notyetvalidated
686+
/// @notyetdoced
687+
/// @cppvectoroverload
688+
/// @see postMultiplyCompMatr()
689+
void postMultiplyCompMatr(Qureg qureg, std::vector<int> targets, CompMatr matr);
690+
691+
615692
/// @notyettested
616693
/// @notyetvalidated
617694
/// @notyetdoced
@@ -667,6 +744,12 @@ extern "C" {
667744
void multiplyDiagMatr1(Qureg qureg, int target, DiagMatr1 matr);
668745

669746

747+
/// @notyettested
748+
/// @notyetvalidated
749+
/// @notyetdoced
750+
void postMultiplyDiagMatr1(Qureg qureg, int target, DiagMatr1 matrix);
751+
752+
670753
/// @notyetdoced
671754
/// @see applyCompMatr1()
672755
void applyDiagMatr1(Qureg qureg, int target, DiagMatr1 matr);
@@ -734,6 +817,12 @@ extern "C" {
734817
void multiplyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matr);
735818

736819

820+
/// @notyettested
821+
/// @notyetvalidated
822+
/// @notyetdoced
823+
void postMultiplyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matrix);
824+
825+
737826
/// @notyetdoced
738827
/// @see applyCompMatr1()
739828
void applyDiagMatr2(Qureg qureg, int target1, int target2, DiagMatr2 matr);
@@ -801,6 +890,12 @@ extern "C" {
801890
void multiplyDiagMatr(Qureg qureg, int* targets, int numTargets, DiagMatr matrix);
802891

803892

893+
/// @notyettested
894+
/// @notyetvalidated
895+
/// @notyetdoced
896+
void postMultiplyDiagMatr(Qureg qureg, int* targets, int numTargets, DiagMatr matrix);
897+
898+
804899
/// @notyetdoced
805900
/// @see applyCompMatr1()
806901
void applyDiagMatr(Qureg qureg, int* targets, int numTargets, DiagMatr matrix);
@@ -828,6 +923,12 @@ void applyMultiStateControlledDiagMatr(Qureg qureg, int* controls, int* states,
828923
void multiplyDiagMatrPower(Qureg qureg, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
829924

830925

926+
/// @notyettested
927+
/// @notyetvalidated
928+
/// @notyetdoced
929+
void postMultiplyDiagMatrPower(Qureg qureg, int* targets, int numTargets, DiagMatr matrix, qcomp exponent);
930+
931+
831932
/** @notyetdoced
832933
*
833934
* @formulae
@@ -874,6 +975,14 @@ void applyMultiStateControlledDiagMatrPower(Qureg qureg, int* controls, int* sta
874975
void multiplyDiagMatr(Qureg qureg, std::vector<int> targets, DiagMatr matrix);
875976

876977

978+
/// @notyettested
979+
/// @notyetvalidated
980+
/// @notyetdoced
981+
/// @cppvectoroverload
982+
/// @see postMultiplyDiagMatr()
983+
void postMultiplyDiagMatr(Qureg qureg, std::vector<int> targets, DiagMatr matrix);
984+
985+
877986
/// @notyettested
878987
/// @notyetvalidated
879988
/// @notyetdoced
@@ -914,6 +1023,14 @@ void applyMultiStateControlledDiagMatr(Qureg qureg, std::vector<int> controls, s
9141023
void multiplyDiagMatrPower(Qureg qureg, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
9151024

9161025

1026+
/// @notyettested
1027+
/// @notyetvalidated
1028+
/// @notyetdoced
1029+
/// @cppvectoroverload
1030+
/// @see postMultiplyDiagMatrPower()
1031+
void postMultiplyDiagMatrPower(Qureg qureg, std::vector<int> targets, DiagMatr matrix, qcomp exponent);
1032+
1033+
9171034
/// @notyettested
9181035
/// @notyetvalidated
9191036
/// @notyetdoced
@@ -979,6 +1096,18 @@ void multiplyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix);
9791096
void multiplyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent);
9801097

9811098

1099+
/// @notyetdoced
1100+
/// @notyettested
1101+
/// @notyetvalidated
1102+
void postMultiplyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix);
1103+
1104+
1105+
/// @notyetdoced
1106+
/// @notyettested
1107+
/// @notyetvalidated
1108+
void postMultiplyFullStateDiagMatrPower(Qureg qureg, FullStateDiagMatr matrix, qcomp exponent);
1109+
1110+
9821111
/// @notyetdoced
9831112
/// @notyetvalidated
9841113
void applyFullStateDiagMatr(Qureg qureg, FullStateDiagMatr matrix);
@@ -1143,6 +1272,12 @@ extern "C" {
11431272
void multiplySwap(Qureg qureg, int qubit1, int qubit2);
11441273

11451274

1275+
/// @notyetdoced
1276+
/// @notyettested
1277+
/// @notyetvalidated
1278+
void postMultiplySwap(Qureg qureg, int qubit1, int qubit2);
1279+
1280+
11461281
/** Applies a SWAP gate between @p qubit1 and @p qubit2 of @p qureg.
11471282
*
11481283
* @diagram
@@ -1264,20 +1399,41 @@ extern "C" {
12641399

12651400

12661401
/// @notyetdoced
1402+
/// @notyettested
12671403
/// @see multiplyCompMatr1()
12681404
void multiplyPauliX(Qureg qureg, int target);
12691405

12701406

12711407
/// @notyetdoced
1408+
/// @notyettested
12721409
/// @see multiplyCompMatr1()
12731410
void multiplyPauliY(Qureg qureg, int target);
12741411

12751412

12761413
/// @notyetdoced
1414+
/// @notyettested
12771415
/// @see multiplyCompMatr1()
12781416
void multiplyPauliZ(Qureg qureg, int target);
12791417

12801418

1419+
/// @notyetdoced
1420+
/// @notyettested
1421+
/// @see postMultiplyCompMatr1()
1422+
void postMultiplyPauliX(Qureg qureg, int target);
1423+
1424+
1425+
/// @notyetdoced
1426+
/// @notyettested
1427+
/// @see postMultiplyCompMatr1()
1428+
void postMultiplyPauliY(Qureg qureg, int target);
1429+
1430+
1431+
/// @notyetdoced
1432+
/// @notyettested
1433+
/// @see postMultiplyCompMatr1()
1434+
void postMultiplyPauliZ(Qureg qureg, int target);
1435+
1436+
12811437
/// @notyetdoced
12821438
void applyPauliX(Qureg qureg, int target);
12831439

@@ -1408,6 +1564,12 @@ extern "C" {
14081564
void multiplyPauliStr(Qureg qureg, PauliStr str);
14091565

14101566

1567+
/// @notyetdoced
1568+
/// @notyettested
1569+
/// @notyetvalidated
1570+
void postMultiplyPauliStr(Qureg qureg, PauliStr str);
1571+
1572+
14111573
/// @notyetdoced
14121574
void applyPauliStr(Qureg qureg, PauliStr str);
14131575

@@ -1796,6 +1958,12 @@ extern "C" {
17961958
void multiplyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
17971959

17981960

1961+
/// @notyetdoced
1962+
/// @notyettested
1963+
/// @notyetvalidated
1964+
void postMultiplyPauliGadget(Qureg qureg, PauliStr str, qreal angle);
1965+
1966+
17991967
/** @notyetdoced
18001968
*
18011969
* @formulae
@@ -1929,6 +2097,12 @@ extern "C" {
19292097
void multiplyPhaseGadget(Qureg qureg, int* targets, int numTargets, qreal angle);
19302098

19312099

2100+
/// @notyetdoced
2101+
/// @notyettested
2102+
/// @notyetvalidated
2103+
void postMultiplyPhaseGadget(Qureg qureg, int* targets, int numTargets, qreal angle);
2104+
2105+
19322106
/** @notyetdoced
19332107
*
19342108
* @formulae
@@ -2201,6 +2375,14 @@ void applyMultiQubitPhaseShift(Qureg qureg, int* targets, int numTargets, qreal
22012375
void multiplyPhaseGadget(Qureg qureg, std::vector<int> targets, qreal angle);
22022376

22032377

2378+
/// @notyettested
2379+
/// @notyetvalidated
2380+
/// @notyetdoced
2381+
/// @cppvectoroverload
2382+
/// @see postMultiplyPhaseGadget()
2383+
void postMultiplyPhaseGadget(Qureg qureg, std::vector<int> targets, qreal angle);
2384+
2385+
22042386
/// @notyettested
22052387
/// @notyetvalidated
22062388
/// @notyetdoced
@@ -2273,6 +2455,12 @@ extern "C" {
22732455
void multiplyPauliStrSum(Qureg qureg, PauliStrSum sum, Qureg workspace);
22742456

22752457

2458+
/// @notyetdoced
2459+
/// @notyettested
2460+
/// @notyetvalidated
2461+
void postMultiplyPauliStrSum(Qureg qureg, PauliStrSum sum, Qureg workspace);
2462+
2463+
22762464
/** @notyettested
22772465
*
22782466
* Effects (an approximation to) the exponential of @p sum, weighted by @p angle, upon @p qureg,
@@ -2558,6 +2746,12 @@ extern "C" {
25582746
void multiplyMultiQubitNot(Qureg qureg, int* targets, int numTargets);
25592747

25602748

2749+
/// @notyetdoced
2750+
/// @notyettested
2751+
/// @notyetvalidated
2752+
void postMultiplyMultiQubitNot(Qureg qureg, int* targets, int numTargets);
2753+
2754+
25612755
/// @notyetdoced
25622756
void applyMultiQubitNot(Qureg qureg, int* targets, int numTargets);
25632757

@@ -2592,6 +2786,14 @@ void applyMultiStateControlledMultiQubitNot(Qureg qureg, int* controls, int* sta
25922786
void multiplyMultiQubitNot(Qureg qureg, std::vector<int> targets);
25932787

25942788

2789+
/// @notyettested
2790+
/// @notyetvalidated
2791+
/// @notyetdoced
2792+
/// @cppvectoroverload
2793+
/// @see postMultiplyMultiQubitNot()
2794+
void postMultiplyMultiQubitNot(Qureg qureg, std::vector<int> targets);
2795+
2796+
25952797
/// @notyettested
25962798
/// @notyetvalidated
25972799
/// @notyetdoced

0 commit comments

Comments
 (0)