@@ -859,27 +859,38 @@ void applyMultiStateControlledPauliX(Qureg qureg, int* controls, int* states, in
859859 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
860860 validate_controlStates (states, numControls, __func__); // permits states==nullptr
861861
862- // harmlessly re-validates
863- applyMultiStateControlledPauliStr (qureg, controls, states, numControls, getPauliStr (" X" , {target}));
862+ // note that for the single-target scenario, we do not call the backend of
863+ // applyMultiStateControlledPauliStr() since it contains sub-optimal logic
864+ // which sees the factor of every amplitude dynamically evaluated (based on
865+ // index parity, etc); the dense-matrix element lookup is faster
866+
867+ // / @todo
868+ // / a bespoke all-pauli-X function (like in QuEST v3) will be faster still
869+ // / since it avoids all superfluous flops; check worthwhile for multi-qubit
870+
871+ // harmlessly re-validates, including hardcoded matrix unitarity
872+ CompMatr1 matrix = util_getPauliX ();
873+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, &target, 1 , matrix, __func__);
864874}
865875
866876void applyMultiStateControlledPauliY (Qureg qureg, int * controls, int * states, int numControls, int target) {
867877 validate_quregFields (qureg, __func__);
868878 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
869879 validate_controlStates (states, numControls, __func__); // permits states==nullptr
870880
871- // harmlessly re-validates
872- applyMultiStateControlledPauliStr (qureg, controls, states, numControls, getPauliStr (" Y" , {target}));
881+ // harmlessly re-validates, including hardcoded matrix unitarity
882+ CompMatr1 matrix = util_getPauliY ();
883+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, &target, 1 , matrix, __func__);
873884}
874885
875886void applyMultiStateControlledPauliZ (Qureg qureg, int * controls, int * states, int numControls, int target) {
876887 validate_quregFields (qureg, __func__);
877888 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
878889 validate_controlStates (states, numControls, __func__); // permits states==nullptr
879890
880- // harmlessly re-validates
881- DiagMatr1 matr = getDiagMatr1 ({ 1 , - 1 } );
882- applyMultiStateControlledDiagMatr1 (qureg, controls, states, numControls, target, matr );
891+ // harmlessly re-validates, including hardcoded matrix unitarity
892+ DiagMatr1 matrix = util_getPauliZ ( );
893+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, & target, 1 , matrix, __func__ );
883894}
884895
885896} // end de-mangler
@@ -1077,26 +1088,44 @@ void applyMultiStateControlledRotateX(Qureg qureg, int* controls, int* states, i
10771088 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
10781089 validate_controlStates (states, numControls, __func__); // permits states==nullptr
10791090
1080- // harmlessly re-validates
1081- applyMultiStateControlledPauliGadget (qureg, controls, states, numControls, getPauliStr (" X" , {target}), angle);
1091+ // note that for the single-target scenario, we do not call the backend of
1092+ // applyMultiStateControlledPauliGadget() since it contains sub-optimal logic
1093+ // which sees the factor of every amplitude dynamically evaluated (based on
1094+ // index parity, etc); the dense-matrix element lookup is faster
1095+
1096+ // harmlessly re-validates, including hardcoded matrix unitarity
1097+ CompMatr1 matrix = util_getExpPauliX (angle);
1098+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, &target, 1 , matrix, __func__);
10821099}
10831100
10841101void applyMultiStateControlledRotateY (Qureg qureg, int * controls, int * states, int numControls, int target, qreal angle) {
10851102 validate_quregFields (qureg, __func__);
10861103 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
10871104 validate_controlStates (states, numControls, __func__); // permits states==nullptr
10881105
1089- // harmlessly re-validates
1090- applyMultiStateControlledPauliGadget (qureg, controls, states, numControls, getPauliStr (" Y" , {target}), angle);
1106+ // note that for the single-target scenario, we do not call the backend of
1107+ // applyMultiStateControlledPauliGadget() since it contains sub-optimal logic
1108+ // which sees the factor of every amplitude dynamically evaluated (based on
1109+ // index parity, etc); the dense-matrix element lookup is faster
1110+
1111+ // harmlessly re-validates, including hardcoded matrix unitarity
1112+ CompMatr1 matrix = util_getExpPauliY (angle);
1113+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, &target, 1 , matrix, __func__);
10911114}
10921115
10931116void applyMultiStateControlledRotateZ (Qureg qureg, int * controls, int * states, int numControls, int target, qreal angle) {
10941117 validate_quregFields (qureg, __func__);
10951118 validate_controlsAndTarget (qureg, controls, numControls, target, __func__);
10961119 validate_controlStates (states, numControls, __func__); // permits states==nullptr
10971120
1098- // harmlessly re-validates
1099- applyMultiStateControlledPauliGadget (qureg, controls, states, numControls, getPauliStr (" Z" , {target}), angle);
1121+ // note that for the single-target scenario, we do not call the backend of
1122+ // applyMultiStateControlledPauliGadget() since it contains sub-optimal logic
1123+ // which sees the factor of every amplitude dynamically evaluated (based on
1124+ // index parity, etc); the dense-matrix element lookup is faster
1125+
1126+ // harmlessly re-validates, including hardcoded matrix unitarity
1127+ DiagMatr1 matrix = util_getExpPauliZ (angle);
1128+ validateAndApplyAnyCtrlAnyTargUnitaryMatrix (qureg, controls, states, numControls, &target, 1 , matrix, __func__);
11001129}
11011130
11021131} // end de-mangler
0 commit comments