Commit 37c7c368 authored by QuentinH's avatar QuentinH
Browse files

a

parent 6ccc0672
......@@ -20,8 +20,10 @@ macaulay_gen: LDLIBS += `pkg-config --libs m4ri`
reconstruct_monomials: parser.o tools.o tools_parser.o monomials.o reconstruct_monomials.o
reconstruct_monomials: LDLIBS += `pkg-config --libs m4ri`
monomial_new_test: tools.o monomial_new.o monomial_new_test.o
test_monomials_tmp: tools.o monomials_tmp.o test_monomials_tmp.o
test_parser_main: tools_parser.o monomials.o tools.o parser.o test_parser_main.o
test_polynomial_main: tools_parser.o monomials.o tools.o parser.o polynomial.o test_polynomial_main.o
test_enum_main: tools_parser.o monomials.o tools.o parser.o polynomial.o enum.o gauss.o test_enum_main.o
#test: parser.o tools.o tools_parser.o monomials.o test.o
#test: LDLIBS += `pkg-config --libs m4ri`
......@@ -31,7 +33,10 @@ tools.o: tools.h
monomials.o: monomials.h tools.h
polynomial.o: polynomial.h tools.h tools_parser.h monomials.h
tools_parser.o: tools_parser.h monomials.h tools.h
gauss.o: gauss.h
monomial_new.o: tools.h monomial_new.h
monomials_tmp.o: tools.h monomials_tmp.h
enum.o: tools.h tools_parser.h monomials.h polynomial.h enum.h gauss.h
macaulay_gen.o: parser.h tools_parser.h tools.h monomials.h
macaulay_gen.o: CFLAGS += `pkg-config --cflags m4ri`
......@@ -43,6 +48,8 @@ monomial_new_test.o:tools.h monomial_new.h
test_parser_main.o: tools_parser.h monomials.h tools.h parser.h
test_polynomial_main.o: tools_parser.h monomials.h tools.h parser.h polynomial.h
test_monomials_tmp.o:tools.h monomials_tmp.h
test_enum_main.o:tools_parser.h monomials.h tools.h parser.h polynomial.h enum.h
#test.o: parser.h tools_parser.h tools.h monomials.h
#test.o: CFLAGS += `pkg-config --cflags m4ri`
......@@ -51,4 +58,4 @@ test_polynomial_main.o: tools_parser.h monomials.h tools.h parser.h polynomial.h
clean:
rm -rf *.o my_mat/ *log.bin
rm -f parser_demo moebius_demo parser_demo_alt monica monica_vector macaulay_gen lanczos reconstruct_monomials test test_parser_main
rm -f parser_demo moebius_demo parser_demo_alt monica monica_vector macaulay_gen lanczos reconstruct_monomials test test_parser_main test_polynomial_main test_monomials_tmp test_enum_main
#include <stdio.h>
#include <stdlib.h>
#include "tools_parser.h"
#include "tools.h"
// #include "monomials.h"
#include "enum.h"
#include "gauss.h"
struct matrix_system {
int row;
int col;
int n; /* # of monomials */
bool **A; /* A[row*col][n] */
bool **B; /* B[row*1][n] */
struct monomial_ctx_t *mono;
};
// This function still need to be tested
// Give A matrix values with monomial sol input
bool **update_mat_A(bool **poly, monomial_t sol, struct polynomial_system *poly_sys)
{
bool **res;
// Alloccate res
res = malloc(sizeof(bool *)* poly_sys->m);
for (int i = 0; i < poly_sys->m; i++)
res[i] = malloc(sizeof(bool) * poly_sys->v);
// Evaluate matrix A with monomial sol input
void evaluate_mat_A(bool **poly, monomial_t sol, struct polynomial_system *poly_sys, bool **eval_A)
{
int cpt_i = -1;
// update poly
for (int i = 0; i < poly_sys->m * poly_sys->v; i++)
{
// check if there is 1 in polynome
bool cur = poly[i][0];
for (int j = 1; j < monomial_rank_degD(poly_sys->n, poly_sys->mono); j++)
bool cur = 0;
for (int j = 0; j < get_Nd(poly_sys->n - poly_sys->v, poly_sys->mono); j++)
{
if (poly[i][j] == 1)
{
if (monomial_gcd(sol, monomial_unrank(poly_sys->mono, j) == sol))
monomial_t mul = monomial_mul(sol, monomial_unrank(poly_sys->mono, j));
if (mul == sol)
cur ^= 1;
}
}
if (i % poly_sys->v == 0)
cpt_i++;
res[cpt_i][i%poly_sys->v] = cur;
eval_A[cpt_i][i%poly_sys->v] = cur;
}
return res;
}
bool *update_mat_B(bool **poly, monomial_t sol, struct polynomial_system *poly_sys)
{
bool *res;
res = malloc(sizeof(bool)* poly_sys->m);
// Evaluate matrix B with monomial sol input
void evaluate_mat_B(bool **poly, monomial_t sol, struct polynomial_system *poly_sys, bool *eval_B)
{
for (int i = 0; i < poly_sys->m; i++)
{
// check if there is 1 in polynome
bool cur = poly[i][0];
for (int j = 1; j < monomial_rank_degD(poly_sys->n, poly_sys->mono); j++)
bool cur = 0;
for (int j = 0; j < get_Nd(poly_sys->n-poly_sys->v, poly_sys->mono); j++)
{
if (poly[i][j] == 1)
{
if (monomial_gcd(sol, monomial_unrank(poly_sys->mono, j) == sol))
monomial_t mul = monomial_mul(sol, monomial_unrank(poly_sys->mono, j));
if (mul == sol)
cur ^= 1;
}
}
res[i] = cur;
eval_B[i] = cur;
}
return res;
}
// traduit un tableau de boolean en un monomial
monomial_t bool_to_mono(bool *arr, int length)
{
monomial_t ans = 0;
for (int i = 0; i < length; i++)
for (int i = length-1; i >= 0; i--)
{
ans <<= 1;
ans ^= arr[i];
......@@ -85,66 +64,106 @@ monomial_t bool_to_mono(bool *arr, int length)
return ans;
}
monomial_t test_sol(monomial_t sol, struct polynomial_system *poly_sys)
// Renvoie -1 si le guess tenté n'est pas bon, et renvoie la solution directement sinon
// sous la forme [x5, x4,..]
monomial_t test_guess(monomial_t guess, struct polynomial_system *poly_sys, bool **eval_A, bool *eval_B)
{
if (sol == -1)
return -1;
bool **new_A = update_mat_A(poly_sys->A, sol, poly_sys);
bool *new_B = update_mat_B(poly_sys->B, sol, poly_sys);
evaluate_mat_A(poly_sys->A, guess, poly_sys, eval_A);
evaluate_mat_B(poly_sys->B, guess, poly_sys, eval_B);
// solve from pdg.c
bool *new_sol = solve(new_A, new_B, poly_sys->m, poly_sys->v);
// solve and check_ans from gauss.h
bool *new_sol = solve(eval_A, eval_B, poly_sys->m, poly_sys->v);
// need to clone A and B to check
bool tmp = check_ans(eval_A, eval_B, poly_sys->m, poly_sys->v, new_sol);
bool tmp = check_ans(new_A, new_B, poly_sys->m, poly_sys->v, new_sol);
// Free A and B
for (int i = 0; i < poly_sys->m; i++)
free(new_A[i]);
free(new_A);
free(new_B);
// bad solution
if (tmp == 0)
if (tmp == 0)
return -1;
// for (int i = 0; i < poly_sys->v; i++)
// printf("%d\t", new_sol[i]);
// printf("\n");
// printf("On decale de %d\n", poly_sys->n - poly_sys->v);
monomial_t sol_v = bool_to_mono(new_sol, poly_sys->v) << (poly_sys->n - poly_sys->v);
return sol_v + guess;
}
return bool_to_mono(tmp, poly_sys->v);
// Ecris m dans le fichier out
// ATTENTION
// m est écris à l'envers par soucis de lisibilité dans le fichier est donc écris:
// [x1, x2, ...]
void write_monomial_to_file(monomial_t m, int length, FILE *out)
{
char s[length+1];
for (int i = 0; i < length; i++)
{
s[i] = '0' + m%2;
m >>= 1;
}
s[length] = '\0';
fprintf(out, "%s\n", s);
}
monomial_t enum_recur(monomial_t a, int b, int v, struct polynomial_system *poly_sys)
/*
* Renvoie RIEN. écrit les solutions trouvées dans out.
*/
void enum_recur(monomial_t guess, int v, struct polynomial_system *poly_sys, FILE *out, bool **eval_A, bool *eval_B)
{
if (v == 0)
return a;
a = a << 1;
a ^= b;
monomial_t sol1 = enum_recur(a, 0, v-1, poly_sys);
monomial_t sol2 = enum_recur(a, 1, v-1, poly_sys);
monomial_t tmp = test_sol(sol1, poly_sys);
if (tmp == -1)
tmp = test_sol(sol2, poly_sys);
return tmp;
{
monomial_t tmp = test_guess(guess, poly_sys, eval_A, eval_B);
if (tmp != -1)
write_monomial_to_file(tmp, poly_sys->n, out);
return;
}
enum_recur(guess << 1, v-1, poly_sys, out, eval_A, eval_B);
enum_recur((guess << 1) + 1, v-1, poly_sys, out, eval_A, eval_B);
return ;
}
monomial_t enumerate(struct polynomial_system *poly_sys)
// write solutions of system with
// [1,x1,x2,...]form
void enumerate(struct polynomial_system *poly_sys, char *filename)
{
// allocate A and B
bool **eval_A = (bool **)malloc(sizeof(bool *) * poly_sys->m);
bool *eval_B = (bool *)malloc(sizeof(bool) * poly_sys->m);
for (int i = 0; i < poly_sys->m; i++)
eval_A[i] = (bool *)malloc(sizeof(bool) * poly_sys->v);
monomial_t a = 0;
monomial_t sol1 = enum_recur(a, 0, poly_sys->n - 1, poly_sys);
monomial_t sol2 = enum_recur(a, 1, poly_sys->n - 1, poly_sys);
if (sol1 != -1)
return sol1;
if (sol2 != -1)
return sol2;
printf("No solution found\n");
return -1;
}
FILE *out = fopen(filename, "w");
enum_recur(a, poly_sys->n - poly_sys->v, poly_sys, out, eval_A, eval_B);
fclose(out);
// free eval_A/B
for (int i = 0; i < poly_sys->m; i++)
free(eval_A[i]);
free(eval_A);
free(eval_B);
// maybe write the number of solutions found
// printf("No solution found\n");
}
int main()
void print_evaluated_A(bool **eval_A, struct polynomial_system *poly_sys)
{
printf("======= Evaluated_A ======\n");
for (int i = 0; i < poly_sys->m; i++)
{
for (int j = 0; j < poly_sys->v; j++)
printf("%d\t", eval_A[i][j]);
printf("\n");
}
printf("\n");
}
return 0;
void print_evaluated_B(bool *eval_B, struct polynomial_system *poly_sys)
{
printf("======= Evaluated_B ======\n");
for (int i = 0; i < poly_sys->m; i++)
printf("%d\n", eval_B[i]);
printf("\n");
}
\ No newline at end of file
#include "monomial_new.h"
#ifndef _ENUM_H_
#define _ENUM_H_
#include "tools_parser.h"
#include "tools.h"
#include "monomials.h"
#include "polynomial.h"
struct polynomial_system {
int n; /* # variables */
int v; /* # linear variables */
char ** variable_name; /* array of strings, size n */
int D; /* max degree of any monomial */
int m; /* # polynomials */
bool ** poly; /* array of polynomials, size m */
bool **A;
bool **B;
struct monomial_ctx_t * mono; /* description of the monomials */
};
bool **update_mat(bool **poly, monomial_t sol, struct polynomial_system *poly_sys);
monomial_t enumerate(struct polynomial_system *poly_sys);
\ No newline at end of file
void evaluate_mat_A(bool **poly, monomial_t sol, struct polynomial_system *poly_sys, bool **eval_A);
void evaluate_mat_B(bool **poly, monomial_t sol, struct polynomial_system *poly_sys, bool *eval_B);
void enumerate(struct polynomial_system *poly_sys, char *filename);
void print_evaluated_A(bool **eval_A, struct polynomial_system *poly_sys);
void print_evaluated_B(bool *eval_B, struct polynomial_system *poly_sys);
void write_monomial_to_file(monomial_t m, int length, FILE *out);
#endif
\ No newline at end of file
// pdg = pivot de gauss
// TODO rename le fichier
#include "gauss.h"
void switch_row(bool **A, bool *B, int p1, int p2)
{
if (p1 == p2)
return ;
bool *tmp = A[p1];
A[p1] = A[p2];
A[p2] = tmp;
bool tmp_b = B[p1];
B[p1] = B[p2];
B[p2] = tmp_b;
}
void elimination_down(bool **A, bool *B, int pivot, int row, int col)
{
B[row] ^= B[pivot];
for (int i = pivot; i < col; i++)
A[row][i] ^= A[pivot][i];
}
void elimination_up(bool **A, bool *B, int pivot, int row, int col)
{
B[row] ^= B[pivot];
A[row][pivot] ^= A[pivot][pivot];
}
void print_sys(bool **A, bool *B, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", A[i][j]);
printf("\t%d\n", B[i]);
}
printf("\n");
}
bool **clone_A(bool **A, int row, int col)
{
bool **res = malloc(sizeof(bool *) * row);
for (int i = 0; i < row; i++)
{
res[i] = malloc(sizeof(bool) * col);
for (int j = 0; j < col; j++)
res[i][j] = A[i][j];
}
return res;
}
bool *clone_B(bool *B, int row)
{
bool *res = malloc(sizeof(bool) * row);
for (int i = 0; i < row; i++)
res[i] = B[i];
return res;
}
// Probleme si i > j
bool *solve(bool **A, bool *B, int row, int col)
{
bool **A_clone = clone_A(A, row, col);
bool *B_clone = clone_B(B, row);
int cpt, i, j;
// Triangulation
for (cpt = 0; cpt < col; cpt++)
{
// Find pivot
for (i = cpt; i < row; i++)
{
if (A_clone[i][cpt] == 1)
{
switch_row(A_clone, B_clone, cpt, i);
break ;
}
}
// Elimination
// i == row <=> column with only 0's
if (i != row)
for (i = cpt+1; i < row; i++)
if (A_clone[i][cpt] == 1)
elimination_down(A_clone, B_clone, cpt, i, col);
}
// Probleme ici si i > j
// Diagonalization
for (i = cpt; i >= 0; i--)
{
// Elimination
for (j = i-1; j >= 0; j--)
if (A_clone[j][i] == 1)
elimination_up(A_clone, B_clone, i, j, col);
}
// Writing sol
bool *sol = malloc(sizeof(bool) * col);
for (int i = 0; i < col; i++)
sol[i] = B_clone[i];
for (int i = 0; i < row; i++)
free(A_clone[i]);
free(A_clone);
free(B_clone);
return sol;
}
void gen_mat(bool **A, bool *B, int row, int col)
{
for (int i = 0; i < row; i++)
{
B[i] = rand()%2;
for (int j = 0; j < col; j++)
A[i][j] = rand()%2;
}
}
// return 1 if solution is correct, 0 else
bool check_ans(bool **A, bool *B, int row, int col, bool *ans)
{
bool check;
for (int i = 0; i < row; i++)
{
check = 0;
for (int j = 0; j < col; j++)
check = check ^ (A[i][j] & ans[j]);
if (check != B[i])
{
// printf("Bad solution...\n");
return 0;
}
}
// printf("Good solution !\n");
// for (int i = 0; i < col; i++)
// printf("%d\n", ans[i]);
// printf("\n");
return 1;
}
// int main(void)
// {
// srand(time(NULL));
// int row = 5, col = 3;
// bool **A;
// bool *B;
// A = malloc(sizeof(bool *) * row);
// for (int i = 0; i < row; i++)
// A[i] = malloc(sizeof(bool) * col);
// B = malloc(sizeof(bool) * row);
// gen_mat(A, B, row, col);
// bool **og_A = clone_A(A, row, col);
// bool *og_B = clone_B(B, row);
// print_sys(A, B, row, col);
// bool *ans = solve(A, B, row, col);
// check_ans(og_A, og_B, row, col, ans);
// return (0);
// }
\ No newline at end of file
#ifndef _GAUSS_H_
#define _GAUSS_H_
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
bool *solve(bool **A, bool *B, int row, int col);
bool check_ans(bool **A, bool *B, int row, int col, bool *ans);
#endif
\ No newline at end of file
......@@ -5,9 +5,6 @@
#include "tools.h"
#include "monomials.h"
typedef __int128 u128;
typedef u128 monomial_t;
struct monomial_ctx_t
{
monomial_t *monomials;
......@@ -368,3 +365,18 @@ void ffs_array(int *tab, int size, struct monomial_ctx_t *mono)
}
}
monomial_t monomial_gcd(monomial_t a, monomial_t b)
{
return a & b;
}
monomial_t monomial_mul(monomial_t a, monomial_t b)
{
return a | b;
}
monomial_t monomial_unrank(struct monomial_ctx_t *mono, int ind)
{
return mono->monomials[ind];
}
\ No newline at end of file
#ifndef _MONOMIALS_H_
#define _MONOMIALS_H_
#include "tools.h"
#define MAXDEG 8
#define MAXDEG 64
typedef __int128 u128;
typedef u128 monomial_t;
struct monomial_ctx_t;
struct monomial_ctx_t * monomial_setup(int n_var, int v, int D);
......@@ -25,4 +30,10 @@ void ffs_array(int *tab, int size, struct monomial_ctx_t *mono);
// int **monomial_transpose(int *mat, u64 size_ker, u64 size_mono, struct monomial_ctx_t *mono);
// bool **matrix_construct(monomial_t *tab, u64 size_tab, struct monomial_ctx_t *mono);
// struct input_poly_t *reconstruct(char *filename_ker, char *filename_ilog, char *filename_jlog, int D, struct input_poly_t *f, struct monomial_ctx_t *mono);
//
\ No newline at end of file
//
/* enum part */
monomial_t monomial_gcd(monomial_t a, monomial_t b);
monomial_t monomial_mul(monomial_t a, monomial_t b);
monomial_t monomial_unrank(struct monomial_ctx_t *mono, int ind);
#endif
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include "tools.h"
#include "monomials_tmp.h"
typedef __int128 monomial_t;
int hamming_weight(monomial_t m)
{
return __builtin_popcountl(m) + __builtin_popcountl(m >> 64);
}
/* generic monomials */
monomial_t monomial_one()
{
return (monomial_t)0;
}
monomial_t monomial_var(int i)
{
return ((monomial_t) 1) << i;
}
monomial_t monomial_mul(monomial_t a, monomial_t b)
{
return a | b;
}
monomial_t monomial_gcd(monomial_t a, monomial_t b)
{
return a & b;
}
int monomial_degree(monomial_t a)
{
return hamming_weight(a);
}
void monomial_deconstruct(monomial_t a, int *vars, int n)
{
for (int i = 0; i < n; i++)
{
vars[i] = (int)(a&1);
a = a>>1;
}
}
bool monomial_isone(monomial_t a)
{
return a == 0;
}
bool monomial_isvar(monomial_t a)
{
return monomial_degree(a) == 1;
}
int monomial_getvar(monomial_t a)
{
if (monomial_isvar(a) == 0)
return -1;
int cpt = 0;
while (a != 1)
{
a >>= 1;
cpt++;
}
return cpt;