Files
cmc-pseudo-polynomials/al_bool_matrix.hpp

137 lines
4.5 KiB
C++

#ifndef _AL_BOOL_MATRIX_HPP
#define _AL_BOOL_MATRIX_HPP
#include <cassert>
#include <cstdint>
#include <bitset>
#include <limits>
#include <string>
template <class STORAGE, size_t SIZE>
class BoolVector {
public:
BoolVector(): _value(0) {
static_assert(not std::numeric_limits<STORAGE>::is_signed);
}
BoolVector(STORAGE val): _value(val) {
static_assert(not std::numeric_limits<STORAGE>::is_signed);
assert(val < 1ll << SIZE);
}
BoolVector operator*(BoolVector other) const {
return BoolVector(_value & other.get_value());
}
STORAGE get_value() const {
return _value;
}
STORAGE at(STORAGE ind) const {
return (_value >> ind) % 2;
}
std::string string() const {
std::string res(SIZE, '0');
for (size_t ind = 0; ind < SIZE; ++ind) {
char cur_ch = at(ind) % 2 == 0 ? '0' : '1';
res[ind] = cur_ch;
}
return res;
}
private:
STORAGE _value;
};
template<class STORAGE, size_t SIZE>
class BoolSquareMatrix {
public:
BoolSquareMatrix(): _values(0) {
static_assert(not std::numeric_limits<STORAGE>::is_signed);
}
BoolSquareMatrix(STORAGE val): _values(val) {
static_assert(not std::numeric_limits<STORAGE>::is_signed);
}
STORAGE at(STORAGE row, STORAGE col) const {
return (_values >> index(row, col)) % 2;
}
STORAGE get_determinant() {
if constexpr ( SIZE == 2 ) {
return at(0,0) * at(1,1) - at(0,1) * at(1,0);
} else if constexpr ( SIZE == 4 or SIZE == 3 ) {
int cur_modifier = 1;
STORAGE res = 0;
for (STORAGE remove_ind = 0; remove_ind < SIZE; ++remove_ind) {
STORAGE tmp_vector_value = 0;
for (STORAGE i = 1; i < SIZE; ++i) {
for (STORAGE j = 0; j < SIZE; ++j) {
if ( j == remove_ind )
continue;
tmp_vector_value *= 2;
tmp_vector_value += at(i, j);
}
}
BoolSquareMatrix<STORAGE, SIZE - 1> tmp_matix(tmp_vector_value);
res += cur_modifier * tmp_matix.get_determinant() * at(0, remove_ind);
cur_modifier *= -1;
}
return res;
}
}
BoolVector<STORAGE, SIZE> operator * (BoolVector<STORAGE, SIZE> vec) const {
/* a_1
* a_2
* a_3
*/
STORAGE vector_value = 0;
for (STORAGE ind = 0; ind < SIZE; ++ind) {
BoolVector<STORAGE, SIZE> cur_vec = vec * get_row(ind);
/* STORAGE cur_sum = 0;
for (STORAGE vec_ind = 0; vec_ind < SIZE; ++vec_ind)
cur_sum += cur_vec.at(vec_ind);
same but slow version, we just need number of bits
*/
vector_value *= 2;
vector_value += __builtin_popcount(cur_vec.get_value()) % 2; // cur_sum
}
return BoolVector<STORAGE, SIZE>(vector_value);
}
STORAGE get_value() const {
return _values;
}
std::string string(std::string delimiter="\n") const {
std::string res;
for (STORAGE i = 0; i < SIZE; ++i) {
for (STORAGE j = 0; j < SIZE; ++j) {
char cur_ch = at(i,j) % 2 == 0 ? '0' : '1';
res += cur_ch;
}
if ( i != SIZE - 1 )
res += delimiter;
}
return res;
}
bool operator < (BoolSquareMatrix other) const {
return _values < other._values;
}
bool operator == (BoolSquareMatrix other) const {
return _values == other._values;
}
private:
STORAGE _values;
STORAGE index(STORAGE row, STORAGE col) const {
return SIZE * row + col;
}
BoolVector<STORAGE, SIZE> get_row(STORAGE row) const {
STORAGE vector_value = 0;
for (STORAGE i = 0; i < SIZE; ++i) {
vector_value *= 2;
vector_value += at(row, i);
}
return BoolVector<STORAGE, SIZE>(vector_value);
}
};
#endif // _AL_BOOL_MATRIX_HPP