Skip to content

Commit

Permalink
inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
Strilanc committed Mar 20, 2024
1 parent a68d19e commit e6e48bc
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 40 deletions.
22 changes: 6 additions & 16 deletions src/stim/util_bot/twiddle.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,23 @@
#ifndef _STIM_UTIL_BOT_TWIDDLE_H
#define _STIM_UTIL_BOT_TWIDDLE_H

#include <bit>
#include <cstddef>
#include <cstdint>
#include <stdexcept>

namespace stim {

inline uint8_t floor_lg2(size_t value) {
uint8_t result = 0;
while (value > 1) {
result += 1;
value >>= 1;
}
return result;
}

inline uint8_t is_power_of_2(size_t value) {
return value != 0 && (value & (value - 1)) == 0;
return sizeof(value)*8 - 1 - std::countl_zero(value);
}

inline size_t first_set_bit(size_t value, size_t min_result) {
size_t t = min_result;
value >>= min_result;
// assert(value);
while (!(value & 1)) {
value >>= 1;
t += 1;
if (!value) {
throw std::invalid_argument("No matching set bit.");
}
return t;
return std::countr_zero(value) + min_result;
}

} // namespace stim
Expand Down
45 changes: 24 additions & 21 deletions src/stim/util_bot/twiddle.test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,35 @@
// limitations under the License.

#include "stim/util_bot/twiddle.h"
#include <bit>

#include "gtest/gtest.h"

using namespace stim;

TEST(conversions, is_power_of_2) {
ASSERT_FALSE(is_power_of_2(0));
ASSERT_TRUE(is_power_of_2(1));
ASSERT_TRUE(is_power_of_2(2));
ASSERT_FALSE(is_power_of_2(3));
ASSERT_TRUE(is_power_of_2(4));
ASSERT_FALSE(is_power_of_2(5));
ASSERT_FALSE(is_power_of_2(6));
ASSERT_FALSE(is_power_of_2(7));
ASSERT_TRUE(is_power_of_2(8));
ASSERT_FALSE(is_power_of_2(9));
TEST(twiddle, floor_lg2) {
ASSERT_EQ(63 - std::countl_zero((uint64_t)1), 0);
ASSERT_EQ(63 - std::countl_zero((uint64_t)2), 1);
ASSERT_EQ(63 - std::countl_zero((uint64_t)3), 1);
ASSERT_EQ(63 - std::countl_zero((uint64_t)4), 2);
ASSERT_EQ(63 - std::countl_zero((uint64_t)5), 2);
ASSERT_EQ(63 - std::countl_zero((uint64_t)6), 2);
ASSERT_EQ(63 - std::countl_zero((uint64_t)7), 2);
ASSERT_EQ(63 - std::countl_zero((uint64_t)8), 3);
ASSERT_EQ(63 - std::countl_zero((uint64_t)9), 3);
}

TEST(conversions, floor_lg2) {
ASSERT_EQ(floor_lg2(1), 0);
ASSERT_EQ(floor_lg2(2), 1);
ASSERT_EQ(floor_lg2(3), 1);
ASSERT_EQ(floor_lg2(4), 2);
ASSERT_EQ(floor_lg2(5), 2);
ASSERT_EQ(floor_lg2(6), 2);
ASSERT_EQ(floor_lg2(7), 2);
ASSERT_EQ(floor_lg2(8), 3);
ASSERT_EQ(floor_lg2(9), 3);
TEST(twiddle, first_set_bit) {
ASSERT_EQ(first_set_bit(0b0000111001000, 0), 3);
ASSERT_EQ(first_set_bit(0b0000111001000, 1), 3);
ASSERT_EQ(first_set_bit(0b0000111001000, 2), 3);
ASSERT_EQ(first_set_bit(0b0000111001000, 3), 3);
ASSERT_EQ(first_set_bit(0b0000111001000, 4), 6);
ASSERT_EQ(first_set_bit(0b0000111001000, 5), 6);
ASSERT_EQ(first_set_bit(0b0000111001000, 6), 6);
ASSERT_EQ(first_set_bit(0b0000111001000, 7), 7);
ASSERT_EQ(first_set_bit(0b0000111001000, 8), 8);

ASSERT_EQ(first_set_bit(0b0000111001001, 0), 0);
ASSERT_EQ(first_set_bit(1 << 20, 0), 20);
}
4 changes: 2 additions & 2 deletions src/stim/util_top/circuit_vs_amplitudes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ inline static size_t compute_occupation(const std::vector<std::complex<float>> &

Circuit stim::stabilizer_state_vector_to_circuit(
const std::vector<std::complex<float>> &state_vector, bool little_endian) {
if (!is_power_of_2(state_vector.size())) {
if (!std::has_single_bit(state_vector.size())) {
std::stringstream ss;
ss << "Expected number of amplitudes to be a power of 2.";
ss << " The given state vector had " << state_vector.size() << " amplitudes.";
Expand Down Expand Up @@ -82,7 +82,7 @@ Circuit stim::stabilizer_state_vector_to_circuit(
}
sim.smooth_stabilizer_state(sim.state[0]);
size_t occupation = compute_occupation(sim.state);
if (!is_power_of_2(occupation)) {
if (!std::has_single_bit(occupation)) {
throw std::invalid_argument("State vector isn't a stabilizer state.");
}

Expand Down
2 changes: 1 addition & 1 deletion src/stim/util_top/stabilizers_vs_amplitudes.inl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ template <size_t W>
Tableau<W> unitary_to_tableau(const std::vector<std::vector<std::complex<float>>> &matrix, bool little_endian) {
// Verify matrix is square.
size_t num_amplitudes = matrix.size();
if (!is_power_of_2(num_amplitudes)) {
if (!std::has_single_bit(num_amplitudes)) {
throw std::invalid_argument(
"Matrix width and height must be a power of 2. Height was " + std::to_string(num_amplitudes));
}
Expand Down

0 comments on commit e6e48bc

Please sign in to comment.