The goal of decoding
is to provide decoding algorithms for error
correcting codes. We tried to write algorithms in a generic way so
that a lot of alphabets can be used (e.g. finite fields, finite local
rings). It is up to the user of the library to give some C code
that provides needed functions to manipulate the elements of the
chosen alphabet. The word "alphabet" is badly chosen because decoding
requires an alphabet to be a (not nessarily commutative) ring with
identity. We will use the words "alphabet" and "ring" interchangeably.
The current page describes how to provide your own alphabet to
decoding
. A few alphabets, such as prime fields, are provided by
decoding
but are far from being optimized. For exemple, if you want
optimized finite fields in caracteristic 2, you can use MPFQ.
For a list of alphabets proposed by decoding
see
decoding-alphabets
(3).
It is strongly recommanded to have a separated file for each alphabet
you want to use. Before doing anything, you must include
decoding/ring_reset.h
.
#include <decoding/ring_reset.h>
This file undefs some macros that could have been defined by
another alphabet. For details see decoding-ring-defines
(3).
Then you must give a name to the ring you are implementing with
the R
macro. For example
#define R GF5
This name will correspond to the C type to declare elements of GF(5).
All functions that manipulate elements of GF(5), such as polynomial
multiplication, will see their names prefixed with GF5
.
For test purpose you can define how to create the ring in MAGMA
with the GF_MAGMA_DECL
macro. It is not mandatory.
#define GF_MAGMA_DECL "k := GF(5)"
Now you declare the C type to represent elements of your ring.
For example, with GF(5), one only needs an int
to represents
its elements.
typedef int R[1];
Note that we have not typedef int R
. This is because the first
argument of a function manipulating elements of GF(5) gets the
result of the computation.
The following functions must be provided. They follow the semantic
of the GMP mpz_
functions. This document is generated from the
comments of the include/decoding/rings/GF5.c
, you can look at it
to have a working example of a ring whose elements hold in a C int
.
void R_clear(R a);
Frees the memory occupied by a
.
If you use a
after a call to R_clear
the behavior is undefined.
void R_clears(R a);
Free the memory occupied by a NULL-terminated list of R
variables.
If you use one of the variable after a call to R_clears
the behavior
is undefined.
void R_init(R a);
Initialize a
and set its value to 0
. This is the
place to allocate some memory needed for a
.
void R_inits(R a,...);
Initialize a NULL-terminated list of R
variables, and set their
values to 0
. This is the place to allocate some memory needed for
the variables.
void R_copy(R r,R a);
Copy the value of a
into r
. This must be a deep copy.
void R_init_copy(R r,R a);
Initialize r
and do a deep copy of a
into r
.
void R_print(FILE *out,R a);
Print (prettyprint) a
into the output stream out
.
int cmp(R a,R b);
Compare a
and b
and returns 0
if and only if the value of
a
is mathematically equal to the value of b
.
int R_iszero(R a);
Compare a
and 0
. Returns 0
if and only if a
is nonzero.
void R_zero(R r);
Set r
to 0
.
void R_random(R r);
Set r
to a random element of the ring.
void R_add(R r,R a,R b);
Set r
to a + b
.
Note that r
, a
and b
can point to the same memory.
void R_sub(R r,R a,R b);
Set r
to a - b
.
Note that r
, a
and b
can point to the same memory.
void R_sub_sub(R r,R a,R b);
Set r
to r - a - b
.
Note that r
, a
and b
can point to the same memory.
void R_add_mul(R r,R a,R b);
Set r
to r + (a * b)
.
Note that r
, a
and b
can point to the same memory.
void R_sub_mul(R r,R a,R b);
Set r
to r - (a * b)
.
Note that r
, a
and b
can point to the same memory.
void R_neg(R r,R a);
Set r
to -a
.
Note that r
and a
can point to the same memory.
void R_mul(R r,R a,R b);
Set r
to a * b
.
Note that r
, a
and b
can point to the same memory.
void R_square(R r,R a);
Set r
to a * a
.
Note that r
and a
can point to the same memory.
int R_inv(R r,R a);
Set r
to a^-1
. Return 0
if and only if a
has an inverse.
If a
has no inverse then the value of r
is undefined.
Note that r
and a
can point to the same memory.
int R_div(R r,R a,R b);
Set r
to a / b)
. Return 0
if and only if b
has an inverse.
If b
has no inverse then the value of r
is undefined.
Note that r
, a
and b
can point to the same memory.
void R_castint(R r,int a);
Set r
to the value of the image of a
in the ring.
void R_next(R r,R a);
Set r
to the element of the ring following a
.
Suppose that your ring has cardinality n
.
You must order the elements of your ring so that they can all
be reached with exactly n
calls to R_next
.
This function is useful to construct the support of Reed-Solomon
codes.
You can add auxiliary variables and functions. Let say you want
to add myfunc
. It is recommended to prefix the function name
with R_
. This is how to proceed:
#define R_myfunc __C(R,_myfunc)
void R_myfunc(int a,R b);
[ ... ]
void R_myfunc(int a,R b) {
...
}
[ ... ]
#undef R_myfunc
The [ ... ]
usually contains the implementation of the ring,
at least all the functions descrobed above.
You can use the new function with the name R_myfunc
before the
#undef R_myfunc
. The __C
macros concatenates R
(GF5
for
example) and _myfunc
. Thus name of the new function in other source
files or after the #undef R_myfunc
is GF5_myfunc
. The same holds
for variables:
#define R_myvar __C(R,_myvar)
some_type R_myvar;
[ ... ]
#undef R_myvar
Finally you must include decoding/algos.h
at the end of the source
file.
#include <decoding/algos.h>
Written by Guillaume Quintin (coincoin169g@gmail.com).
decoding-alphabets
(3)
decoding-ring-defines
(3)
MPFQ(http://mpfq.gforge.inria.fr/),
GMP(http://gmplib.org/),
MAGMA(http://magma.maths.usyd.edu.au/magma/)