Next: Z and Q, Previous: Installation, Up: Top [Contents][Index]
CALIB defines a set of algebraic domains.
Each domain D
provides a set of operations that can be
performed upon algebraic values (i.e., objects) that are
members of domain D
(or other domains).
In most cases, a domain D
must be specified by
instantiating it with certain parameters.
For example, when creating a Zp domain (the integers modulo a prime
p), one must specify a particular prime p.
For example:
struct calib_Zp_dom * dom; dom = calib_make_Zp_dom_ui (23);
creates a domain dom
representing “the integers modulo 23.”
All future operations invoked via dom
understand that the prime
modulus being used is 23.
If one invokes dom -> add (...)
or dom -> inv (...)
, it
will be understood to mean “addition modulo 23” or “multiplicative
inverse modulo 23,” respectively.
Most of CALIB’s operations exist as “member functions” (i.e., members that are pointers to functions) residing in the corresponding domain object.
The fundmental architectural idea being explored in CALIB is this notion of operations provided by domain objects that represent completely specified algebraic domains.
A more complicated CALIB domain can be constructed to represent the Galois Field GF(p^k) defined by the polynomial x^3 + 2x + 7 which is a monic, irreducible polynomial in Zp[x], with p=23.
The central idea of CALIB is that all details of this algebraic
structure (i.e., the prime p=23 and the Galois Field generator
polynomial) are fully encapsulated within a hierarchically structured
set of domain objects that contain all of the instantiated data
(e.g., prime p = 23
and generator polynomial
x^3 + 2x + 7).
The constructed domain object then provides operations/algorithms
operating over the “values” of that domain.
Domain objects in calib all use the following naming convention:
struct calib_FOO_dom;
where FOO
denotes the type of algebraic domain.
The algebraic values that represent members or instances of a domain are usually represented by a second object, conventionally named as follows:
struct calib_FOO_obj;
Exceptions to this rule occur for domains whose values are represented
directly as GMP integers or rationals.
(The Zp
domain is the only current exception to this rule.
Zp
does not provide a struct calib_Zp_obj
“value object,” but instead represents its values directly as GMP
integers.)
CALIB has adopted the GMP conventions for value object construction
and destruction: providing init()
and clear()
operations
to initialize raw value objects in the domain.
In many cases, the ability to initialize and clear given arrays of
such objects are also provided.
These conventions permit the value objects (if desired) to be local
variables of a function, efficiently stored in the stack frame of the
function, rather than dynamically allocated from the memory heap.
Unless otherwise specified, the “value” of a value object after initialization is zero.
CALIB value objects always contain the domain to which they belong,
which must be specified at value object init()
time.
This has at least two direct implications:
Many of CALIB’s domains provide a dup()
function that returns a
dynamically-allocated copy of the given source value, and a
corresponding free()
function that combines the clear()
operation with a call to the standard C library free()
function.
There is no garbage collection with CALIB. It uses standard C programming methods to manage memory usage with all of the corresponding advantages (efficiency) and pitfalls (memory leaks). Good tools are available for detecting memory leaks, and they seem to work well with CALIB.
The header file "calib/types.h"
provides the following typedefs:
typedef signed char calib_int8s; typedef unsigned char calib_int8u; typedef char calib_int8; typedef signed short calib_int16s; typedef unsigned short calib_int16u; typedef short calib_int16; typedef signed int calib_int32s; typedef unsigned int calib_int32u; typedef int calib_int32; typedef signed long long calib_int64s; typedef unsigned long long calib_int64u; typedef long long calib_int64; typedef char calib_bool; /* Types mimicking those that "should" be in GMP (but are not). */ typedef signed long int calib_si_t; typedef unsigned long int calib_ui_t;
These provide 8, 16, 32 and 64-bit integers, with versions that are
specifically unsigned
, signed
and the “natural”
signedness of the given type.
(For example, the C standard gives implementations freedom for
char
to be either signed
or unsigned
.)
The designers of GMP missed an opportunity to define typedef
s
like gmp_ui_t
and gmp_si_t
to encapsulate the types of
“raw,” language-level unsigned
and signed
integer
types used in the GMP function type signatures.
CALIB avoids this pitfall by providing calib_ui_t
and
calib_si_t
.
Unless otherwise specified, the same address can be passed to
arguments that are pointers to objects of the same type.
The following is an example where two inputs and an output argument
all refer to the same object POLY
:
const struct calib_Zx_dom * Zx; struct calib_Zx_obj POLY; Zx = calib_get_Zx_dom (); Zx -> init (&POLY); ... /* This squares the Z[x] polynomial POLY. */ Zx -> mul (&POLY, &POLY, &POLY);
For functions having multiple output arguments, however, it is
never permitted to pass the same (non-NULL
) address to
two or more such output arguments — the result in such cases would
depend upon the order in which the CALIB function assigns these output
values.
CALIB chooses to leave such assignment order explicitly undefined.
Next: Z and Q, Previous: Installation, Up: Top [Contents][Index]