Base version with linear combinated classes

This commit is contained in:
2019-12-13 18:17:29 +03:00
parent d3b1fc754a
commit 30ddecfa3c
3 changed files with 191 additions and 8 deletions

View File

@@ -6,14 +6,16 @@
#include <fstream>
#include "al_function.hpp"
#include "al_bool_matrix.hpp"
using namespace std;
typedef uint16_t Storage;
const size_t ARGS_COUNT = 4;
const size_t ARGS_COUNT = 3;
const size_t FUNCTION_LEN = 1ll << ARGS_COUNT;
const size_t FUNCTIONS_COUNT = 1ll << FUNCTION_LEN;
typedef Function<Storage, FUNCTION_LEN> MyFunction;
typedef BoolSquareMatrix<Storage, ARGS_COUNT> MyMatrix;
void test_function() {
Function<uint16_t, 8> f_8(16);
@@ -49,11 +51,41 @@ void test_function() {
cout << "f(x_1, x_2, x_3 + 1) = " << negation.var_negation(3).string() << endl;
*/
BoolSquareMatrix<uint16_t, 3> ones_matrix((1 << 10) - 1), i_matrix(0b100010001), minus_i_matrix(0b001010100);
assert(ones_matrix.string("") == "111111111");
assert(ones_matrix.get_determinant() == 0);
assert(i_matrix.string("") == "100010001");
assert(i_matrix.get_determinant() == 1);
assert(minus_i_matrix.string("") == "001010100");
assert(minus_i_matrix.get_determinant() == uint16_t(-1));
cout << "self-test passed" << endl;
}
template<class STORAGE, size_t ARGUMENTS_COUNT, class Callable>
Function<STORAGE, 1ll << ARGUMENTS_COUNT > get_function_from_callable(Callable INPUT_FUNCTION) {
const STORAGE values_count = 1ll << ARGUMENTS_COUNT;
STORAGE function_values(0);
for (STORAGE cur_vec_value = values_count; cur_vec_value != 0; --cur_vec_value) {
BoolVector<STORAGE, ARGUMENTS_COUNT> vec(cur_vec_value - 1);
function_values *= 2;
function_values += INPUT_FUNCTION(vec);
}
return Function<STORAGE, values_count >(function_values);
}
vector<MyFunction> get_function_class(MyFunction f) {
vector< MyMatrix > get_good_matrices() {
vector< MyMatrix > res;
for (size_t cur_val = 1ll << (ARGS_COUNT * ARGS_COUNT); cur_val != 0; --cur_val) {
MyMatrix cur_matrix(cur_val);
if ( cur_matrix.get_determinant() != 0 )
res.push_back(cur_matrix);
}
return res;
}
vector<MyFunction> get_function_class(MyFunction f, const vector< MyMatrix >& tranformations, ostream& out) {
set<MyFunction> cur_res;
for (Storage i = 0; i < FUNCTION_LEN; ++i) {
MyFunction cur_f = f;
@@ -62,7 +94,24 @@ vector<MyFunction> get_function_class(MyFunction f) {
cur_f = cur_f.var_negation(arg_ind + 1);
cur_res.insert(cur_f);
}
return vector<MyFunction>(cur_res.begin(), cur_res.end());
set<MyFunction> transformed_res;
for (auto f: cur_res) {
for (auto transformation: tranformations) {
MyFunction linear_transformed = get_function_from_callable<Storage, ARGS_COUNT>(
[transformation, f](const BoolVector<Storage, ARGS_COUNT> vec) -> Storage {
return f.at((transformation * vec).get_value());
}
);
bool is_inserted = transformed_res.insert(linear_transformed).second;
if ( is_inserted ) {
out << linear_transformed.string() << " = " << f.string() << " with ("
<< transformation.string(",") << ")" << endl;
}
}
}
return vector<MyFunction>(transformed_res.begin(), transformed_res.end());
}
@@ -143,7 +192,7 @@ void fill_ranks(vector<MyFunction> monomials) {
MyFunction res_el = el_first xor el_second;
if ( used_map[res_el.value()] == 0 ) {
--functions_remains;
used_map[res_el.value()] = total_ranks;
used_map.at(res_el.value()) = total_ranks;
ranks.at(total_ranks).push_back(res_el);
}
}
@@ -153,6 +202,11 @@ void fill_ranks(vector<MyFunction> monomials) {
cout << "size for rank " << total_ranks << " is " << ranks.at(total_ranks).size() << endl;
}
auto possible_tranformations = get_good_matrices();
cout << "Total " << possible_tranformations.size() << " linear tranformations" << endl;
//for (auto el: possible_tranformations)
// cout << el.string(",") <<endl;
ranks.clear();
for (auto i = total_ranks - 1; i != 0; --i)
ranks.push_back(vector<MyFunction>()); // empty set
@@ -163,13 +217,16 @@ void fill_ranks(vector<MyFunction> monomials) {
continue;
++total_functions;
MyFunction current_fn(fn_value);
vector<MyFunction> function_class = get_function_class(current_fn);
f_out << "Function class for " << current_fn.string() << ": ";
vector<MyFunction> function_class = get_function_class(
current_fn, possible_tranformations, f_out
);
cout << "size of function class is " << function_class.size() << endl;
f_out << "Function class for " << current_fn.string() << ": (" << endl;
for (auto marked_function: function_class) {
used_map[marked_function.value()] = 0;
f_out << marked_function.string() << " ";
f_out << " " << marked_function.string() << endl;
}
f_out << endl;
f_out << ")" << endl;
ranks.at(cur_rank - 1).push_back(current_fn);
}
cout << "total unique functions: " << total_functions << endl;