aboutsummaryrefslogtreecommitdiff
path: root/src/algebra/radix.spad.pamphlet
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
committerdos-reis <gdr@axiomatics.org>2007-08-14 05:14:52 +0000
commitab8cc85adde879fb963c94d15675783f2cf4b183 (patch)
treec202482327f474583b750b2c45dedfc4e4312b1d /src/algebra/radix.spad.pamphlet
downloadopen-axiom-ab8cc85adde879fb963c94d15675783f2cf4b183.tar.gz
Initial population.
Diffstat (limited to 'src/algebra/radix.spad.pamphlet')
-rw-r--r--src/algebra/radix.spad.pamphlet427
1 files changed, 427 insertions, 0 deletions
diff --git a/src/algebra/radix.spad.pamphlet b/src/algebra/radix.spad.pamphlet
new file mode 100644
index 00000000..d26f7b52
--- /dev/null
+++ b/src/algebra/radix.spad.pamphlet
@@ -0,0 +1,427 @@
+\documentclass{article}
+\usepackage{axiom}
+\begin{document}
+\title{\$SPAD/src/algebra radix.spad}
+\author{Stephen M. Watt, Clifton J. Williamson}
+\maketitle
+\begin{abstract}
+\end{abstract}
+\eject
+\tableofcontents
+\eject
+\section{domain RADIX RadixExpansion}
+<<domain RADIX RadixExpansion>>=
+)abbrev domain RADIX RadixExpansion
+++ Author: Stephen M. Watt
+++ Date Created: October 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations: wholeRadix, fractRadix, wholeRagits, fractRagits
+++ Related Domains: BinaryExpansion, DecimalExpansion, HexadecimalExpansion,
+++ RadixUtilities
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeating decimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ decimal expansions or more generally as repeating expansions in any base.
+
+RadixExpansion(bb): Exports == Implementation where
+ bb : Integer
+ I ==> Integer
+ NNI ==> NonNegativeInteger
+ OUT ==> OutputForm
+ RN ==> Fraction Integer
+ ST ==> Stream Integer
+ QuoRem ==> Record(quotient: Integer, remainder: Integer)
+
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(rx) converts a radix expansion to a rational number.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(rx) returns the fractional part of a radix expansion.
+ wholeRagits: % -> List Integer
+ ++ wholeRagits(rx) returns the ragits of the integer part
+ ++ of a radix expansion.
+ fractRagits: % -> Stream Integer
+ ++ fractRagits(rx) returns the ragits of the fractional part
+ ++ of a radix expansion.
+ prefixRagits: % -> List Integer
+ ++ prefixRagits(rx) returns the non-cyclic part of the ragits
+ ++ of the fractional part of a radix expansion.
+ ++ For example, if \spad{x = 3/28 = 0.10 714285 714285 ...},
+ ++ then \spad{prefixRagits(x)=[1,0]}.
+ cycleRagits: % -> List Integer
+ ++ cycleRagits(rx) returns the cyclic part of the ragits of the
+ ++ fractional part of a radix expansion.
+ ++ For example, if \spad{x = 3/28 = 0.10 714285 714285 ...},
+ ++ then \spad{cycleRagits(x) = [7,1,4,2,8,5]}.
+ wholeRadix: List Integer -> %
+ ++ wholeRadix(l) creates an integral radix expansion from a list
+ ++ of ragits.
+ ++ For example, \spad{wholeRadix([1,3,4])} will return \spad{134}.
+ fractRadix: (List Integer, List Integer) -> %
+ ++ fractRadix(pre,cyc) creates a fractional radix expansion
+ ++ from a list of prefix ragits and a list of cyclic ragits.
+ ++ For example, \spad{fractRadix([1],[6])} will return \spad{0.16666666...}.
+
+ Implementation ==> add
+ -- The efficiency of arithmetic operations is poor.
+ -- Could use a lazy eval where either rational rep
+ -- or list of ragit rep (the current) or both are kept
+ -- as demanded.
+
+ bb < 2 => error "Radix base must be at least 2"
+ Rep := Record(sgn: Integer, int: List Integer,
+ pfx: List Integer, cyc: List Integer)
+
+ q: RN
+ qr: QuoRem
+ a,b: %
+ n: I
+
+ radixInt: (I, I) -> List I
+ radixFrac: (I, I, I) -> Record(pfx: List I, cyc: List I)
+ checkRagits: List I -> Boolean
+
+ -- Arithmetic operations
+ characteristic() == 0
+ differentiate a == 0
+
+ 0 == [1, nil(), nil(), nil()]
+ 1 == [1, [1], nil(), nil()]
+ - a == (a = 0 => 0; [-a.sgn, a.int, a.pfx, a.cyc])
+ a + b == (a::RN + b::RN)::%
+ a - b == (a::RN - b::RN)@RN::%
+ n * a == (n * a::RN)::%
+ a * b == (a::RN * b::RN)::%
+ a / b == (a::RN / b::RN)::%
+ (i:I) / (j:I) == (i/j)@RN :: %
+ a < b == a::RN < b::RN
+ a = b == a.sgn = b.sgn and a.int = b.int and
+ a.pfx = b.pfx and a.cyc = b.cyc
+ numer a == numer(a::RN)
+ denom a == denom(a::RN)
+
+ -- Algebraic coercions
+ coerce(a):RN == (wholePart a) :: RN + fractionPart a
+ coerce(n):% == n :: RN :: %
+ coerce(q):% ==
+ s := 1; if q < 0 then (s := -1; q := -q)
+ qr := divide(numer q,denom q)
+ whole := radixInt (qr.quotient,bb)
+ fractn := radixFrac(qr.remainder,denom q,bb)
+ cycle := (fractn.cyc = [0] => nil(); fractn.cyc)
+ [s,whole,fractn.pfx,cycle]
+
+ retractIfCan(a):Union(RN,"failed") == a::RN
+ retractIfCan(a):Union(I,"failed") ==
+ empty?(a.pfx) and empty?(a.cyc) => wholePart a
+ "failed"
+
+ -- Exported constructor/destructors
+ ceiling a == ceiling(a::RN)
+ floor a == floor(a::RN)
+
+ wholePart a ==
+ n0 := 0
+ for r in a.int repeat n0 := bb*n0 + r
+ a.sgn*n0
+ fractionPart a ==
+ n0 := 0
+ for r in a.pfx repeat n0 := bb*n0 + r
+ null a.cyc =>
+ a.sgn*n0/bb**((#a.pfx)::NNI)
+ n1 := n0
+ for r in a.cyc repeat n1 := bb*n1 + r
+ n := n1 - n0
+ d := (bb**((#a.cyc)::NNI) - 1) * bb**((#a.pfx)::NNI)
+ a.sgn*n/d
+
+ wholeRagits a == a.int
+ fractRagits a == concat(construct(a.pfx)@ST,repeating a.cyc)
+ prefixRagits a == a.pfx
+ cycleRagits a == a.cyc
+
+ wholeRadix li ==
+ checkRagits li
+ [1, li, nil(), nil()]
+ fractRadix(lpfx, lcyc) ==
+ checkRagits lpfx; checkRagits lcyc
+ [1, nil(), lpfx, lcyc]
+
+ -- Output
+
+ ALPHAS : String := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+
+ intToExpr(i:I): OUT ==
+ -- computes a digit for bases between 11 and 36
+ i < 10 => i :: OUT
+ elt(ALPHAS,(i-10) + minIndex(ALPHAS)) :: OUT
+
+ exprgroup(le: List OUT): OUT ==
+ empty? le => error "exprgroup needs non-null list"
+ empty? rest le => first le
+ abs bb <= 36 => hconcat le
+ blankSeparate le
+
+ intgroup(li: List I): OUT ==
+ empty? li => error "intgroup needs non-null list"
+ empty? rest li => intToExpr first(li)
+ abs bb <= 10 => hconcat [i :: OUT for i in li]
+ abs bb <= 36 => hconcat [intToExpr(i) for i in li]
+ blankSeparate [i :: OUT for i in li]
+
+ overBar(li: List I): OUT == overbar intgroup li
+
+ coerce(a): OUT ==
+ le : List OUT := nil()
+ if not null a.cyc then le := concat(overBar a.cyc,le)
+ if not null a.pfx then le := concat(intgroup a.pfx,le)
+ if not null le then le := concat("." :: OUT,le)
+ if not null a.int then le := concat(intgroup a.int,le)
+ else le := concat(0 :: OUT,le)
+ rex := exprgroup le
+ if a.sgn < 0 then -rex else rex
+
+ -- Construction utilities
+ checkRagits li ==
+ for i in li repeat if i < 0 or i >= bb then
+ error "Each ragit (digit) must be between 0 and base-1"
+ true
+
+ radixInt(n,bas) ==
+ rits: List I := nil()
+ while abs n ^= 0 repeat
+ qr := divide(n,bas)
+ n := qr.quotient
+ rits := concat(qr.remainder,rits)
+ rits
+
+ radixFrac(num,den,bas) ==
+ -- Rits is the sequence of quotient/remainder pairs
+ -- in calculating the radix expansion of the rational number.
+ -- We wish to find p and c such that
+ -- rits.i are distinct for 0<=i<=p+c-1
+ -- rits.i = rits.(i+p) for i>p
+ -- I.e. p is the length of the non-periodic prefix and c is
+ -- the length of the cycle.
+
+ -- Compute p and c using Floyd's algorithm.
+ -- 1. Find smallest n s.t. rits.n = rits.(2*n)
+ qr := divide(bas * num, den)
+ i : I := 0
+ qr1i := qr2i := qr
+ rits: List QuoRem := [qr]
+ until qr1i = qr2i repeat
+ qr1i := divide(bas * qr1i.remainder,den)
+ qrt := divide(bas * qr2i.remainder,den)
+ qr2i := divide(bas * qrt.remainder,den)
+ rits := concat(qr2i, concat(qrt, rits))
+ i := i + 1
+ rits := reverse_! rits
+ n := i
+ -- 2. Find p = first i such that rits.i = rits.(i+n)
+ ritsi := rits
+ ritsn := rits; for i in 1..n repeat ritsn := rest ritsn
+ i := 0
+ while first(ritsi) ^= first(ritsn) repeat
+ ritsi := rest ritsi
+ ritsn := rest ritsn
+ i := i + 1
+ p := i
+ -- 3. Find c = first i such that rits.p = rits.(p+i)
+ ritsn := rits; for i in 1..n repeat ritsn := rest ritsn
+ rn := first ritsn
+ cfound:= false
+ c : I := 0
+ for i in 1..p while not cfound repeat
+ ritsn := rest ritsn
+ if rn = first(ritsn) then
+ c := i
+ cfound := true
+ if not cfound then c := n
+ -- 4. Now produce the lists of ragits.
+ ritspfx: List I := nil()
+ ritscyc: List I := nil()
+ for i in 1..p repeat
+ ritspfx := concat(first(rits).quotient, ritspfx)
+ rits := rest rits
+ for i in 1..c repeat
+ ritscyc := concat(first(rits).quotient, ritscyc)
+ rits := rest rits
+ [reverse_! ritspfx, reverse_! ritscyc]
+
+@
+\section{domain BINARY BinaryExpansion}
+<<domain BINARY BinaryExpansion>>=
+)abbrev domain BINARY BinaryExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: April 26, 1990
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, binary
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ binary expansions.
+
+BinaryExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(b) converts a binary expansion to a rational number.
+ coerce: % -> RadixExpansion(2)
+ ++ coerce(b) converts a binary expansion to a radix expansion with base 2.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(b) returns the fractional part of a binary expansion.
+ binary: Fraction Integer -> %
+ ++ binary(r) converts a rational number to a binary expansion.
+
+ Implementation ==> RadixExpansion(2) add
+ binary r == r :: %
+ coerce(x:%): RadixExpansion(2) == x pretend RadixExpansion(2)
+
+@
+\section{domain DECIMAL DecimalExpansion}
+<<domain DECIMAL DecimalExpansion>>=
+)abbrev domain DECIMAL DecimalExpansion
+++ Author: Stephen M. Watt
+++ Date Created: October, 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeating decimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ decimal expansions.
+DecimalExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(d) converts a decimal expansion to a rational number.
+ coerce: % -> RadixExpansion(10)
+ ++ coerce(d) converts a decimal expansion to a radix expansion
+ ++ with base 10.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(d) returns the fractional part of a decimal expansion.
+ decimal: Fraction Integer -> %
+ ++ decimal(r) converts a rational number to a decimal expansion.
+
+ Implementation ==> RadixExpansion(10) add
+ decimal r == r :: %
+ coerce(x:%): RadixExpansion(10) == x pretend RadixExpansion(10)
+
+@
+\section{domain HEXADEC HexadecimalExpansion}
+<<domain HEXADEC HexadecimalExpansion>>=
+)abbrev domain HEXADEC HexadecimalExpansion
+++ Author: Clifton J. Williamson
+++ Date Created: April 26, 1990
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, hexadecimal
+++ Examples:
+++ References:
+++ Description:
+++ This domain allows rational numbers to be presented as repeating
+++ hexadecimal expansions.
+
+HexadecimalExpansion(): Exports == Implementation where
+ Exports ==> QuotientFieldCategory(Integer) with
+ coerce: % -> Fraction Integer
+ ++ coerce(h) converts a hexadecimal expansion to a rational number.
+ coerce: % -> RadixExpansion(16)
+ ++ coerce(h) converts a hexadecimal expansion to a radix expansion
+ ++ with base 16.
+ fractionPart: % -> Fraction Integer
+ ++ fractionPart(h) returns the fractional part of a hexadecimal expansion.
+ hex: Fraction Integer -> %
+ ++ hex(r) converts a rational number to a hexadecimal expansion.
+
+ Implementation ==> RadixExpansion(16) add
+ hex r == r :: %
+ coerce(x:%): RadixExpansion(16) == x pretend RadixExpansion(16)
+
+@
+\section{package RADUTIL RadixUtilities}
+<<package RADUTIL RadixUtilities>>=
+)abbrev package RADUTIL RadixUtilities
+++ Author: Stephen M. Watt
+++ Date Created: October 1986
+++ Date Last Updated: May 15, 1991
+++ Basic Operations:
+++ Related Domains: RadixExpansion
+++ Also See:
+++ AMS Classifications:
+++ Keywords: radix, base, repeading decimal
+++ Examples:
+++ References:
+++ Description:
+++ This package provides tools for creating radix expansions.
+RadixUtilities: Exports == Implementation where
+ Exports ==> with
+ radix: (Fraction Integer,Integer) -> Any
+ ++ radix(x,b) converts x to a radix expansion in base b.
+ Implementation ==> add
+ radix(q, b) ==
+ coerce(q :: RadixExpansion(b))$AnyFunctions1(RadixExpansion b)
+
+@
+\section{License}
+<<license>>=
+--Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
+--All rights reserved.
+--
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are
+--met:
+--
+-- - Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+--
+-- - Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in
+-- the documentation and/or other materials provided with the
+-- distribution.
+--
+-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+--
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+--IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+--TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+--PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+--OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+--EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+--PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+@
+<<*>>=
+<<license>>
+
+<<domain RADIX RadixExpansion>>
+<<domain BINARY BinaryExpansion>>
+<<domain DECIMAL DecimalExpansion>>
+<<domain HEXADEC HexadecimalExpansion>>
+<<package RADUTIL RadixUtilities>>
+@
+\eject
+\begin{thebibliography}{99}
+\bibitem{1} nothing
+\end{thebibliography}
+\end{document}