Base version with linear combinated classes
This commit is contained in:
73
main.cpp
73
main.cpp
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user