Commit 2b12d3b3 authored by QuentinH's avatar QuentinH
Browse files

c

parent 4e3793f9
#include <stdio.h>
#include <stdlib.h>
#include "tools_parser.h"
#include "tools.h"
// #include "monomials.h"
#include "monomial_new.h"
// int convert_gray_code(int n)
// {
// return n ^ (n >> 1);
// }
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 */
struct monomial_ctx_t * mono; /* description of the monomials */
};
// Give A matrix values with monomial sol input
bool **update_mat(bool **poly, monomial_t sol, struct polynomial_system *poly_sys)
{
bool **res;
// Aloccate 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);
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++)
{
if (poly[i][j] == 1)
{
if (monomial_gcd(sol, monomial_unrank(poly_sys->mono, j) == sol))
cur ^= 1;
}
}
if (i % poly_sys->v == 0)
cpt_i++;
res[cpt_i][i%poly_sys->v] = cur;
}
return res;
}
//TODO
monomial_t solve(monomial_t sol, struct polynomial_system *poly_sys)
{
if (sol == -1)
return -1;
return;
}
monomial_t enum_recur(monomial_t a, int b, int v, struct polynomial_system *poly_sys)
{
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 = solve(sol1, poly_sys);
if (tmp == -1)
tmp = solve(sol2, poly_sys);
return tmp;
}
monomial_t enumerate(struct polynomial_system *poly_sys)
{
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;
}
int main()
{
// for (int n = 0; n < 16; n++)
// {
// printf("n = %d, ng = %d\n", n, convert_gray_code(n));
// }
printf("%d\n", 1 << 1);
return 0;
}
\ No newline at end of file
#include "monomial_new.h"
struct monomial_ctx_t
{
monomial_t *monomials;
int Nd[MAXDEG];
int D;
int n_var;
int v;
};
monomial_t monomial_one()
{
return (monomial_t)0;
}
monomial_t monomial_var(int n)
{
monomial_t res = 1;
res = res << n;
return res;
}
monomial_t monomial_mul(int a, int b, struct monomial_ctx_t *mono)
{
return (monomial_rank(mono, mono->monomials[a] | mono->monomials[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 nb_vars)
{
vars = malloc(sizeof(int) * nb_vars);
for (int i = 0; i < nb_vars; i++)
{
vars[i] = a%2;
a = a >> 1;
}
return ;
}
void monomial_deconstruct(monomial_t a, int *vars, int nb_vars)
{
vars = malloc(sizeof(int) * nb_vars);
for (int i = 0; i < nb_vars; i++)
vars[nb_vars - i - 1] = a&(1<<i);
return ;
}
bool monomial_isone(monomial_t a)
{
return a == 0;
}
bool monomial_isvar(monomial_t a)
{
if (hamming_weight(a) == 1)
return 1;
return 0;
}
int monomial_getvar(monomial_t a)
{
if (monomial_isvar(a))
return ffs(a);
return -1;
}
static int hamming_weight(monomial_t m)
{
return __builtin_popcountl(m) + __builtin_popcountl(m >> 64);
}
static int binary_search(monomial_t target, int lo, int hi, struct monomial_ctx_t *mono)
{
hi -= 1;
while (lo <= hi)
{
int mid = (lo + hi) / 2;
if (target > mono->monomials[mid])
lo = mid + 1;
else if (target < mono->monomials[mid])
hi = mid - 1;
else
return mid;
}
assert(0);
}
bool monomial_isvalid(const struct monomial_ctx_t *mono, monomial_t a)
{
monomial_t mask = 0;
for (int i = 1; i < mono->Nd[1]; i++)
mask = mask | mono->monomials[i];
if (hamming_weight(mask & a) < 2)
return 1;
return 0;
}
int monomial_rank(const struct monomial_ctx_t *mono, monomial_t a)
{
int d = hamming_weight(a);
return binary_search(a, mono->Nd[d], mono->Nd[d + 1], mono);
}
monomial_t monomial_unrank(const struct monomial_ctx_t *mono, int n)
{
return mono->monomials[n];
}
int monomial_rank_degD(int D, struct monomial_ctx_t *mono)
{
return mono->Nd[D];
}
// enumerate in grlex order
static int monomial_enumerate_lex(int degree, monomial_t *out, int n_var)
{
if (degree == 0) {
if (out != NULL)
out[0] = 0;
return 1;
}
int count = 0;
monomial_t top = mkvar(n_var);
monomial_t i = mkvar(n_var-1);
while (i < top) {
if (out != NULL)
out[count] = i;
count++;
if (hamming_weight(i) < degree)
i++;
else if (hamming_weight(i) == degree)
{
if (i%2 == 0)
i += i^(i & (i-1));
else
i++;
}
else
printf("Error in monomial_enumerate_lex\n");
}
return count;
}
static int monomial_rank_lex(monomial_t m, struct monomial_ctx_t *mono)
{
return binary_search(m, mono->Nd[0], mono->Nd[1], mono);
}
static void monomial_setup_list(struct monomial_ctx_t *mono)
{
int D = mono->D;
assert(D >= 2);
double start = wtime();
log(0, "Monomials setup\n");
log(1, " - Counting monomials\n");
mono->Nd[0] = 0;
for (int d = 0; d <= D; d++) {
int binom_n_d = monomial_enumerate(d, NULL, mono->n_var); /* not the smartest way to do the job... */
mono->Nd[d + 1] = mono->Nd[d] + binom_n_d;
log(2, " - %d monomials of degree %d\n", binom_n_d, d);
}
log(1, " - Building monomial list\n");
mono->monomials = alloc_array(mono->Nd[D + 1], sizeof(*(mono->monomials)), "monomial list");
for (int d = 0; d <= D; d++)
monomial_enumerate(d, &(mono->monomials[mono->Nd[d]]), mono->n_var);
// test_grlex_order(mono);
// test_ranking(mono);
log(1, " - Monomials setup: %.1fs\n", wtime() - start);
}
/* public functions */
struct monomial_ctx_t *monomial_setup(int n_var, int v, int D)
{
struct monomial_ctx_t *mono = (struct monomial_ctx_t *)malloc(sizeof(struct monomial_ctx_t));
mono->v = v;
mono->D = D;
mono->n_var = n_var;
monomial_setup_list(mono);
return mono;
}
static void monomial_setup_list_lex(struct monomial_ctx_t *mono)
{
int D = mono->D;
assert(D >= 2);
double start = wtime();
log(0, "Monomials setup\n");
log(1, " - Counting monomials\n");
mono->Nd[0] = 0;
for (int n = 0; n < mono->n_var; n++) {
int binom_n_d = monomial_enumerate_lex(D, NULL, n+1); /* not the smartest way to do the job... */
mono->Nd[n + 1] = mono->Nd[n] + binom_n_d;
// log(2, " - %d monomials of degree %d\n", binom_n_d, d);
}
log(2, " - %d monomials of degree <= %d\n", mono->Nd[mono->n_var], D);
log(1, " - Building monomial list\n");
mono->monomials = alloc_array(mono->Nd[mono->n_var], sizeof(*(mono->monomials)), "monomial list");
mono->monomials[0] = 0;
for (int i = 1; i < mono->n_var; i++)
monomial_enumerate(D, mono->monomials + mono->Nd[i-1], i);
// test_grlex_order(mono);
// test_ranking(mono);
log(1, " - Monomials setup: %.1fs\n", wtime() - start);
}
/* public functions */
struct monomial_ctx_t *monomial_setup_lex(int n_var, int v, int D)
{
struct monomial_ctx_t *mono = (struct monomial_ctx_t *)malloc(sizeof(struct monomial_ctx_t));
mono->v = v;
mono->D = D;
mono->n_var = n_var;
monomial_setup_list_lex(mono);
return mono;
}
\ No newline at end of file
#include "tools.h"
#define MAXDEG 8
#include <assert.h>
#include <stdlib.h>
#include <err.h>
typedef __int128 monomial_t;
struct monomial_ctx_t;
/* generic monomials */
monomial_t monomial_one();
monomial_t monomial_var(int n);
monomial_t monomial_mul(int a, int b, struct monomial_ctx_t *mono);
monomial_t monomial_gcd(monomial_t a, monomial_t b);
int monomial_degree(monomial_t a);
void monomial_deconstruct(monomial_t a, int *vars, int nb_vars);
bool monomial_isone(monomial_t a);
bool monomial_isvar(monomial_t a);
int monomial_getvar(monomial_t a);
/* ordered monomials */
struct monomial_ctx_t * monomial_setup_lex(int n_var, int D);
struct monomial_ctx_t * monomial_setup(int n_var, int v, int D);
bool monomial_isvalid(const struct monomial_ctx_t *mono, monomial_t a);
int monomial_rank(const struct monomial_ctx_t *mono, monomial_t a);
monomial_t monomial_unrank(const struct monomial_ctx_t *mono, int i);
int monomial_rank_degD(int D, struct monomial_ctx_t *mono);
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment