Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ALMASTY
mq
Commits
2b12d3b3
Commit
2b12d3b3
authored
May 09, 2022
by
QuentinH
Browse files
c
parent
4e3793f9
Changes
3
Show whitespace changes
Inline
Side-by-side
enum.c
0 → 100644
View file @
2b12d3b3
#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
monomial_new.c
0 → 100644
View file @
2b12d3b3
#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
monomial_new.h
0 → 100644
View file @
2b12d3b3
#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
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment