diff --git a/releasenotes/notes/fix-amplitude-e28a8d127ae1d5e7.yaml b/releasenotes/notes/fix-amplitude-e28a8d127ae1d5e7.yaml new file mode 100644 index 0000000000..496bbe562c --- /dev/null +++ b/releasenotes/notes/fix-amplitude-e28a8d127ae1d5e7.yaml @@ -0,0 +1,10 @@ +--- +prelude: > + AerState::probability and AerState::amplitude returned the wrong states + for the MPS simulator. +fixes: + - | + Added a function that provides the correct states, ``reorder_qubits_rev``, + which is called now by ``MPS::get_amplitude_vector``. + For more details, refer to: + `#2235 ` \ No newline at end of file diff --git a/src/simulators/matrix_product_state/matrix_product_state_internal.cpp b/src/simulators/matrix_product_state/matrix_product_state_internal.cpp index 424637c4f0..ad961b580c 100644 --- a/src/simulators/matrix_product_state/matrix_product_state_internal.cpp +++ b/src/simulators/matrix_product_state/matrix_product_state_internal.cpp @@ -82,6 +82,7 @@ template void reorder_all_qubits(const vec_t &orig_probvector, const reg_t &qubits, vec_t &new_probvector); uint_t reorder_qubits(const reg_t &qubits, uint_t index); +uint_t reorder_qubits_rev(const reg_t &qubits, uint_t index); //------------------------------------------------------------------------ // Function name: permute_all_qubits @@ -208,6 +209,29 @@ uint_t reorder_qubits(const reg_t &qubits, uint_t index) { return new_index; } +uint_t reorder_qubits_rev(const reg_t &qubits, uint_t index) { + uint_t new_index = 0; + + int_t current_pos = 0, current_val = 0, new_pos = 0, shift = 0; + uint_t num_qubits = qubits.size(); + for (uint_t i = 0; i < num_qubits; i++) { + current_pos = qubits[i]; + current_val = 1ULL << current_pos; + new_pos = i; + shift = new_pos - current_pos; + if (index & current_val) { + if (shift > 0) { + new_index += current_val << shift; + } else if (shift < 0) { + new_index += current_val >> -shift; + } else { + new_index += current_val; + } + } + } + return new_index; +} + template void permute_all_qubits(const vec_t &orig_statevector, const reg_t &input_qubits, const reg_t &output_qubits, @@ -1350,7 +1374,7 @@ Vector MPS::get_amplitude_vector(const reg_t &base_values) { // Since the qubits may not be ordered, we determine the actual index // by the internal order of the qubits, to obtain the actual_base_value uint_t actual_base_value = - reorder_qubits(qubit_ordering_.order_, base_values[i]); + reorder_qubits_rev(qubit_ordering_.order_, base_values[i]); base_value = AER::Utils::int2string(actual_base_value); amplitude_vector[i] = get_single_amplitude(base_value); }