Questions on modular arithmetic functions in rat3a.lisp
Subject: Questions on modular arithmetic functions in rat3a.lisp
From: Richard Fateman
Date: Thu, 21 Jun 2012 08:17:32 -0700
On 6/21/2012 6:35 AM, Camm Maguire wrote:
> Greetings!
>
> 1) The comments indicate that modulus is nil or positive. Is it always
> an integer?
All uses of modular arithmetic in the existing code assume that the
modulus is
a prime positive integer. The system refuses to allow modulus:2.5;
it also
gives a warning for modulus:20, a non-prime. It goes into an infinite
loop for modulus:-45. (a bug...)
> 2) The comments indicate that if modulus is non-nil, the arguments to
> ctimes (et.al. ?) are numberp and less than modulus.
proper elements should be less than modulus/2 in abs val. except if
modulus = 2, then the
two proper elements are 0,1.
e.g. modulo 5, the numbers are -2,-1,0,1,2.
If ctimes is given numbers outside that range the result should be in
that range.
> Are they in fact
> integers?
They are integers. It is somewhat unlikely that someone comes up with a
meaningful
interpretation of non-integer here, that makes good use of the rest of
the mechanisms.
> Are they bounded from below?
the result is bounded from below by half the modulus.
> 3) GCL has a C implementation of ctimes which balances modular
> arithmetic between -modulus/2 and modulus/2. The generic lisp version
> seems only to implement the upper bound.
That then is a mistake.
> Is there a reason for this?
Probably it is an error if SBCL does not use a balanced representation..
> Is the modular balancing necessary?
It is possible to use any sequential set of numbers, e.g. 0,1,2,3,4
instead of -2,-1,0,1,2 for
modulus=5, and build a system around that choice. The balanced choice
has a few conveniences
such as some calculations over the integers mod <some huge prime> look
exactly like the
calculations over the integers.
> 4) Why is bctimes/rem used in cbexpt instead of ctimes/mod?
bctimes is faster because it doesn't need to check to see if modulus =
nil . It is called repeatedly
from within the expt program.
If there is an interest in making these programs run fast, it may be
worthwhile to separate
out the case of
modulus <= 2*(most-positive-fixnum)
where the arithmetic can be done in registers etc.
This is in fact the most common case and is presumably slowed down by
the prospect of
ever encountering a bignum modulus.
See the code in the reciprocal in rat3a, as an example. But if you
want to code other stuff in C
as was done by Bill Schelter for GCL, that would make some things
faster. Whether one would
notice it depends on how much rational polynomial arithmetic was being used.
RJF