]>
The Segment domain provides a generalized interval type.
Segments are created using the .. construct by indicating the (included) end points.
The first end point is called the loloSegment and the second is called hihiSegment.
These names are used even though the end points might belong to an unordered set.
In addition to the end points, each segment has an integer ``increment.'' An increment can be specified using the ``by'' construct.
This part can be obtained using the incrincrSegment function.
Unless otherwise specified, the increment is 1.
A single value can be converted to a segment with equal end points. This happens if segments and single values are mixed in a list.
If the underlying type is an ordered ring, it is possible to perform additional operations. The expandexpandSegment operation creates a list of points in a segment.
If k > 0, then expand(l..h by k) creates the list [l, l+k, ..., lN] where lN <= h < lN+k. If k < 0, then lN >= h > lN+k.
It is also possible to expand a list of segments. This is equivalent to appending lists obtained by expanding each segment individually.
For more information on related topics, see SegmentBindingXmpPage and UniversalSegmentXmpPage .
The SegmentBinding type is used to indicate a range for a named symbol.
First give the symbol, then an = and finally a segment of values.
This is used to provide a convenient syntax for arguments to certain operations.
The left-hand side must be of type Symbol but the right-hand side can be a segment over any type.
The left- and right-hand sides can be obtained using the variablevariableSegmentBinding and segmentsegmentSegmentBinding operations.
For more information on related topics, see SegmentXmpPage and UniversalSegmentXmpPage .
The Set domain allows one to represent explicit finite sets of values. These are similar to lists, but duplicate elements are not allowed.
Sets can be created by giving a fixed set of values ...
or by using a collect form, just as for lists. In either case, the set is formed from a finite collection of values.
The basic operations on sets are intersectintersectSet, unionunionSet, differencedifferenceSet, and symmetricDifferencesymmetricDifferenceSet.
The set difference(s,t) contains those members of s which are not in t.
The set symmetricDifference(s,t) contains those elements which are in s or t but not in both.
Set membership is tested using the member?member?Set operation.
The subset?subset?Set function determines whether one set is a subset of another.
When the base type is finite, the absolute complement of a set is defined. This finds the set of all multiplicative generators of PrimeField 11---the integers mod 11.
The following values are not generators.
Often the members of a set are computed individually; in addition, values can be inserted or removed from a set over the course of a computation.
There are two ways to do this:
One is to view a set as a data structure and to apply updating operations.
The other way is to view a set as a mathematical entity and to create new sets from old.
For more information about lists, see ListXmpPage .
The SingleInteger domain is intended to provide support in Axiom for machine integer arithmetic. It is generally much faster than (bignum) Integer arithmetic but suffers from a limited range of values. Since Axiom can be implemented on top of various dialects of Lisp, the actual representation of small integers may not correspond exactly to the host machines integer representation.
In the CCL implementation of AXIOM (Release 2.1 onwards) the underlying representation of SingleInteger is the same as Integer. The underlying Lisp primitives treat machine-word sized computations specially.
You can discover the minimum and maximum values in your implementation by using minminSingleInteger and maxmaxSingleInteger.
To avoid confusion with Integer, which is the default type for integers, you usually need to work with declared variables (ugTypesDeclarePage in Section ugTypesDeclareNumber ) ...
or use package calling (ugTypesPkgCallPage in Section ugTypesPkgCallNumber ).
You can add, multiply and subtract SingleInteger objects, and ask for the greatest common divisor (gcd).
The least common multiple (lcm) is also available.
Operations mulmodmulmodSingleInteger, addmodaddmodSingleInteger, submodsubmodSingleInteger, and invmodinvmodSingleInteger are similar---they provide arithmetic modulo a given small integer. Here is .
To reduce a small integer modulo a prime, use positiveRemainderpositiveRemainderSingleInteger.
Operations AndAndSingleInteger, OrOrSingleInteger, xorxorSingleInteger, and NotNotSingleInteger provide bit level operations on small integers.
Use shift(int,numToShift) to shift bits, where i is shifted left if numToShift is positive, right if negative.
Many other operations are available for small integers, including many of those provided for Integer. To see the other operations, use the Browse HyperDoc facility (ugBrowsePage in Section ugBrowseNumber ).
The SparseTable domain provides a general purpose table type with default entries.
Here we create a table to save strings under integer keys. The value "Try again!" is returned if no other value has been stored for a key.
Entries can be stored in the table.
These values can be retrieved as usual, but if a look up fails the default entry will be returned.
To see which values are explicitly stored, the keyskeysSparseTable and entriesentriesSparseTable functions can be used.
If a specific table representation is required, the GeneralSparseTable constructor should be used. The domain SparseTable(K, E, dflt) is equivalent to GeneralSparseTable(K,E,Table(K,E), dflt). For more information, see TableXmpPage and GeneralSparseTableXmpPage .
The top level matrix type in Axiom is Matrix (see MatrixXmpPage ), which provides basic arithmetic and linear algebra functions. However, since the matrices can be of any size it is not true that any pair can be added or multiplied. Thus Matrix has little algebraic structure. Sometimes you want to use matrices as coefficients for polynomials or in other algebraic contexts. In this case, SquareMatrix should be used. The domain SquareMatrix(n,R) gives the ring of n by n square matrices over R. Since SquareMatrix is not normally exposed at the top level, you must expose it before it can be used.
Once SQMATRIX has been exposed, values can be created using the squareMatrixsquareMatrixSquareMatrix function.
The usual arithmetic operations are available.
Square matrices can be used where ring elements are required. For example, here is a matrix with matrix entries.
Or you can construct a polynomial with square matrix coefficients.
This value can be converted to a square matrix with polynomial coefficients.
For more information on related topics, see ugTypesWritingModesPage in Section ugTypesWritingModesNumber , ugTypesExposePage in Section ugTypesExposeNumber , and MatrixXmpPage .
The SquareFreeRegularTriangularSet domain constructor implements square-free regular triangular sets. See the RegularTriangularSet domain constructor for general regular triangular sets. Let T be a regular triangular set consisting of polynomials t1, ..., tm ordered by increasing main variables. The regular triangular set T is square-free if T is empty or if t1, ..., tm-1 is square-free and if the polynomial tm is square-free as a univariate polynomial with coefficients in the tower of simple extensions associated with t1, ..., tm-1.
The main interest of square-free regular triangular sets is that their associated towers of simple extensions are product of fields. Consequently, the saturated ideal of a square-free regular triangular set is radical. This property simplifies some of the operations related to regular triangular sets. However, building square-free regular triangular sets is generally more expensive than building general regular triangular sets.
As the RegularTriangularSet domain constructor, the SquareFreeRegularTriangularSet domain constructor also implements a method for solving polynomial systems by means of regular triangular sets. This is in fact the same method with some adaptations to take into account the fact that the computed regular chains are square-free. Note that it is also possible to pass from a decomposition into general regular triangular sets to a decomposition into square-free regular triangular sets. This conversion is used internally by the LazardSetSolvingPackage package constructor.
N.B. When solving polynomial systems with the SquareFreeRegularTriangularSet domain constructor or the LazardSetSolvingPackage package constructor, decompositions have no redundant components. See also LexTriangularPackage and ZeroDimensionalSolvePackage for the case of algebraic systems with a finite number of (complex) solutions.
We shall explain now how to use the constructor SquareFreeRegularTriangularSet.
This constructor takes four arguments. The first one, R, is the coefficient ring of the polynomials; it must belong to the category GcdDomain. The second one, E, is the exponent monoid of the polynomials; it must belong to the category OrderedAbelianMonoidSup. the third one, V, is the ordered set of variables; it must belong to the category OrderedSet. The last one is the polynomial ring; it must belong to the category RecursivePolynomialCategory(R,E,V). The abbreviation for SquareFreeRegularTriangularSet is SREGSET.
Note that the way of understanding triangular decompositions is detailed in the example of the RegularTriangularSet constructor.
Let us illustrate the use of this constructor with one example (Donati-Traverso). Define the coefficient ring.
Define the list of variables,
and make it an ordered set;
then define the exponent monoid.
Define the polynomial ring.
Let the variables be polynomial.
Now call the SquareFreeRegularTriangularSet domain constructor.
Define a polynomial system.
First of all, let us solve this system in the sense of Kalkbrener.
And now in the sense of Lazard (or Wu and other authors).
Now to see the difference with the RegularTriangularSet domain constructor, we define:
and compute:
If you look at the second set in both decompositions in the sense of Lazard, you will see that the polynomial with main variable y is not the same.
Let us understand what has happened.
We define:
Then we compute:
A Stream object is represented as a list whose last element contains the wherewithal to create the next element, should it ever be required.
Let ints be the infinite stream of non-negative integers.
By default, ten stream elements are calculated. This number may be changed to something else by the system command )set streams calculate. For the display purposes of this book, we have chosen a smaller value.
More generally, you can construct a stream by specifying its initial value and a function which, when given an element, creates the next element.
You can create the stream of odd non-negative integers by either filtering them from the integers, or by evaluating an expression for each integer.
You can accumulate the initial segments of a stream using the scanscanStreamFunctions2 operation.
The corresponding elements of two or more streams can be combined in this way.
Many operations similar to those applicable to lists are available for streams.
The packages StreamFunctions1, StreamFunctions2 and StreamFunctions3 export some useful stream manipulation operations. For more information, see ugLangItsPage in Section ugLangItsNumber , ugProblemSeriesPage in Section ugProblemSeriesNumber , ContinuedFractionXmpPage , and ListXmpPage .
The type String provides character strings. Character strings provide all the operations for a one-dimensional array of characters, plus additional operations for manipulating text. For more information on related topics, see CharacterXmpPage and CharacterClassXmpPage . You can also issue the system command )show String to display the full list of operations defined by String.
String values can be created using double quotes.
Note, however, that double quotes and underscores must be preceded by an extra underscore.
It is also possible to use newnewString to create a string of any size filled with a given character. Since there are many new functions it is necessary to indicate the desired type.
The length of a string is given by #.
Indexing operations allow characters to be extracted or replaced in strings. For any string s, indices lie in the range 1.. #s.
Indexing is really just the application of a string to a subscript, so any application syntax works.
If it is important not to modify a given string, it should be copied before any updating operations are used.
Operations are provided to split and join strings. The concatconcatString operation allows several strings to be joined together.
There is a version of concatconcatString that works with two strings.
Juxtaposition can also be used to concatenate strings.
Substrings are obtained by giving an index range.
A string can be split into several substrings by giving a separation character or character class.
Unwanted characters can be trimmed from the beginning or end of a string using the operations trimtrimString, leftTrimleftTrimString and rightTrimrightTrimString.
Each of these functions takes a string and a second argument to specify the characters to be discarded.
The second argument can be given either as a single character or as a character class.
Strings can be changed to upper case or lower case using the operations upperCaseupperCaseString, upperCase!upperCase!String, lowerCaselowerCaseString and lowerCase!lowerCase!String.
The versions with the exclamation mark change the original string, while the others produce a copy.
Some basic string matching is provided. The function prefix?prefix?String tests whether one string is an initial prefix of another.
A similar function, suffix?suffix?String, tests for suffixes.
The function substring?substring?String tests for a substring given a starting position.
A number of positionpositionString functions locate things in strings. If the first argument to position is a string, then position(s,t,i) finds the location of s as a substring of t starting the search at position i.
If s is not found, then 0 is returned (minIndex(s)-1 in IndexedString).
To search for a specific character or a member of a character class, a different first argument is used.
This domain provides a table type in which the keys are known to be strings so special techniques can be used. Other than performance, the type StringTable(S) should behave exactly the same way as Table(String,S). See TableXmpPage for general information about tables.
This creates a new table whose keys are strings.
The value associated with each string key is the number of characters in the string.
Symbols are one of the basic types manipulated by Axiom. The Symbol domain provides ways to create symbols of many varieties.
The simplest way to create a symbol is to ``single quote'' an identifier.
This gives the symbol even if x has been assigned a value. If x has not been assigned a value, then it is possible to omit the quote.
Declarations must be used when working with symbols, because otherwise the interpreter tries to place values in a more specialized type Variable.
The normal way of entering polynomials uses this fact.
Another convenient way to create symbols is to convert a string. This is useful when the name is to be constructed by a program.
Sometimes it is necessary to generate new unique symbols, for example, to name constants of integration. The expression new() generates a symbol starting with %.
Successive calls to newnewSymbol produce different symbols.
The expression new("s") produces a symbol starting with %s.
A symbol can be adorned in various ways. The most basic thing is applying a symbol to a list of subscripts.
Somewhat less pretty is to attach subscripts, superscripts or arguments.
It is possible to test whether a symbol has scripts using the scripted?scripted?Symbol test.
If a symbol is not scripted, then it may be converted to a string.
The basic parts can always be extracted using the namenameSymbol and scriptsscriptsSymbol operations.
The most general form is obtained using the scriptscriptSymbol operation. This operation takes an argument which is a list containing, in this order, lists of subscripts, superscripts, presuperscripts, presubscripts and arguments to a symbol.
If trailing lists of scripts are omitted, they are assumed to be empty.
The Table constructor provides a general structure for associative storage. This type provides hash tables in which data objects can be saved according to keys of any type. For a given table, specific types must be chosen for the keys and entries.
In this example the keys to the table are polynomials with integer coefficients. The entries in the table are strings.
To save an entry in the table, the seteltseteltTable operation is used. This can be called directly, giving the table a key and an entry.
Alternatively, you can use assignment syntax.
Entries are retrieved from the table by calling the elteltTable operation.
This operation is called when a table is ``applied'' to a key using this or the following syntax.
Parentheses are used only for grouping. They are needed if the key is an infixed expression.
Note that the elteltTable operation is used only when the key is known to be in the table---otherwise an error is generated.
You can get a list of all the keys to a table using the keyskeysTable operation.
If you wish to test whether a key is in a table, the searchsearchTable operation is used. This operation returns either an entry or "failed".
The return type is a union so the success of the search can be tested using case.
The removeremoveTable operation is used to delete values from a table.
If an entry exists under the key, then it is returned. Otherwise removeremoveTable returns "failed".
The number of key-entry pairs can be found using the # #Table operation.
Just as keyskeysTable returns a list of keys to the table, a list of all the entries can be obtained using the membersmembersTable operation.
A number of useful operations take functions and map them on to the table to compute the result. Here we count the entries which have ``Hard'' as a prefix.
Other table types are provided to support various needs. \indent
The domain TextFile allows Axiom to read and write character data and exchange text with other programs. This type behaves in Axiom much like a File of strings, with additional operations to cause new lines. We give an example of how to produce an upper case copy of a file.
This is the file from which we read the text.
This is the file to which we write the text.
Entire lines are handled using the readLinereadLineTextFile and writeLinewriteLineTextFile operations.
Use the endOfFile?endOfFile?TextFile operation to check if you have reached the end of the file.
The file f1 is exhausted and should be closed.
It is sometimes useful to write lines a bit at a time. The writewriteTextFile operation allows this.
This ends the line. This is done in a machine-dependent manner.
Finally, clean up.
For more information on related topics, see FileXmpPage , KeyedAccessFileXmpPage , and LibraryXmpPage .
The TwoDimensionalArray domain is used for storing data in a two dimensional data structure indexed by row and by column. Such an array is a homogeneous data structure in that all the entries of the array must belong to the same Axiom domain (although see ugTypesAnyNonePage in Section ugTypesAnyNoneNumber ). Each array has a fixed number of rows and columns specified by the user and arrays are not extensible. In Axiom, the indexing of two-dimensional arrays is one-based. This means that both the ``first'' row of an array and the ``first'' column of an array are given the index 1. Thus, the entry in the upper left corner of an array is in position (1,1).
The operation newnewTwoDimensionalArray creates an array with a specified number of rows and columns and fills the components of that array with a specified entry. The arguments of this operation specify the number of rows, the number of columns, and the entry.
This creates a five-by-four array of integers, all of whose entries are zero.
The entries of this array can be set to other integers using the operation seteltseteltTwoDimensionalArray.
Issue this to set the element in the upper left corner of this array to 17.
Now the first element of the array is 17.
Likewise, elements of an array are extracted using the operation elteltTwoDimensionalArray.
Another way to use these two operations is as follows. This sets the element in position (3,2) of the array to 15.
This extracts the element in position (3,2) of the array.
The operations elteltTwoDimensionalArray and seteltseteltTwoDimensionalArray come equipped with an error check which verifies that the indices are in the proper ranges. For example, the above array has five rows and four columns, so if you ask for the entry in position (6,2) with arr(6,2) Axiom displays an error message. If there is no need for an error check, you can call the operations qeltqeltTwoDimensionalArray and qseteltqseteltTwoDimensionalArray which provide the same functionality but without the error check. Typically, these operations are called in well-tested programs.
The operations rowrowTwoDimensionalArray and columncolumnTwoDimensionalArray extract rows and columns, respectively, and return objects of OneDimensionalArray with the same underlying element type.
You can determine the dimensions of an array by calling the operations nrowsnrowsTwoDimensionalArray and ncolsncolsTwoDimensionalArray, which return the number of rows and columns, respectively.
To apply an operation to every element of an array, use mapmapTwoDimensionalArray. This creates a new array. This expression negates every element.
This creates an array where all the elements are doubled.
To change the array destructively, use mapmapTwoDimensionalArray instead of mapmapTwoDimensionalArray. If you need to make a copy of any array, use copycopyTwoDimensionalArray.
Use member?member?TwoDimensionalArray to see if a given element is in an array.
To see how many times an element appears in an array, use countcountTwoDimensionalArray.
For more information about the operations available for TwoDimensionalArray, issue )show TwoDimensionalArray. For information on related topics, see MatrixXmpPage and OneDimensionalArrayXmpPage .