Skip to content

Commit 886cf5e

Browse files
authored
Merge pull request #7 from msoeken/flip_var
Flip variable
2 parents 5062bc8 + 9318576 commit 886cf5e

File tree

3 files changed

+160
-10
lines changed

3 files changed

+160
-10
lines changed

docs/changelog.rst

+3
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,6 @@ v0.1
2727

2828
* Swap adjacent variables: ``swap_adjacent_inplace``, ``swap_adjacent``
2929
`#6 <https://github.com/msoeken/kitty/pull/6>`_
30+
31+
* Flip variable: ``flip_inplace``, ``flip``
32+
`#7 <https://github.com/msoeken/kitty/pull/7>`_

include/kitty/operations.hpp

+50
Original file line numberDiff line numberDiff line change
@@ -311,4 +311,54 @@ inline TT swap_adjacent( const TT& tt, uint64_t var_index )
311311
return copy;
312312
}
313313

314+
template<typename TT>
315+
void flip_inplace( TT& tt, uint64_t var_index )
316+
{
317+
assert( var_index < tt.num_vars() );
318+
319+
if ( tt.num_blocks() == 1 )
320+
{
321+
const auto shift = 1 << var_index;
322+
tt._bits[0] = ( ( tt._bits[0] << shift ) & detail::projections[var_index] ) | ( ( tt._bits[0] & detail::projections[var_index] ) >> shift );
323+
}
324+
else if ( var_index < 6 )
325+
{
326+
const auto shift = 1 << var_index;
327+
std::transform( std::begin( tt._bits ), std::end( tt._bits ), std::begin( tt._bits ),
328+
[var_index, shift]( uint64_t word ) {
329+
return ( ( word << shift ) & detail::projections[var_index] ) | ( ( word & detail::projections[var_index] ) >> shift );
330+
} );
331+
}
332+
else
333+
{
334+
const auto step = 1 << ( var_index - 6 );
335+
auto it = std::begin( tt._bits );
336+
while ( it != std::end( tt._bits ) )
337+
{
338+
for ( auto i = decltype( step ){0}; i < step; ++i )
339+
{
340+
std::swap( *( it + i ), *( it + i + step ) );
341+
}
342+
it += 2 * step;
343+
}
344+
}
345+
}
346+
347+
template<int NumVars>
348+
inline void flip_inplace( static_truth_table<NumVars, true>& tt, uint64_t var_index )
349+
{
350+
assert( var_index < tt.num_vars() );
351+
352+
const auto shift = 1 << var_index;
353+
tt._bits = ( ( tt._bits << shift ) & detail::projections[var_index] ) | ( ( tt._bits & detail::projections[var_index] ) >> shift );
354+
}
355+
356+
template<typename TT>
357+
inline TT flip( const TT& tt, uint64_t var_index )
358+
{
359+
auto copy = tt;
360+
flip_inplace( copy, var_index );
361+
return copy;
362+
}
363+
314364
} // namespace kitty

test/operations.cpp

+107-10
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,6 @@ TEST( OperationsTest, ternary_for_large )
173173
}
174174
}
175175

176-
class OperationsTest : public ::testing::TestWithParam<std::pair<unsigned, std::string>>
177-
{
178-
};
179-
180176
TEST( OperationsTest, swap_adjacent_inplace_small )
181177
{
182178
for ( const auto& p : std::vector<std::pair<unsigned, std::string>>{{0u, "bce8"}, {1u, "e6e8"}, {2u, "dea8"}} )
@@ -189,7 +185,6 @@ TEST( OperationsTest, swap_adjacent_inplace_small )
189185

190186
EXPECT_TRUE( equal( tt_s, tt_s_res ) );
191187

192-
193188
dynamic_truth_table tt_d( 4 ), tt_d_res( 4 );
194189
create_from_hex_string( tt_d, "dae8" );
195190

@@ -210,7 +205,6 @@ TEST( OperationsTest, swap_adjacent_small )
210205

211206
EXPECT_TRUE( equal( swap_adjacent( tt_s, p.first ), tt_s_res ) );
212207

213-
214208
dynamic_truth_table tt_d( 4 ), tt_d_res( 4 );
215209
create_from_hex_string( tt_d, "dae8" );
216210
create_from_hex_string( tt_d_res, p.second );
@@ -219,7 +213,11 @@ TEST( OperationsTest, swap_adjacent_small )
219213
}
220214
}
221215

222-
TEST_P( OperationsTest, swap_adjacent_inplace_large )
216+
class OperationsTestSwap : public ::testing::TestWithParam<std::pair<unsigned, std::string>>
217+
{
218+
};
219+
220+
TEST_P( OperationsTestSwap, swap_adjacent_inplace_large )
223221
{
224222
static_truth_table<9> tt_s, tt_s_res;
225223
create_from_hex_string( tt_s, "28e3b8d62855c4b787eef391a93b33297856658b6743aa3cc7e11fde4e9cbf7c98b07f5febfff33bc7ad6f551bc4cbc440453e1bbe24f0cb4f268c6771b55eee" );
@@ -238,7 +236,7 @@ TEST_P( OperationsTest, swap_adjacent_inplace_large )
238236
EXPECT_TRUE( equal( tt_d, tt_d_res ) );
239237
}
240238

241-
TEST_P( OperationsTest, swap_adjacent_large )
239+
TEST_P( OperationsTestSwap, swap_adjacent_large )
242240
{
243241
static_truth_table<9> tt_s, tt_s_res;
244242
create_from_hex_string( tt_s, "28e3b8d62855c4b787eef391a93b33297856658b6743aa3cc7e11fde4e9cbf7c98b07f5febfff33bc7ad6f551bc4cbc440453e1bbe24f0cb4f268c6771b55eee" );
@@ -253,8 +251,8 @@ TEST_P( OperationsTest, swap_adjacent_large )
253251
EXPECT_TRUE( equal( swap_adjacent( tt_d, GetParam().first ), tt_d_res ) );
254252
}
255253

256-
INSTANTIATE_TEST_CASE_P( OperationsTestInst,
257-
OperationsTest,
254+
INSTANTIATE_TEST_CASE_P( OperationsTestSwapInst,
255+
OperationsTestSwap,
258256
::testing::Values( std::make_pair( 0u, "48e5d8b64833a2d787eef591c95d55497836638d6725cc5aa7e11fbe2e9adf7a"
259257
"98d07f3fedfff55da7cb6f331da2ada220235e1dde42f0ad2f468a6771d33eee" ),
260258
std::make_pair( 1u, "28cbacd62855d09f93facf85a92f0f296c5659a35b43aa3cd3c937f672b4bf7c"
@@ -271,3 +269,102 @@ INSTANTIATE_TEST_CASE_P( OperationsTestInst,
271269
"98b07f5febfff33b40453e1bbe24f0cbc7ad6f551bc4cbc44f268c6771b55eee" ),
272270
std::make_pair( 7u, "28e3b8d62855c4b787eef391a93b332998b07f5febfff33bc7ad6f551bc4cbc4"
273271
"7856658b6743aa3cc7e11fde4e9cbf7c40453e1bbe24f0cb4f268c6771b55eee" ) ) );
272+
273+
TEST( OperationsTest, flip_inplace_small )
274+
{
275+
for ( const auto& p : std::vector<std::pair<unsigned, std::string>>{{0u, "0b34"}, {1u, "0dc2"}, {2u, "7083"}, {3u, "3807"}} )
276+
{
277+
static_truth_table<4> tt_s, tt_s_res;
278+
create_from_hex_string( tt_s, "0738" );
279+
280+
flip_inplace( tt_s, p.first );
281+
create_from_hex_string( tt_s_res, p.second );
282+
283+
EXPECT_TRUE( equal( tt_s, tt_s_res ) );
284+
285+
dynamic_truth_table tt_d( 4 ), tt_d_res( 4 );
286+
create_from_hex_string( tt_d, "0738" );
287+
288+
flip_inplace( tt_d, p.first );
289+
create_from_hex_string( tt_d_res, p.second );
290+
291+
EXPECT_TRUE( equal( tt_d, tt_d_res ) );
292+
}
293+
}
294+
295+
TEST( OperationsTest, flip_small )
296+
{
297+
for ( const auto& p : std::vector<std::pair<unsigned, std::string>>{{0u, "0b34"}, {1u, "0dc2"}, {2u, "7083"}, {3u, "3807"}} )
298+
{
299+
static_truth_table<4> tt_s, tt_s_res;
300+
create_from_hex_string( tt_s, "0738" );
301+
create_from_hex_string( tt_s_res, p.second );
302+
303+
EXPECT_TRUE( equal( flip( tt_s, p.first ), tt_s_res ) );
304+
305+
dynamic_truth_table tt_d( 4 ), tt_d_res( 4 );
306+
create_from_hex_string( tt_d, "0738" );
307+
create_from_hex_string( tt_d_res, p.second );
308+
309+
EXPECT_TRUE( equal( flip( tt_d, p.first ), tt_d_res ) );
310+
}
311+
}
312+
313+
class OperationsTestFlip : public ::testing::TestWithParam<std::pair<unsigned, std::string>>
314+
{
315+
};
316+
317+
TEST_P( OperationsTestFlip, flip_inplace_large )
318+
{
319+
static_truth_table<9> tt_s, tt_s_res;
320+
create_from_hex_string( tt_s, "8725ca41421c7bba0ca86e26347847526fc346d7f3e79e76566a9493fbef11e24f74a07643afd946195f6a372757e045f3bca58f110ef00ebf2d81e80ba5679f" );
321+
322+
flip_inplace( tt_s, GetParam().first );
323+
create_from_hex_string( tt_s_res, GetParam().second );
324+
325+
EXPECT_TRUE( equal( tt_s, tt_s_res ) );
326+
327+
dynamic_truth_table tt_d( 9 ), tt_d_res( 9 );
328+
create_from_hex_string( tt_d, "8725ca41421c7bba0ca86e26347847526fc346d7f3e79e76566a9493fbef11e24f74a07643afd946195f6a372757e045f3bca58f110ef00ebf2d81e80ba5679f" );
329+
330+
flip_inplace( tt_d, GetParam().first );
331+
create_from_hex_string( tt_d_res, GetParam().second );
332+
333+
EXPECT_TRUE( equal( tt_d, tt_d_res ) );
334+
}
335+
336+
TEST_P( OperationsTestFlip, flip_large )
337+
{
338+
static_truth_table<9> tt_s, tt_s_res;
339+
create_from_hex_string( tt_s, "8725ca41421c7bba0ca86e26347847526fc346d7f3e79e76566a9493fbef11e24f74a07643afd946195f6a372757e045f3bca58f110ef00ebf2d81e80ba5679f" );
340+
create_from_hex_string( tt_s_res, GetParam().second );
341+
342+
EXPECT_TRUE( equal( flip( tt_s, GetParam().first ), tt_s_res ) );
343+
344+
dynamic_truth_table tt_d( 9 ), tt_d_res( 9 );
345+
create_from_hex_string( tt_d, "8725ca41421c7bba0ca86e26347847526fc346d7f3e79e76566a9493fbef11e24f74a07643afd946195f6a372757e045f3bca58f110ef00ebf2d81e80ba5679f" );
346+
create_from_hex_string( tt_d_res, GetParam().second );
347+
348+
EXPECT_TRUE( equal( flip( tt_d, GetParam().first ), tt_d_res ) );
349+
}
350+
351+
INSTANTIATE_TEST_CASE_P( OperationsTestFlipInst,
352+
OperationsTestFlip,
353+
::testing::Values( std::make_pair( 0u, "4b1ac582812cb7750c549d1938b48ba19fc389ebf3db6db9a9956863f7df22d1"
354+
"8fb850b9835fe68926af953b1babd08af37c5a4f220df00d7f1e42d4075a9b6f" ),
355+
std::make_pair( 1u, "2d853a141843deea03a29b89c1d21d589f3c197dfcbd6bd9599a616cfebf44b8"
356+
"1fd1a0d91caf7619465f9acd8d5db015fce3a52f440bf00bef8724b20ea59d6f" ),
357+
std::make_pair( 2u, "7852ac1424c1b7abc08ae66243877425f63c647d3f7ee96765a64939bffe112e"
358+
"f4470a6734fa9d6491f5a67372750e543fcb5af811e00fe0fbd2188eb05a76f9" ),
359+
std::make_pair( 3u, "258741ca1c42ba7ba80c266e78345247c36fd746e7f3769e6a569394effbe211"
360+
"744f76a0af4346d95f19376a572745e0bcf38fa50e110ef02dbfe881a50b9f67" ),
361+
std::make_pair( 4u, "ca4187257bba421c6e260ca84752347846d76fc39e76f3e79493566a11e2fbef"
362+
"a0764f74d94643af6a37195fe0452757a58ff3bcf00e110e81e8bf2d679f0ba5" ),
363+
std::make_pair( 5u, "421c7bba8725ca41347847520ca86e26f3e79e766fc346d7fbef11e2566a9493"
364+
"43afd9464f74a0762757e045195f6a37110ef00ef3bca58f0ba5679fbf2d81e8" ),
365+
std::make_pair( 6u, "0ca86e26347847528725ca41421c7bba566a9493fbef11e26fc346d7f3e79e76"
366+
"195f6a372757e0454f74a07643afd946bf2d81e80ba5679ff3bca58f110ef00e" ),
367+
std::make_pair( 7u, "6fc346d7f3e79e76566a9493fbef11e28725ca41421c7bba0ca86e2634784752"
368+
"f3bca58f110ef00ebf2d81e80ba5679f4f74a07643afd946195f6a372757e045" ),
369+
std::make_pair( 8u, "4f74a07643afd946195f6a372757e045f3bca58f110ef00ebf2d81e80ba5679f"
370+
"8725ca41421c7bba0ca86e26347847526fc346d7f3e79e76566a9493fbef11e2" ) ) );

0 commit comments

Comments
 (0)