\documentclass{book} %\usepackage{axiom} \usepackage{graphicx} % struggle with latex figure-floating behavior \renewcommand\floatpagefraction{.9} \renewcommand\topfraction{.9} \renewcommand\bottomfraction{.9} \renewcommand\textfraction{.1} \setcounter{totalnumber}{50} \setcounter{topnumber}{50} \setcounter{bottomnumber}{50} % spadcommands are the actual text that you type at the axiom prompt \newcommand{\spadcommand}[1]% {\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm } % spadgraph are the actual text that you type at the axiom prompt for draw \newcommand{\spadgraph}[1]% {\begin{flushleft}{\tt #1}\end{flushleft}\vskip .1cm } % returnType is the type signature returned by the axiom interpreter \newcommand{\returnType}[1]% {\begin{flushright}{\tt #1}\end{flushright}\vskip .1cm} % spadsig gives the standard -> notation for signatures \newcommand{\spadsig}[2]{{\sf #1 $\rightarrow$ #2}} % The book begins with some introductory material that is not really % listed as a chapter. This creates a header similar to \chapter. \newcommand{\pseudoChapter}[1]% {\vskip .5in \noindent {\Large{\bf #1}}\vskip .5in} % The book begins with some introductory material that is not really % listed as a section. This creates a header similar to \section. \newcommand{\pseudoSection}[1]% {\vskip .25in \noindent {\large{\bf #1}}\vskip .25in} % spadofFrom records the operation in the index and the domain in the index \newcommand{\spadopFrom}[2]{\index{library!operations!#1 @\begingroup \string\tt{} #1 \endgroup}\index{#2}``{\tt #1}''} % spadfunFrom records the function name and domain in the index \newcommand{\spadfunFrom}[2]{{\bf #1}\index{#1 @\begingroup \string\bf{} #1 \endgroup}\index{#2}} % special meanings for math characters \newcommand{\N}{\mbox{\bbold N}} \newcommand{\Natural}{\mbox{\bbold N}} \newcommand{\Z}{\mbox{\bbold Z}} \newcommand{\Integer}{\mbox{\bbold Z}} \newcommand{\Rational}{\mbox{\bbold Q}} \newcommand{\Q}{\mbox{\bbold Q}} \newcommand{\Complex}{\mbox{\bbold C}} \newcommand{\C}{{\mathcal C}} \newcommand{\Real}{\mbox{\bbold R}} \newcommand{\F}{{\mathcal F}} \newcommand{\R}{{\mathcal R}} % draw a box around a text block \newcommand\boxed[2]{% \begin{center} \begin{tabular}{|c|} \hline \begin{minipage}{#1} \normalsize {#2} \end{minipage}\\ \hline \end{tabular} \end{center}} \newcommand{\optArg}[1]{{{\tt [}{#1}{\tt ]}}} \newcommand{\argDef}[1]{{\tt ({#1})}} \newcommand{\funSyntax}[2]{{\bf #1}{\tt ({\small\it{#2}})}} \newcommand{\funArgs}[1]{{\tt ({\small\it {#1}})}\newline} \newcommand{\condata}[4]{{\bf #1} {\bf #2} {\bf #3} {\bf #4}} \def\glossaryTerm#1{{\bf #1}\index{#1}} \def\glossaryTermNoIndex#1{{\bf #1}} \def\glossarySyntaxTerm#1{{\tt #1}\index{#1}} \long\def\ourGloss#1#2{\par\pagebreak[3]{#1}\newline{#2}} \def\csch{\mathop{\rm csch}\nolimits} \def\erf{\mathop{\rm erf}\nolimits} \def\zag#1#2{ {{\hfill \left. {#1} \right|} \over {\left| {#2} \right. \hfill} } } % these bitmaps are used by HyperDoc \newdimen\commentWidth \commentWidth=11pc \newdimen\colGutterWidth \colGutterWidth=1pc \newdimen\baseLeftSkip \baseLeftSkip=\commentWidth \advance\baseLeftSkip by \colGutterWidth \newcommand\ExitBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/exit.ps}\end{picture}}} \newcommand\ReturnBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/home.ps}\end{picture}}} \newcommand\HelpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/help.ps}\end{picture}}} \newcommand\UpBitmap{{\setlength{\unitlength}{0.01in}\begin{picture}(50,16)(0,0)\special{psfile=ps/up.ps}\end{picture}}} \newcommand{\tpd}[5]{{\setlength{\unitlength}{0.01in}\begin{picture}(#1,#2)(#3,#4)\special{psfile=#5}\end{picture}}} \begin{document} \begin{titlepage} \center{\includegraphics{ps/axiomFront.ps}} \vskip 0.1in \includegraphics{ps/bluebayou.ps}\\ \vskip 0.1in {\Huge{The 30 Year Horizon}} \vskip 0.1in $$ \begin{array}{lll} Manuel\ Bronstein & William\ Burge & Timothy\ Daly \\ James\ Davenport & Michael\ Dewar & Martin\ Dunstan \\ Albrecht\ Fortenbacher & Patrizia\ Gianni & Johannes\ Grabmeier \\ Jocelyn\ Guidry & Richard\ Jenks & Larry\ Lambe \\ Michael\ Monagan & Scott\ Morrison & William\ Sit \\ Jonathan\ Steinbach & Robert\ Sutor & Barry\ Trager \\ Stephen\ Watt & Jim\ Wen & Clifton\ Williamson \end{array} $$ \center{\large{VOLUME 3: REFERENCE}} \end{titlepage} \pagenumbering{roman} \begin{verbatim} The Blue Bayou image Copyright (c) 2004 Jocelyn Guidry Portions Copyright (c) 2004 Martin Dunstan Portions Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. All rights reserved. This book and the Axiom software is licensed as follows: 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. \end{verbatim} \tableofcontents \vfill \eject \setlength{\parindent}{0em} \setlength{\parskip}{1ex} {\Large{\bf New Foreword}} \vskip .25in On October 1, 2001 Axiom was withdrawn from the market and ended life as a commercial product. On September 3, 2002 Axiom was released under the Modified BSD license, including this document. On August 27, 2003 Axiom was released as free and open source software available for download from the Free Software Foundation's website, Savannah. Work on Axiom has had the generous support of the Center for Algorithms and Interactive Scientific Computation (CAISS) at City College of New York. Special thanks go to Dr. Gilbert Baumslag for his support of the long term goal. The online version of this documentation is roughly 1000 pages. In order to make printed versions we've broken it up into three volumes. The first volume is tutorial in nature. The second volume is for programmers. The third volume is reference material. We've also added a fourth volume for developers. All of these changes represent an experiment in print-on-demand delivery of documentation. Time will tell whether the experiment succeeded. Axiom has been in existence for over thirty years. It is estimated to contain about three hundred man-years of research and has, as of September 3, 2003, 143 people listed in the credits. All of these people have contributed directly or indirectly to making Axiom available. Axiom is being passed to the next generation. I'm looking forward to future milestones. With that in mind I've introduced the theme of the ``30 year horizon''. We must invent the tools that support the Computational Mathematician working 30 years from now. How will research be done when every bit of mathematical knowledge is online and instantly available? What happens when we scale Axiom by a factor of 100, giving us 1.1 million domains? How can we integrate theory with code? How will we integrate theorems and proofs of the mathematics with space-time complexity proofs and running code? What visualization tools are needed? How do we support the conceptual structures and semantics of mathematics in effective ways? How do we support results from the sciences? How do we teach the next generation to be effective Computational Mathematicians? The ``30 year horizon'' is much nearer than it appears. \vskip .25in %\noindent Tim Daly\\ CAISS, City College of New York\\ November 10, 2003 ((iHy)) \vfill \eject \pagenumbering{arabic} %\setcounter{chapter}{9} % Chapter 10 \chapter{Some Examples of Domains and Packages} In this chapter we show examples of many of the most commonly used AXIOM domains and packages. The sections are organized by constructor names. \section{AssociationList} \label{AssociationListXmpPage} The {\tt AssociationList} constructor provides a general structure for associative storage. This type provides association lists in which data objects can be saved according to keys of any type. For a given association list, specific types must be chosen for the keys and entries. You can think of the representation of an association list as a list of records with key and entry fields. Association lists are a form of table and so most of the operations available for {\tt Table} are also available for {\tt AssociationList}. They can also be viewed as lists and can be manipulated accordingly. This is a {\tt Record} type with age and gender fields. \spadcommand{Data := Record(monthsOld : Integer, gender : String)} $$ \mbox{\rm Record(monthsOld: Integer,gender: String)} $$ \returnType{Type: Domain} In this expression, {\tt al} is declared to be an association list whose keys are strings and whose entries are the above records. \spadcommand{al : AssociationList(String,Data)} \returnType{Type: Void} The \spadfunFrom{table}{AssociationList} operation is used to create an empty association list. \spadcommand{al := table()} $$ table() $$ \returnType{Type: AssociationList(String,Record(monthsOld: Integer,gender: String))} You can use assignment syntax to add things to the association list. \spadcommand{al."bob" := [407,"male"]\$Data} $$ \left[ {monthsOld={407}}, {gender= \mbox{\tt "male"} } \right] $$ \returnType{Type: Record(monthsOld: Integer,gender: String)} \spadcommand{al."judith" := [366,"female"]\$Data} $$ \left[ {monthsOld={366}}, {gender= \mbox{\tt "female"} } \right] $$ \returnType{Type: Record(monthsOld: Integer,gender: String)} \spadcommand{al."katie" := [24,"female"]\$Data} $$ \left[ {monthsOld={24}}, {gender= \mbox{\tt "female"} } \right] $$ \returnType{Type: Record(monthsOld: Integer,gender: String)} Perhaps we should have included a species field. \spadcommand{al."smokie" := [200,"female"]\$Data} $$ \left[ {monthsOld={200}}, {gender= \mbox{\tt "female"} } \right] $$ \returnType{Type: Record(monthsOld: Integer,gender: String)} Now look at what is in the association list. Note that the last-added (key, entry) pair is at the beginning of the list. \spadcommand{al} $$ \begin{array}{@{}l} table \left( { \mbox{\tt "smokie"} = {\left[ {monthsOld={200}}, {gender= \mbox{\tt "female"} } \right]}}, \right. \\ \\ \displaystyle \ \ \ \ \ \ \ \ { \mbox{\tt "katie"} = {\left[ {monthsOld={24}}, {gender= \mbox{\tt "female"} } \right]}}, \\ \\ \displaystyle \ \ \ \ \ \ \ \ { \mbox{\tt "judith"} = {\left[ {monthsOld={366}}, {gender= \mbox{\tt "female"} } \right]}}, \\ \\ \displaystyle \left. \ \ \ \ \ \ \ \ { \mbox{\tt "bob"} = {\left[ {monthsOld={407}}, {gender= \mbox{\tt "male"} } \right]}} \right) \end{array} $$ \returnType{Type: AssociationList(String,Record(monthsOld: Integer,gender: String))} You can reset the entry for an existing key. \spadcommand{al."katie" := [23,"female"]\$Data} $$ \left[ {monthsOld={23}}, {gender= \mbox{\tt "female"} } \right] $$ \returnType{Type: Record(monthsOld: Integer,gender: String)} Use \spadfunFrom{delete}{AssociationList} to destructively remove an element of the association list. Use \spadfunFrom{delete}{AssociationList} to return a copy of the association list with the element deleted. The second argument is the index of the element to delete. \spadcommand{delete!(al,1)} $$ \begin{array}{@{}l} table \left( { \mbox{\tt "katie"} = {\left[ {monthsOld={23}}, {gender= \mbox{\tt "female"} } \right]}}, \right. \\ \\ \displaystyle \ \ \ \ \ \ \ \ { \mbox{\tt "judith"} = {\left[ {monthsOld={366}}, {gender= \mbox{\tt "female"} } \right]}}, \\ \\ \displaystyle \left. \ \ \ \ \ \ \ \ { \mbox{\tt "bob"} = {\left[ {monthsOld={407}}, {gender= \mbox{\tt "male"} } \right]}} \right) \end{array} $$ \returnType{Type: AssociationList(String,Record(monthsOld: Integer,gender: String))} For more information about tables, see \ref{TableXmpPage} on page~\pageref{TableXmpPage}. For more information about lists, see \ref{ListXmpPage} on page~\pageref{ListXmpPage}. \section{BalancedBinaryTree} \label{BalancedBinaryTreeXmpPage} {\tt BalancedBinaryTrees(S)} is the domain of balanced binary trees with elements of type {\tt S} at the nodes. A binary tree is either {\tt empty} or else consists of a {\tt node} having a {\tt value} and two branches, each branch a binary tree. A balanced binary tree is one that is balanced with respect its leaves. One with $2^k$ leaves is perfectly ``balanced'': the tree has minimum depth, and the {\tt left} and {\tt right} branch of every interior node is identical in shape. Balanced binary trees are useful in algebraic computation for so-called ``divide-and-conquer'' algorithms. Conceptually, the data for a problem is initially placed at the root of the tree. The original data is then split into two subproblems, one for each subtree. And so on. Eventually, the problem is solved at the leaves of the tree. A solution to the original problem is obtained by some mechanism that can reassemble the pieces. In fact, an implementation of the Chinese Remainder Algorithm using balanced binary trees was first proposed by David Y. Y. Yun at the IBM T. J. Watson Research Center in Yorktown Heights, New York, in 1978. It served as the prototype for polymorphic algorithms in Axiom. In what follows, rather than perform a series of computations with a single expression, the expression is reduced modulo a number of integer primes, a computation is done with modular arithmetic for each prime, and the Chinese Remainder Algorithm is used to obtain the answer to the original problem. We illustrate this principle with the computation of $12^2 = 144$. A list of moduli. \spadcommand{lm := [3,5,7,11]} $$ \left[ 3, 5, 7, {11} \right] $$ \returnType{Type: List PositiveInteger} The expression {\tt modTree(n, lm)} creates a balanced binary tree with leaf values {\tt n mod m} for each modulus {\tt m} in {\tt lm}. \spadcommand{modTree(12,lm)} $$ \left[ 0, 2, 5, 1 \right] $$ \returnType{Type: List Integer} Operation {\tt modTree} does this using operations on balanced binary trees. We trace its steps. Create a balanced binary tree {\tt t} of zeros with four leaves. \spadcommand{t := balancedBinaryTree(\#lm, 0)} $$ \left[ {\left[ 0, 0, 0 \right]}, 0, {\left[ 0, 0, 0\right]} \right] $$ \returnType{Type: BalancedBinaryTree NonNegativeInteger} The leaves of the tree are set to the individual moduli. \spadcommand{setleaves!(t,lm)} $$ \left[ {\left[ 3, 0, 5\right]}, 0, {\left[ 7, 0, {11} \right]} \right] $$ \returnType{Type: BalancedBinaryTree NonNegativeInteger} Use {\tt mapUp!} to do a bottom-up traversal of {\tt t}, setting each interior node to the product of the values at the nodes of its children. \spadcommand{mapUp!(t,\_*)} $$ 1155 $$ \returnType{Type: PositiveInteger} The value at the node of every subtree is the product of the moduli of the leaves of the subtree. \spadcommand{t} $$ \left[ {\left[ 3, {15}, 5\right]}, {1155}, {\left[ 7, {77}, {11} \right]} \right] $$ \returnType{Type: BalancedBinaryTree NonNegativeInteger} Operation {\tt mapDown!}{\tt (t,a,fn)} replaces the value {\tt v} at each node of {\tt t} by {\tt fn(a,v)}. \spadcommand{mapDown!(t,12,\_rem)} $$ \left[ {\left[ 0, {12}, 2\right]}, {12}, {\left[ 5, {12}, 1 \right]} \right] $$ \returnType{Type: BalancedBinaryTree NonNegativeInteger} The operation {\tt leaves} returns the leaves of the resulting tree. In this case, it returns the list of {\tt 12 mod m} for each modulus {\tt m}. \spadcommand{leaves \%} $$ \left[ 0, 2, 5, 1 \right] $$ \returnType{Type: List NonNegativeInteger} Compute the square of the images of {\tt 12} modulo each {\tt m}. \spadcommand{squares := [x**2 rem m for x in \% for m in lm]} $$ \left[ 0, 4, 4, 1 \right] $$ \returnType{Type: List NonNegativeInteger} Call the Chinese Remainder Algorithm to get the answer for $12^2$. \spadcommand{chineseRemainder(\%,lm)} $$ 144 $$ \returnType{Type: PositiveInteger} \section{BasicOperator} \label{BasicOperatorXmpPage} A basic operator is an object that can be symbolically applied to a list of arguments from a set, the result being a kernel over that set or an expression. In addition to this section, please see \ref{ExpressionXmpPage} on page~\pageref{ExpressionXmpPage} and \ref{KernelXmpPage} on page~\pageref{KernelXmpPage} for additional information and examples. You create an object of type {\tt BasicOperator} by using the \spadfunFrom{operator}{BasicOperator} operation. This first form of this operation has one argument and it must be a symbol. The symbol should be quoted in case the name has been used as an identifier to which a value has been assigned. A frequent application of {\tt BasicOperator} is the creation of an operator to represent the unknown function when solving a differential equation. Let {\tt y} be the unknown function in terms of {\tt x}. \spadcommand{y := operator 'y} $$ y $$ \returnType{Type: BasicOperator} This is how you enter the equation {\tt y'' + y' + y = 0}. \spadcommand{deq := D(y x, x, 2) + D(y x, x) + y x = 0} $$ {{{y \sb {{\ }} \sp {,,}} \left({x} \right)}+ {{y\sb {{\ }} \sp {,}} \left({x} \right)}+ {y\left({x} \right)}}=0 $$ \returnType{Type: Equation Expression Integer} To solve the above equation, enter this. \spadcommand{solve(deq, y, x)} $$ \left[ {particular=0}, {basis={\left[ {{\cos \left({{{x \ {\sqrt {3}}} \over 2}} \right)} \ {e \sp {\left( -{x \over 2} \right)}}}, {{e \sp {\left( -{x \over 2} \right)}} \ {\sin \left({{{x \ {\sqrt {3}}} \over 2}} \right)}} \right]}} \right] $$ \returnType{Type: Union(Record(particular: Expression Integer, basis: List Expression Integer),...)} See \ref{ugProblemDEQPage} on page~\pageref{ugProblemDEQPage} in Section \ref{ugProblemDEQNumber} on page~\pageref{ugProblemDEQNumber} for this kind of use of {\tt BasicOperator}. Use the single argument form of \spadfunFrom{operator}{BasicOperator} (as above) when you intend to use the operator to create functional expressions with an arbitrary number of arguments {\it Nary} means an arbitrary number of arguments can be used in the functional expressions. \spadcommand{nary? y} $$ {\tt true} $$ \returnType{Type: Boolean} \spadcommand{unary? y} $$ {\tt false} $$ \returnType{Type: Boolean} Use the two-argument form when you want to restrict the number of arguments in the functional expressions created with the operator. This operator can only be used to create functional expressions with one argument. \spadcommand{opOne := operator('opOne, 1)} $$ opOne $$ \returnType{Type: BasicOperator} \spadcommand{nary? opOne} $$ {\tt false} $$ \returnType{Type: Boolean} \spadcommand{unary? opOne} $$ {\tt true} $$ \returnType{Type: Boolean} Use \spadfunFrom{arity}{BasicOperator} to learn the number of arguments that can be used. It returns {\tt "false"} if the operator is nary. \spadcommand{arity opOne} $$ 1 $$ \returnType{Type: Union(NonNegativeInteger,...)} Use \spadfunFrom{name}{BasicOperator} to learn the name of an operator. \spadcommand{name opOne} $$ opOne $$ \returnType{Type: Symbol} Use \spadfunFrom{is?}{BasicOperator} to learn if an operator has a particular name. \spadcommand{is?(opOne, 'z2)} $$ {\tt false} $$ \returnType{Type: Boolean} You can also use a string as the name to be tested against. \spadcommand{is?(opOne, "opOne")} $$ {\tt true} $$ \returnType{Type: Boolean} You can attached named properties to an operator. These are rarely used at the top-level of the Axiom interactive environment but are used with Axiom library source code. By default, an operator has no properties. \spadcommand{properties y} $$ table() $$ \returnType{Type: AssociationList(String,None)} The interface for setting and getting properties is somewhat awkward because the property values are stored as values of type {\tt None}. Attach a property by using \spadfunFrom{setProperty}{BasicOperator}. \spadcommand{setProperty(y, "use", "unknown function" :: None )} $$ y $$ \returnType{Type: BasicOperator} \spadcommand{properties y} $$ table \left( {{ \mbox{\tt "use"} =NONE}} \right) $$ \returnType{Type: AssociationList(String,None)} We {\it know} the property value has type {\tt String}. \spadcommand{property(y, "use") :: None pretend String} $$ \mbox{\tt "unknown function"} $$ \returnType{Type: String} Use \spadfunFrom{deleteProperty!}{BasicOperator} to destructively remove a property. \spadcommand{deleteProperty!(y, "use")} $$ y $$ \returnType{Type: BasicOperator} \spadcommand{properties y} $$ table() $$ \returnType{Type: AssociationList(String,None)} \section{BinaryExpansion} \label{BinaryExpansionXmpPage} All rational numbers have repeating binary expansions. Operations to access the individual bits of a binary expansion can be obtained by converting the value to {\tt RadixExpansion(2)}. More examples of expansions are available in \ref{DecimalExpansionXmpPage} on page~\pageref{DecimalExpansionXmpPage}, \ref{HexadecimalExpansionXmpPage} on page~\pageref{HexadecimalExpansionXmpPage}, and \ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}. The expansion (of type {\tt BinaryExpansion}) of a rational number is returned by the \spadfunFrom{binary}{BinaryExpansion} operation. \spadcommand{r := binary(22/7)} $$ {11}.{\overline {001}} $$ \returnType{Type: BinaryExpansion} Arithmetic is exact. \spadcommand{r + binary(6/7)} $$ 100 $$ \returnType{Type: BinaryExpansion} The period of the expansion can be short or long \ldots \spadcommand{[binary(1/i) for i in 102..106] } $$ \begin{array}{@{}l} \left[ {0.0{\overline {00000101}}}, {0.{\overline {000000100111110001000101100101111001110010010101001}}}, \right. \\ \\ \displaystyle {0.{000}{\overline {000100111011}}}, {0.{\overline {000000100111}}}, \\ \\ \displaystyle \left. {0.0{\overline {0000010011010100100001110011111011001010110111100011}}} \right] \end{array} $$ \returnType{Type: List BinaryExpansion} or very long. \spadcommand{binary(1/1007) } $$ \begin{array}{@{}l} 0. \overline {000000000100000100010100100101111000001111110000101111110010110001111101} \\ \displaystyle \ \ \overline {000100111001001100110001100100101010111101101001100000000110000110011110} \\ \displaystyle \ \ \overline {111000110100010111101001000111101100001010111011100111010101110011001010} \\ \displaystyle \ \ \overline {010111000000011100011110010000001001001001101110010101001110100011011101} \\ \displaystyle \ \ \overline {101011100010010000011001011011000000101100101111100010100000101010101101} \\ \displaystyle \ \ \overline {011000001101101110100101011111110101110101001100100001010011011000100110} \\ \displaystyle \ \ \overline {001000100001000011000111010011110001} \end{array} $$ \returnType{Type: BinaryExpansion} These numbers are bona fide algebraic objects. \spadcommand{p := binary(1/4)*x**2 + binary(2/3)*x + binary(4/9)} $$ {{0.{01}} \ {x \sp 2}}+{{0.{\overline {10}}} \ x}+{0.{\overline {011100}}} $$ \returnType{Type: Polynomial BinaryExpansion} \spadcommand{q := D(p, x)} $$ {{0.1} \ x}+{0.{\overline {10}}} $$ \returnType{Type: Polynomial BinaryExpansion} \spadcommand{g := gcd(p, q)} $$ x+{1.{\overline {01}}} $$ \returnType{Type: Polynomial BinaryExpansion} \section{BinarySearchTree} \label{BinarySearchTreeXmpPage} {\tt BinarySearchTree(R)} is the domain of binary trees with elements of type {\tt R}, ordered across the nodes of the tree. A non-empty binary search tree has a value of type {\tt R}, and {\tt right} and {\tt left} binary search subtrees. If a subtree is empty, it is displayed as a period (``.''). Define a list of values to be placed across the tree. The resulting tree has {\tt 8} at the root; all other elements are in the left subtree. \spadcommand{lv := [8,3,5,4,6,2,1,5,7]} $$ \left[ 8, 3, 5, 4, 6, 2, 1, 5, 7 \right] $$ \returnType{Type: List PositiveInteger} A convenient way to create a binary search tree is to apply the operation {\tt binarySearchTree} to a list of elements. \spadcommand{t := binarySearchTree lv} $$ \left[ {\left[ {\left[ 1, 2, . \right]}, 3, {\left[ 4, 5, {\left[ 5, 6, 7 \right]}\right]} \right]}, 8, . \right] $$ \returnType{Type: BinarySearchTree PositiveInteger} Another approach is to first create an empty binary search tree of integers. \spadcommand{emptybst := empty()\$BSTREE(INT)} $$ [\ ] $$ \returnType{Type: BinarySearchTree Integer} Insert the value {\tt 8}. This establishes {\tt 8} as the root of the binary search tree. Values inserted later that are less than {\tt 8} get stored in the {\tt left} subtree, others in the {\tt right} subtree. \spadcommand{t1 := insert!(8,emptybst)} $$ 8 $$ \returnType{Type: BinarySearchTree Integer} Insert the value {\tt 3}. This number becomes the root of the {\tt left} subtree of {\tt t1}. For optimal retrieval, it is thus important to insert the middle elements first. \spadcommand{insert!(3,t1)} $$ \left[3, 8, . \right] $$ \returnType{Type: BinarySearchTree Integer} We go back to the original tree {\tt t}. The leaves of the binary search tree are those which have empty {\tt left} and {\tt right} subtrees. \spadcommand{leaves t} $$ \left[ 1, 4, 5, 7 \right] $$ \returnType{Type: List PositiveInteger} The operation {\tt split}{\tt (k,t)} returns a \index{record} containing the two subtrees: one with all elements ``less'' than {\tt k}, another with elements ``greater'' than {\tt k}. \spadcommand{split(3,t)} $$ \left[ {less={\left[ 1, 2, . \right]}}, {greater={\left[ {\left[ ., 3, {\left[ 4, 5, {\left[ 5, 6, 7 \right]} \right]} \right]}, 8, . \right]}} \right] $$ \returnType{Type: Record(less: BinarySearchTree PositiveInteger,greater: BinarySearchTree PositiveInteger)} Define {\tt insertRoot} to insert new elements by creating a new node. \spadcommand{insertRoot: (INT,BSTREE INT) -> BSTREE INT} \returnType{Type: Void} The new node puts the inserted value between its ``less'' tree and ``greater'' tree. \begin{verbatim} insertRoot(x, t) == a := split(x, t) node(a.less, x, a.greater) \end{verbatim} Function {\tt buildFromRoot} builds a binary search tree from a list of elements {\tt ls} and the empty tree {\tt emptybst}. \spadcommand{buildFromRoot ls == reduce(insertRoot,ls,emptybst)} \returnType{Type: Void} Apply this to the reverse of the list {\tt lv}. \spadcommand{rt := buildFromRoot reverse lv} $$ \left[ {\left[ {\left[ 1, 2, . \right]}, 3, {\left[ 4, 5, {\left[ 5, 6, 7\right]}\right]} \right]}, 8, . \right] $$ \returnType{Type: BinarySearchTree Integer} Have Axiom check that these are equal. \spadcommand{(t = rt)@Boolean} $$ {\tt true} $$ \returnType{Type: Boolean} \section{CardinalNumber} \label{CardinalNumberXmpPage} The {\tt CardinalNumber} domain can be used for values indicating the cardinality of sets, both finite and infinite. For example, the \spadfunFrom{dimension}{VectorSpace} operation in the category {\tt VectorSpace} returns a cardinal number. The non-negative integers have a natural construction as cardinals \begin{verbatim} 0 = #{ }, 1 = {0}, 2 = {0, 1}, ..., n = {i | 0 <= i < n}. \end{verbatim} The fact that {\tt 0} acts as a zero for the multiplication of cardinals is equivalent to the axiom of choice. Cardinal numbers can be created by conversion from non-negative integers. \spadcommand{c0 := 0 :: CardinalNumber} $$ 0 $$ \returnType{Type: CardinalNumber} \spadcommand{c1 := 1 :: CardinalNumber} $$ 1 $$ \returnType{Type: CardinalNumber} \spadcommand{c2 := 2 :: CardinalNumber} $$ 2 $$ \returnType{Type: CardinalNumber} \spadcommand{c3 := 3 :: CardinalNumber} $$ 3 $$ \returnType{Type: CardinalNumber} They can also be obtained as the named cardinal {\tt Aleph(n)}. \spadcommand{A0 := Aleph 0} $$ Aleph \left( {0} \right) $$ \returnType{Type: CardinalNumber} \spadcommand{A1 := Aleph 1} $$ Aleph \left( {1} \right) $$ \returnType{Type: CardinalNumber} The \spadfunFrom{finite?}{CardinalNumber} operation tests whether a value is a finite cardinal, that is, a non-negative integer. \spadcommand{finite? c2} $$ {\tt true} $$ \returnType{Type: Boolean} \spadcommand{finite? A0} $$ {\tt false} $$ \returnType{Type: Boolean} Similarly, the \spadfunFrom{countable?}{CardinalNumber} operation determines whether a value is a countable cardinal, that is, finite or {\tt Aleph(0)}. \spadcommand{countable? c2} $$ {\tt true} $$ \returnType{Type: Boolean} \spadcommand{countable? A0} $$ {\tt true} $$ \returnType{Type: Boolean} \spadcommand{countable? A1} $$ {\tt false} $$ \returnType{Type: Boolean} Arithmetic operations are defined on cardinal numbers as follows: If {\tt x = \#X} and {\tt y = \#Y} then \noindent $ \begin{array}{lr} {\tt x+y = \#(X+Y)} & cardinality of the disjoint union\\ {\tt x-y = \#(X-Y)} & cardinality of the relative complement \\ {\tt x*y = \#(X*Y)} & cardinality of the Cartesian product \\ {\tt x**y = \#(X**Y)} & cardinality of the set of maps from {\tt Y} to {\tt X} \\ \end{array} $ Here are some arithmetic examples. \spadcommand{[c2 + c2, c2 + A1]} $$ \left[4, {Aleph \left({1} \right)}\right] $$ \returnType{Type: List CardinalNumber} \spadcommand{[c0*c2, c1*c2, c2*c2, c0*A1, c1*A1, c2*A1, A0*A1]} $$ \left[ 0, 2, 4, 0, {Aleph \left({1} \right)}, {Aleph \left({1} \right)}, {Aleph \left({1} \right)} \right] $$ \returnType{Type: List CardinalNumber} \spadcommand{[c2**c0, c2**c1, c2**c2, A1**c0, A1**c1, A1**c2]} $$ \left[ 1, 2, 4, 1, {Aleph \left({1} \right)}, {Aleph \left({1} \right)} \right] $$ \returnType{Type: List CardinalNumber} Subtraction is a partial operation: it is not defined when subtracting a larger cardinal from a smaller one, nor when subtracting two equal infinite cardinals. \spadcommand{[c2-c1, c2-c2, c2-c3, A1-c2, A1-A0, A1-A1]} $$ \left[ 1, 0, \mbox{\tt "failed"} , {Aleph \left({1} \right)}, {Aleph \left({1} \right)}, \mbox{\tt "failed"} \right] $$ \returnType{Type: List Union(CardinalNumber,"failed")} The generalized continuum hypothesis asserts that \begin{verbatim} 2**Aleph i = Aleph(i+1) \end{verbatim} and is independent of the axioms of set theory.\footnote{Goedel, {\it The consistency of the continuum hypothesis,} Ann. Math. Studies, Princeton Univ. Press, 1940.} The {\tt CardinalNumber} domain provides an operation to assert whether the hypothesis is to be assumed. \spadcommand{generalizedContinuumHypothesisAssumed true} When the generalized continuum hypothesis is assumed, exponentiation to a transfinite power is allowed. \spadcommand{[c0**A0, c1**A0, c2**A0, A0**A0, A0**A1, A1**A0, A1**A1]} $$ \left[ 0, 1, {Aleph \left({1} \right)}, {Aleph \left({1} \right)}, {Aleph \left({2} \right)}, {Aleph \left({1} \right)}, {Aleph \left({2} \right)} \right] $$ \returnType{Type: List CardinalNumber} Three commonly encountered cardinal numbers are \noindent $ \begin{array}{lr} {\tt a = \#}{\bf Z} & countable infinity \\ {\tt c = \#}{\bf R} & the continuum \\ {\tt f = \#\{g| g: [0,1] -> {\bf R}\}} \\ \end{array} $ In this domain, these values are obtained under the generalized continuum hypothesis in this way. \spadcommand{a := Aleph 0} $$ Aleph \left({0} \right) $$ \returnType{Type: CardinalNumber} \spadcommand{c := 2**a} $$ Aleph \left({1} \right) $$ \returnType{Type: CardinalNumber} \spadcommand{f := 2**c} $$ Aleph \left({2} \right) $$ \returnType{Type: CardinalNumber} \section{CartesianTensor} \label{CartesianTensorXmpPage} {\tt CartesianTensor(i0,dim,R)} provides Cartesian tensors with components belonging to a commutative ring {\tt R}. Tensors can be described as a generalization of vectors and matrices. This gives a concise {\it tensor algebra} for multilinear objects supported by the {\tt CartesianTensor} domain. You can form the inner or outer product of any two tensors and you can add or subtract tensors with the same number of components. Additionally, various forms of traces and transpositions are useful. The {\tt CartesianTensor} constructor allows you to specify the minimum index for subscripting. In what follows we discuss in detail how to manipulate tensors. Here we construct the domain of Cartesian tensors of dimension 2 over the integers, with indices starting at 1. \spadcommand{CT := CARTEN(i0 := 1, 2, Integer)} $$ CartesianTensor(1,2,Integer) $$ \returnType{Type: Domain} \subsubsection{Forming tensors} Scalars can be converted to tensors of rank zero. \spadcommand{t0: CT := 8} $$ 8 $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{rank t0} $$ 0 $$ \returnType{Type: NonNegativeInteger} Vectors (mathematical direct products, rather than one dimensional array structures) can be converted to tensors of rank one. \spadcommand{v: DirectProduct(2, Integer) := directProduct [3,4]} $$ \left[ 3, 4 \right] $$ \returnType{Type: DirectProduct(2,Integer)} \spadcommand{Tv: CT := v} $$ \left[ 3, 4 \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} Matrices can be converted to tensors of rank two. \spadcommand{m: SquareMatrix(2, Integer) := matrix [ [1,2],[4,5] ]} $$ \left[ \begin{array}{cc} 1 & 2 \\ 4 & 5 \end{array} \right] $$ \returnType{Type: SquareMatrix(2,Integer)} \spadcommand{Tm: CT := m} $$ \left[ \begin{array}{cc} 1 & 2 \\ 4 & 5 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{n: SquareMatrix(2, Integer) := matrix [ [2,3],[0,1] ]} $$ \left[ \begin{array}{cc} 2 & 3 \\ 0 & 1 \end{array} \right] $$ \returnType{Type: SquareMatrix(2,Integer)} \spadcommand{Tn: CT := n} $$ \left[ \begin{array}{cc} 2 & 3 \\ 0 & 1 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} In general, a tensor of rank {\tt k} can be formed by making a list of rank {\tt k-1} tensors or, alternatively, a {\tt k}-deep nested list of lists. \spadcommand{t1: CT := [2, 3]} $$ \left[ 2, 3 \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{rank t1} $$ 1 $$ \returnType{Type: PositiveInteger} \spadcommand{t2: CT := [t1, t1]} $$ \left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{t3: CT := [t2, t2]} $$ \left[ {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]}, {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{tt: CT := [t3, t3]; tt := [tt, tt]} $$ \left[ {\left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} & {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} \\ {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} & {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} \end{array} \right]}, {\left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} & {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} \\ {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} & {\left[ \begin{array}{cc} 2 & 3 \\ 2 & 3 \end{array} \right]} \end{array} \right]} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{rank tt} $$ 5 $$ \returnType{Type: PositiveInteger} \subsubsection{Multiplication} Given two tensors of rank {\tt k1} and {\tt k2}, the outer \spadfunFrom{product}{CartesianTensor} forms a new tensor of rank {\tt k1+k2}. Here $$T_{mn}(i,j,k,l) = T_m(i,j) \ T_n(k,l)$$ \spadcommand{Tmn := product(Tm, Tn)} $$ \left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 3 \\ 0 & 1 \end{array} \right]} & {\left[ \begin{array}{cc} 4 & 6 \\ 0 & 2 \end{array} \right]} \\ {\left[ \begin{array}{cc} 8 & {12} \\ 0 & 4 \end{array} \right]} & {\left[ \begin{array}{cc} {10} & {15} \\ 0 & 5 \end{array} \right]} \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} The inner product (\spadfunFrom{contract}{CartesianTensor}) forms a tensor of rank {\tt k1+k2-2}. This product generalizes the vector dot product and matrix-vector product by summing component products along two indices. Here we sum along the second index of $T_m$ and the first index of $T_v$. Here $$T_{mv} = \sum_{j=1}^{\hbox{\tiny\rm dim}} T_m(i,j) \ T_v(j)$$ \spadcommand{Tmv := contract(Tm,2,Tv,1)} $$ \left[ {11}, {32} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} The multiplication operator \spadopFrom{*}{CartesianTensor} is scalar multiplication or an inner product depending on the ranks of the arguments. If either argument is rank zero it is treated as scalar multiplication. Otherwise, {\tt a*b} is the inner product summing the last index of {\tt a} with the first index of {\tt b}. \spadcommand{Tm*Tv} $$ \left[ {11}, {32} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} This definition is consistent with the inner product on matrices and vectors. \spadcommand{Tmv = m * v} $$ {\left[ {11}, {32} \right]}= {\left[{11}, {32} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \subsubsection{Selecting Components} For tensors of low rank (that is, four or less), components can be selected by applying the tensor to its indices. \spadcommand{t0()} $$ 8 $$ \returnType{Type: PositiveInteger} \spadcommand{t1(1+1)} $$ 3 $$ \returnType{Type: PositiveInteger} \spadcommand{t2(2,1)} $$ 2 $$ \returnType{Type: PositiveInteger} \spadcommand{t3(2,1,2)} $$ 3 $$ \returnType{Type: PositiveInteger} \spadcommand{Tmn(2,1,2,1)} $$ 0 $$ \returnType{Type: NonNegativeInteger} A general indexing mechanism is provided for a list of indices. \spadcommand{t0[]} $$ 8 $$ \returnType{Type: PositiveInteger} \spadcommand{t1[2]} $$ 3 $$ \returnType{Type: PositiveInteger} \spadcommand{t2[2,1]} $$ 2 $$ \returnType{Type: PositiveInteger} The general mechanism works for tensors of arbitrary rank, but is somewhat less efficient since the intermediate index list must be created. \spadcommand{t3[2,1,2]} $$ 3 $$ \returnType{Type: PositiveInteger} \spadcommand{Tmn[2,1,2,1]} $$ 0 $$ \returnType{Type: NonNegativeInteger} \subsubsection{Contraction} A ``contraction'' between two tensors is an inner product, as we have seen above. You can also contract a pair of indices of a single tensor. This corresponds to a ``trace'' in linear algebra. The expression {\tt contract(t,k1,k2)} forms a new tensor by summing the diagonal given by indices in position {\tt k1} and {\tt k2}. This is the tensor given by $$xT_{mn} = \sum_{k=1}^{\hbox{\tiny\rm dim}} T_{mn}(k,k,i,j)$$ \spadcommand{cTmn := contract(Tmn,1,2)} $$ \left[ \begin{array}{cc} {12} & {18} \\ 0 & 6 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} Since {\tt Tmn} is the outer product of matrix {\tt m} and matrix {\tt n}, the above is equivalent to this. \spadcommand{trace(m) * n} $$ \left[ \begin{array}{cc} {12} & {18} \\ 0 & 6 \end{array} \right] $$ \returnType{Type: SquareMatrix(2,Integer)} In this and the next few examples, we show all possible contractions of {\tt Tmn} and their matrix algebra equivalents. \spadcommand{contract(Tmn,1,2) = trace(m) * n} $$ {\left[ \begin{array}{cc} {12} & {18} \\ 0 & 6 \end{array} \right]}={\left[ \begin{array}{cc} {12} & {18} \\ 0 & 6 \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \spadcommand{contract(Tmn,1,3) = transpose(m) * n} $$ {\left[ \begin{array}{cc} 2 & 7 \\ 4 & {11} \end{array} \right]}={\left[ \begin{array}{cc} 2 & 7 \\ 4 & {11} \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \spadcommand{contract(Tmn,1,4) = transpose(m) * transpose(n)} $$ {\left[ \begin{array}{cc} {14} & 4 \\ {19} & 5 \end{array} \right]}={\left[ \begin{array}{cc} {14} & 4 \\ {19} & 5 \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \spadcommand{contract(Tmn,2,3) = m * n} $$ {\left[ \begin{array}{cc} 2 & 5 \\ 8 & {17} \end{array} \right]}={\left[ \begin{array}{cc} 2 & 5 \\ 8 & {17} \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \spadcommand{contract(Tmn,2,4) = m * transpose(n)} $$ {\left[ \begin{array}{cc} 8 & 2 \\ {23} & 5 \end{array} \right]}={\left[ \begin{array}{cc} 8 & 2 \\ {23} & 5 \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \spadcommand{contract(Tmn,3,4) = trace(n) * m} $$ {\left[ \begin{array}{cc} 3 & 6 \\ {12} & {15} \end{array} \right]}={\left[ \begin{array}{cc} 3 & 6 \\ {12} & {15} \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \subsubsection{Transpositions} You can exchange any desired pair of indices using the \spadfunFrom{transpose}{CartesianTensor} operation. Here the indices in positions one and three are exchanged, that is, $tT_{mn}(i,j,k,l) = T_{mn}(k,j,i,l).$ \spadcommand{tTmn := transpose(Tmn,1,3)} $$ \left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 3 \\ 8 & {12} \end{array} \right]} & {\left[ \begin{array}{cc} 4 & 6 \\ {10} & {15} \end{array} \right]} \\ {\left[ \begin{array}{cc} 0 & 1 \\ 0 & 4 \end{array} \right]} & {\left[ \begin{array}{cc} 0 & 2 \\ 0 & 5 \end{array} \right]} \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} If no indices are specified, the first and last index are exchanged. \spadcommand{transpose Tmn} $$ \left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 8 \\ 0 & 0 \end{array} \right]} & {\left[ \begin{array}{cc} 4 & {10} \\ 0 & 0 \end{array} \right]} \\ {\left[ \begin{array}{cc} 3 & {12} \\ 1 & 4 \end{array} \right]} & {\left[ \begin{array}{cc} 6 & {15} \\ 2 & 5 \end{array} \right]} \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} This is consistent with the matrix transpose. \spadcommand{transpose Tm = transpose m} $$ {\left[ \begin{array}{cc} 1 & 4 \\ 2 & 5 \end{array} \right]}={\left[ \begin{array}{cc} 1 & 4 \\ 2 & 5 \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} If a more complicated reordering of the indices is required, then the \spadfunFrom{reindex}{CartesianTensor} operation can be used. This operation allows the indices to be arbitrarily permuted. This defines $rT_{mn}(i,j,k,l) = \allowbreak T_{mn}(i,l,j,k).$ \spadcommand{rTmn := reindex(Tmn, [1,4,2,3])} $$ \left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 0 \\ 4 & 0 \end{array} \right]} & {\left[ \begin{array}{cc} 3 & 1 \\ 6 & 2 \end{array} \right]} \\ {\left[ \begin{array}{cc} 8 & 0 \\ {10} & 0 \end{array} \right]} & {\left[ \begin{array}{cc} {12} & 4 \\ {15} & 5 \end{array} \right]} \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \subsubsection{Arithmetic} Tensors of equal rank can be added or subtracted so arithmetic expressions can be used to produce new tensors. \spadcommand{tt := transpose(Tm)*Tn - Tn*transpose(Tm)} $$ \left[ \begin{array}{cc} -6 & -{16} \\ 2 & 6 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{Tv*(tt+Tn)} $$ \left[ -4, -{11} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \spadcommand{reindex(product(Tn,Tn),[4,3,2,1])+3*Tn*product(Tm,Tm)} $$ \left[ \begin{array}{cc} {\left[ \begin{array}{cc} {46} & {84} \\ {174} & {212} \end{array} \right]} & {\left[ \begin{array}{cc} {57} & {114} \\ {228} & {285} \end{array} \right]} \\ {\left[ \begin{array}{cc} {18} & {24} \\ {57} & {63} \end{array} \right]} & {\left[ \begin{array}{cc} {17} & {30} \\ {63} & {76} \end{array} \right]} \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} \subsubsection{Specific Tensors} Two specific tensors have properties which depend only on the dimension. The Kronecker delta satisfies \begin{verbatim} +- | 1 if i = j delta(i,j) = | | 0 if i ^= j +- \end{verbatim} \spadcommand{delta: CT := kroneckerDelta()} $$ \left[ \begin{array}{cc} 1 & 0 \\ 0 & 1 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} This can be used to reindex via contraction. \spadcommand{contract(Tmn, 2, delta, 1) = reindex(Tmn, [1,3,4,2])} $$ {\left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 4 \\ 3 & 6 \end{array} \right]} & {\left[ \begin{array}{cc} 0 & 0 \\ 1 & 2 \end{array} \right]} \\ {\left[ \begin{array}{cc} 8 & {10} \\ {12} & {15} \end{array} \right]} & {\left[ \begin{array}{cc} 0 & 0 \\ 4 & 5 \end{array} \right]} \end{array} \right]}={\left[ \begin{array}{cc} {\left[ \begin{array}{cc} 2 & 4 \\ 3 & 6 \end{array} \right]} & {\left[ \begin{array}{cc} 0 & 0 \\ 1 & 2 \end{array} \right]} \\ {\left[ \begin{array}{cc} 8 & {10} \\ {12} & {15} \end{array} \right]} & {\left[ \begin{array}{cc} 0 & 0 \\ 4 & 5 \end{array} \right]} \end{array} \right]} $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} The Levi Civita symbol determines the sign of a permutation of indices. \spadcommand{epsilon:CT := leviCivitaSymbol()} $$ \left[ \begin{array}{cc} 0 & 1 \\ -1 & 0 \end{array} \right] $$ \returnType{Type: CartesianTensor(1,2,Integer)} Here we have: \begin{verbatim} epsilon(i1,...,idim) = +1 if i1,...,idim is an even permutation of i0,...,i0+dim-1 = -1 if i1,...,idim is an odd permutation of i0,...,i0+dim-1 = 0 if i1,...,idim is not a permutation of i0,...,i0+dim-1 \end{verbatim} This property can be used to form determinants. \spadcommand{contract(epsilon*Tm*epsilon, 1,2) = 2 * determinant m} $$ -6=-6 $$ \returnType{Type: Equation CartesianTensor(1,2,Integer)} \subsubsection{Properties of the CartesianTensor domain} {\tt GradedModule(R,E)} denotes ``{\tt E}-graded {\tt R}-module'', that is, a collection of {\tt R}-modules indexed by an abelian monoid {\tt E.} An element {\tt g} of {\tt G[s]} for some specific {\tt s} in {\tt E} is said to be an element of {\tt G} with \spadfunFrom{degree}{GradedModule} {\tt s}. Sums are defined in each module {\tt G[s]} so two elements of {\tt G} can be added if they have the same degree. Morphisms can be defined and composed by degree to give the mathematical category of graded modules. {\tt GradedAlgebra(R,E)} denotes ``{\tt E}-graded {\tt R}-algebra.'' A graded algebra is a graded module together with a degree preserving {\tt R}-bilinear map, called the \spadfunFrom{product}{GradedAlgebra}. \begin{verbatim} degree(product(a,b)) = degree(a) + degree(b) product(r*a,b) = product(a,r*b) = r*product(a,b) product(a1+a2,b) = product(a1,b) + product(a2,b) product(a,b1+b2) = product(a,b1) + product(a,b2) product(a,product(b,c)) = product(product(a,b),c) \end{verbatim} The domain {\tt CartesianTensor(i0, dim, R)} belongs to the category {\tt GradedAlgebra(R, NonNegativeInteger)}. The non-negative integer \spadfunFrom{degree}{GradedAlgebra} is the tensor rank and the graded algebra \spadfunFrom{product}{GradedAlgebra} is the tensor outer product. The graded module addition captures the notion that only tensors of equal rank can be added. If {\tt V} is a vector space of dimension {\tt dim} over {\tt R}, then the tensor module {\tt T[k](V)} is defined as \begin{verbatim} T[0](V) = R T[k](V) = T[k-1](V) * V \end{verbatim} where {\tt *} denotes the {\tt R}-module tensor \spadfunFrom{product}{GradedAlgebra}. {\tt CartesianTensor(i0,dim,R)} is the graded algebra in which the degree {\tt k} module is {\tt T[k](V)}. \subsubsection{Tensor Calculus} It should be noted here that often tensors are used in the context of tensor-valued manifold maps. This leads to the notion of covariant and contravariant bases with tensor component functions transforming in specific ways under a change of coordinates on the manifold. This is no more directly supported by the {\tt CartesianTensor} domain than it is by the {\tt Vector} domain. However, it is possible to have the components implicitly represent component maps by choosing a polynomial or expression type for the components. In this case, it is up to the user to satisfy any constraints which arise on the basis of this interpretation. \section{Character} \label{CharacterXmpPage} The members of the domain {\tt Character} are values representing letters, numerals and other text elements. For more information on related topics, see \ref{CharacterClassXmpPage} on page~\pageref{CharacterClassXmpPage} and \ref{StringXmpPage} on page~\pageref{StringXmpPage}. Characters can be obtained using {\tt String} notation. \spadcommand{chars := [char "a", char "A", char "X", char "8", char "+"]} $$ \left[ a, A, X, 8, + \right] $$ \returnType{Type: List Character} Certain characters are available by name. This is the blank character. \spadcommand{space()} $$ \ $$ \returnType{Type: Character} This is the quote that is used in strings. \spadcommand{quote()} $$ \mbox{\tt "} $$ \returnType{Type: Character} This is the escape character that allows quotes and other characters within strings. \spadcommand{escape()} $$ \_ $$ \returnType{Type: Character} Characters are represented as integers in a machine-dependent way. The integer value can be obtained using the \spadfunFrom{ord}{Character} operation. It is always true that {\tt char(ord c) = c} and {\tt ord(char i) = i}, provided that {\tt i} is in the range {\tt 0..size()\$Character-1}. \spadcommand{[ord c for c in chars]} $$ \left[ {97}, {65}, {88}, {56}, {43} \right] $$ \returnType{Type: List Integer} The \spadfunFrom{lowerCase}{Character} operation converts an upper case letter to the corresponding lower case letter. If the argument is not an upper case letter, then it is returned unchanged. \spadcommand{[upperCase c for c in chars]} $$ \left[ A, A, X, 8, + \right] $$ \returnType{Type: List Character} Likewise, the \spadfunFrom{upperCase}{Character} operation converts lower case letters to upper case. \spadcommand{[lowerCase c for c in chars] } $$ \left[ a, a, x, 8, + \right] $$ \returnType{Type: List Character} A number of tests are available to determine whether characters belong to certain families. \spadcommand{[alphabetic? c for c in chars] } $$ \left[ {\tt true}, {\tt true}, {\tt true}, {\tt false}, {\tt false} \right] $$ \returnType{Type: List Boolean} \spadcommand{[upperCase? c for c in chars] } $$ \left[ {\tt false}, {\tt true}, {\tt true}, {\tt false}, {\tt false} \right] $$ \returnType{Type: List Boolean} \spadcommand{[lowerCase? c for c in chars] } $$ \left[ {\tt true}, {\tt false}, {\tt false}, {\tt false}, {\tt false} \right] $$ \returnType{Type: List Boolean} \spadcommand{[digit? c for c in chars] } $$ \left[ {\tt false}, {\tt false}, {\tt false}, {\tt true}, {\tt false} \right] $$ \returnType{Type: List Boolean} \spadcommand{[hexDigit? c for c in chars] } $$ \left[ {\tt true}, {\tt true}, {\tt false}, {\tt true}, {\tt false} \right] $$ \returnType{Type: List Boolean} \spadcommand{[alphanumeric? c for c in chars] } $$ \left[ {\tt true}, {\tt true}, {\tt true}, {\tt true}, {\tt false} \right] $$ \returnType{Type: List Boolean} \section{CharacterClass} \label{CharacterClassXmpPage} The {\tt CharacterClass} domain allows classes of characters to be defined and manipulated efficiently. Character classes can be created by giving either a string or a list of characters. \spadcommand{cl1 := charClass [char "a", char "e", char "i", char "o", char "u", char "y"] } $$ \mbox{\tt "aeiouy"} $$ \returnType{Type: CharacterClass} \spadcommand{cl2 := charClass "bcdfghjklmnpqrstvwxyz" } $$ \mbox{\tt "bcdfghjklmnpqrstvwxyz"} $$ \returnType{Type: CharacterClass} A number of character classes are predefined for convenience. \spadcommand{digit()} $$ \mbox{\tt "0123456789"} $$ \returnType{Type: CharacterClass} \spadcommand{hexDigit()} $$ \mbox{\tt "0123456789ABCDEFabcdef"} $$ \returnType{Type: CharacterClass} \spadcommand{upperCase()} $$ \mbox{\tt "ABCDEFGHIJKLMNOPQRSTUVWXYZ"} $$ \returnType{Type: CharacterClass} \spadcommand{lowerCase()} $$ \mbox{\tt "abcdefghijklmnopqrstuvwxyz"} $$ \returnType{Type: CharacterClass} \spadcommand{alphabetic()} $$ \mbox{\tt "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"} $$ \returnType{Type: CharacterClass} \spadcommand{alphanumeric()} $$ \mbox{\tt "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"} $$ \returnType{Type: CharacterClass} You can quickly test whether a character belongs to a class. \spadcommand{member?(char "a", cl1) } $$ {\tt true} $$ \returnType{Type: Boolean} \spadcommand{member?(char "a", cl2) } $$ {\tt false} $$ \returnType{Type: Boolean} Classes have the usual set operations because the {\tt CharacterClass} domain belongs to the category {\tt FiniteSetAggregate(Character)}. \spadcommand{intersect(cl1, cl2) } $$ \mbox{\tt "y"} $$ \returnType{Type: CharacterClass} \spadcommand{union(cl1,cl2) } $$ \mbox{\tt "abcdefghijklmnopqrstuvwxyz"} $$ \returnType{Type: CharacterClass} \spadcommand{difference(cl1,cl2) } $$ \mbox{\tt "aeiou"} $$ \returnType{Type: CharacterClass} \spadcommand{intersect(complement(cl1),cl2) } $$ \mbox{\tt "bcdfghjklmnpqrstvwxz"} $$ \returnType{Type: CharacterClass} You can modify character classes by adding or removing characters. \spadcommand{insert!(char "a", cl2) } $$ \mbox{\tt "abcdfghjklmnpqrstvwxyz"} $$ \returnType{Type: CharacterClass} \spadcommand{remove!(char "b", cl2) } $$ \mbox{\tt "acdfghjklmnpqrstvwxyz"} $$ \returnType{Type: CharacterClass} For more information on related topics, see \ref{CharacterXmpPage} on page~\pageref{CharacterXmpPage} and \ref{StringXmpPage} on page~\pageref{StringXmpPage}. \section{CliffordAlgebra} \label{CliffordAlgebraXmpPage} \noindent {\tt CliffordAlgebra(n,K,Q)} defines a vector space of dimension $2^n$ over the field $K$ with a given quadratic form {\tt Q}. If $\{e_1, \ldots, e_n\}$ is a basis for $K^n$ then \begin{verbatim} { 1, e(i) 1 <= i <= n, e(i1)*e(i2) 1 <= i1 < i2 <=n, ..., e(1)*e(2)*...*e(n) } \end{verbatim} is a basis for the Clifford algebra. The algebra is defined by the relations \begin{verbatim} e(i)*e(i) = Q(e(i)) e(i)*e(j) = -e(j)*e(i), i ^= j \end{verbatim} Examples of Clifford Algebras are gaussians (complex numbers), quaternions, exterior algebras and spin algebras. \subsection{The Complex Numbers as a Clifford Algebra} This is the field over which we will work, rational functions with integer coefficients. \spadcommand{K := Fraction Polynomial Integer } $$ \mbox{\rm Fraction Polynomial Integer} $$ \returnType{Type: Domain} We use this matrix for the quadratic form. \spadcommand{m := matrix [ [-1] ] } $$ \left[ \begin{array}{c} -1 \end{array} \right] $$ \returnType{Type: Matrix Integer} We get complex arithmetic by using this domain. \spadcommand{C := CliffordAlgebra(1, K, quadraticForm m) } $$ \mbox{\rm CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} $$ \returnType{Type: Domain} Here is {\tt i}, the usual square root of {\tt -1.} \spadcommand{i: C := e(1) } $$ e \sb {1} $$ \returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} Here are some examples of the arithmetic. \spadcommand{x := a + b * i } $$ a+{b \ {e \sb {1}}} $$ \returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} \spadcommand{y := c + d * i } $$ c+{d \ {e \sb {1}}} $$ \returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} See \ref{ComplexXmpPage} on page~\pageref{ComplexXmpPage} for examples of Axiom's constructor implementing complex numbers. \spadcommand{x * y } $$ -{b \ d}+{a \ c}+{{\left( {a \ d}+{b \ c} \right)} \ {e \sb {1}}} $$ \returnType{Type: CliffordAlgebra(1,Fraction Polynomial Integer,MATRIX)} \subsection{The Quaternion Numbers as a Clifford Algebra} This is the field over which we will work, rational functions with integer coefficients. \spadcommand{K := Fraction Polynomial Integer } $$ \mbox{\rm Fraction Polynomial Integer} $$ \returnType{Type: Domain} We use this matrix for the quadratic form. \spadcommand{m := matrix [ [-1,0],[0,-1] ] } $$ \left[ \begin{array}{cc} -1 & 0 \\ 0 & -1 \end{array} \right] $$ \returnType{Type: Matrix Integer} The resulting domain is the quaternions. \spadcommand{H := CliffordAlgebra(2, K, quadraticForm m) } $$ \mbox{\rm CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} $$ \returnType{Type: Domain} We use Hamilton's notation for {\tt i},{\tt j},{\tt k}. \spadcommand{i: H := e(1) } $$ e \sb {1} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{j: H := e(2) } $$ e \sb {2} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{k: H := i * j } $$ {e \sb {1}} \ {e \sb {2}} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{x := a + b * i + c * j + d * k } $$ a+{b \ {e \sb {1}}}+{c \ {e \sb {2}}}+{d \ {e \sb {1}} \ {e \sb {2}}} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{y := e + f * i + g * j + h * k } $$ e+{f \ {e \sb {1}}}+{g \ {e \sb {2}}}+{h \ {e \sb {1}} \ {e \sb {2}}} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{x + y } $$ e+a+{{\left( f+b \right)} \ {e \sb {1}}}+{{\left( g+c \right)} \ {e \sb {2}}}+{{\left( h+d \right)} \ {e \sb {1}} \ {e \sb {2}}} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \spadcommand{x * y } $$ \begin{array}{@{}l} -{d \ h} - {c \ g} - {b \ f}+ {a \ e}+ {{\left( {c \ h} -{d \ g}+{a \ f}+{b \ e} \right)}\ {e \sb {1}}}+ \\ \\ \displaystyle {{\left( -{b \ h}+{a \ g}+{d \ f}+{c \ e} \right)}\ {e \sb {2}}}+ {{\left( {a \ h}+{b \ g} -{c \ f}+{d \ e} \right)} \ {e \sb {1}} \ {e \sb {2}}} \end{array} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} See \ref{QuaternionXmpPage} on page~\pageref{QuaternionXmpPage} for examples of Axiom's constructor implementing quaternions. \spadcommand{y * x } $$ \begin{array}{@{}l} -{d \ h} -{c \ g} -{b \ f}+{a \ e}+ {{\left( -{c \ h}+{d \ g}+{a \ f}+{b \ e} \right)}\ {e \sb {1}}}+ \\ \\ \displaystyle {{\left( {b \ h}+{a \ g} -{d \ f}+{c \ e} \right)}\ {e \sb {2}}}+ {{\left( {a \ h} - {b \ g}+{c \ f}+{d \ e} \right)}\ {e \sb {1}} \ {e \sb {2}}} \end{array} $$ \returnType{Type: CliffordAlgebra(2,Fraction Polynomial Integer,MATRIX)} \subsection{The Exterior Algebra on a Three Space} This is the field over which we will work, rational functions with integer coefficients. \spadcommand{K := Fraction Polynomial Integer } $$ \mbox{\rm Fraction Polynomial Integer} $$ \returnType{Type: Domain} If we chose the three by three zero quadratic form, we obtain the exterior algebra on {\tt e(1),e(2),e(3)}. \spadcommand{Ext := CliffordAlgebra(3, K, quadraticForm 0) } $$ \mbox{\rm CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} $$ \returnType{Type: Domain} This is a three dimensional vector algebra. We define {\tt i}, {\tt j}, {\tt k} as the unit vectors. \spadcommand{i: Ext := e(1) } $$ e \sb {1} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \spadcommand{j: Ext := e(2) } $$ e \sb {2} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \spadcommand{k: Ext := e(3) } $$ e \sb {3} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} Now it is possible to do arithmetic. \spadcommand{x := x1*i + x2*j + x3*k } $$ {x1 \ {e \sb {1}}}+{x2 \ {e \sb {2}}}+{x3 \ {e \sb {3}}} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \spadcommand{y := y1*i + y2*j + y3*k } $$ {y1 \ {e \sb {1}}}+{y2 \ {e \sb {2}}}+{y3 \ {e \sb {3}}} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \spadcommand{x + y } $$ {{\left( y1+x1 \right)} \ {e \sb {1}}}+{{\left( y2+x2 \right)} \ {e \sb {2}}}+{{\left( y3+x3 \right)} \ {e \sb {3}}} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \spadcommand{x * y + y * x } $$ 0 $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} On an {\tt n} space, a grade {\tt p} form has a dual {\tt n-p} form. In particular, in three space the dual of a grade two element identifies {\tt e1*e2->e3, e2*e3->e1, e3*e1->e2}. \spadcommand{dual2 a == coefficient(a,[2,3]) * i + coefficient(a,[3,1]) * j + coefficient(a,[1,2]) * k } \returnType{Type: Void} The vector cross product is then given by this. \spadcommand{dual2(x*y) } \begin{verbatim} Compiling function dual2 with type CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX) -> CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX) \end{verbatim} $$ {{\left( {x2 \ y3} -{x3 \ y2} \right)} \ {e \sb {1}}}+{{\left( -{x1 \ y3}+{x3 \ y1} \right)} \ {e \sb {2}}}+{{\left( {x1 \ y2} -{x2 \ y1} \right)} \ {e \sb {3}}} $$ \returnType{Type: CliffordAlgebra(3,Fraction Polynomial Integer,MATRIX)} \subsection{The Dirac Spin Algebra} In this section we will work over the field of rational numbers. \spadcommand{K := Fraction Integer } $$ \mbox{\rm Fraction Integer} $$ \returnType{Type: Domain} We define the quadratic form to be the Minkowski space-time metric. \spadcommand{g := matrix [ [1,0,0,0], [0,-1,0,0], [0,0,-1,0], [0,0,0,-1] ] } $$ \left[ \begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & -1 & 0 & 0 \\ 0 & 0 & -1 & 0 \\ 0 & 0 & 0 & -1 \end{array} \right] $$ \returnType{Type: Matrix Integer} We obtain the Dirac spin algebra used in Relativistic Quantum Field Theory. \spadcommand{D := CliffordAlgebra(4,K, quadraticForm g) } $$ \mbox{\rm CliffordAlgebra(4,Fraction Integer,MATRIX)} $$ \returnType{Type: Domain} The usual notation for the basis is $\gamma$ with a superscript. For Axiom input we will use {\tt gam(i)}: \spadcommand{gam := [e(i)\$D for i in 1..4] } $$ \left[ {e \sb {1}}, {e \sb {2}}, {e \sb {3}}, {e \sb {4}} \right] $$ \returnType{Type: List CliffordAlgebra(4,Fraction Integer,MATRIX)} \noindent There are various contraction identities of the form \begin{verbatim} g(l,t)*gam(l)*gam(m)*gam(n)*gam(r)*gam(s)*gam(t) = 2*(gam(s)gam(m)gam(n)gam(r) + gam(r)*gam(n)*gam(m)*gam(s)) \end{verbatim} where a sum over {\tt l} and {\tt t} is implied. Verify this identity for particular values of {\tt m,n,r,s}. \spadcommand{m := 1; n:= 2; r := 3; s := 4; } \returnType{Type: PositiveInteger} \spadcommand{lhs := reduce(+, [reduce(+, [ g(l,t)*gam(l)*gam(m)*gam(n)*gam(r)*gam(s)*gam(t) for l in 1..4]) for t in 1..4]) } $$ -{4 \ {e \sb {1}} \ {e \sb {2}} \ {e \sb {3}} \ {e \sb {4}}} $$ \returnType{Type: CliffordAlgebra(4,Fraction Integer,MATRIX)} \spadcommand{rhs := 2*(gam s * gam m*gam n*gam r + gam r*gam n*gam m*gam s) } $$ -{4 \ {e \sb {1}} \ {e \sb {2}} \ {e \sb {3}} \ {e \sb {4}}} $$ \returnType{Type: CliffordAlgebra(4,Fraction Integer,MATRIX)} \section{Complex} \label{ComplexXmpPage} The {\tt Complex} constructor implements complex objects over a commutative ring {\tt R}. Typically, the ring {\tt R} is {\tt Integer}, {\tt Fraction Integer}, {\tt Float} or {\tt DoubleFloat}. {\tt R} can also be a symbolic type, like {\tt Polynomial Integer}. For more information about the numerical and graphical aspects of complex numbers, see \ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}. Complex objects are created by the \spadfunFrom{complex}{Complex} operation. \spadcommand{a := complex(4/3,5/2) } $$ {4 \over 3}+{{5 \over 2} \ i} $$ \returnType{Type: Complex Fraction Integer} \spadcommand{b := complex(4/3,-5/2) } $$ {4 \over 3} -{{5 \over 2} \ i} $$ \returnType{Type: Complex Fraction Integer} The standard arithmetic operations are available. \spadcommand{a + b } $$ 8 \over 3 $$ \returnType{Type: Complex Fraction Integer} \spadcommand{a - b } $$ 5 \ i $$ \returnType{Type: Complex Fraction Integer} \spadcommand{a * b } $$ {289} \over {36} $$ \returnType{Type: Complex Fraction Integer} If {\tt R} is a field, you can also divide the complex objects. \spadcommand{a / b } $$ -{{161} \over {289}}+{{{240} \over {289}} \ i} $$ \returnType{Type: Complex Fraction Integer} Use a conversion (\ref{ugTypesConvertPage} on page~\pageref{ugTypesConvertPage} in Section \ref{ugTypesConvertNumber} on page~\pageref{ugTypesConvertNumber}) to view the last object as a fraction of complex integers. \spadcommand{\% :: Fraction Complex Integer } $$ {-{15}+{8 \ i}} \over {{15}+{8 \ i}} $$ \returnType{Type: Fraction Complex Integer} The predefined macro {\tt \%i} is defined to be {\tt complex(0,1)}. \spadcommand{3.4 + 6.7 * \%i} $$ {3.4}+{{6.7} \ i} $$ \returnType{Type: Complex Float} You can also compute the \spadfunFrom{conjugate}{Complex} and \spadfunFrom{norm}{Complex} of a complex number. \spadcommand{conjugate a } $$ {4 \over 3} -{{5 \over 2} \ i} $$ \returnType{Type: Complex Fraction Integer} \spadcommand{norm a } $$ {289} \over {36} $$ \returnType{Type: Fraction Integer} The \spadfunFrom{real}{Complex} and \spadfunFrom{imag}{Complex} operations are provided to extract the real and imaginary parts, respectively. \spadcommand{real a } $$ 4 \over 3 $$ \returnType{Type: Fraction Integer} \spadcommand{imag a } $$ 5 \over 2 $$ \returnType{Type: Fraction Integer} The domain {\tt Complex Integer} is also called the Gaussian integers. If {\tt R} is the integers (or, more generally, a {\tt EuclideanDomain}), you can compute greatest common divisors. \spadcommand{gcd(13 - 13*\%i,31 + 27*\%i)} $$ 5+i $$ \returnType{Type: Complex Integer} You can also compute least common multiples. \spadcommand{lcm(13 - 13*\%i,31 + 27*\%i)} $$ {143} -{{39} \ i} $$ \returnType{Type: Complex Integer} You can \spadfunFrom{factor}{Complex} Gaussian integers. \spadcommand{factor(13 - 13*\%i)} $$ -{{\left( 1+i \right)} \ {\left( 2+{3 \ i} \right)} \ {\left( 3+{2 \ i} \right)}} $$ \returnType{Type: Factored Complex Integer} \spadcommand{factor complex(2,0)} $$ -{i \ {{\left( 1+i \right)} \sp 2}} $$ \returnType{Type: Factored Complex Integer} \section{ContinuedFraction} \label{ContinuedFractionXmpPage} Continued fractions have been a fascinating and useful tool in mathematics for well over three hundred years. Axiom implements continued fractions for fractions of any Euclidean domain. In practice, this usually means rational numbers. In this section we demonstrate some of the operations available for manipulating both finite and infinite continued fractions. It may be helpful if you review \ref{StreamXmpPage} on page~\pageref{StreamXmpPage} to remind yourself of some of the operations with streams. The {\tt ContinuedFraction} domain is a field and therefore you can add, subtract, multiply and divide the fractions. The \spadfunFrom{continuedFraction}{ContinuedFraction} operation converts its fractional argument to a continued fraction. \spadcommand{c := continuedFraction(314159/100000) } $$ 3+ \zag{1}{7}+ \zag{1}{{15}}+ \zag{1}{1}+ \zag{1}{{25}}+ \zag{1}{1}+ \zag{1}{7}+ \zag{1}{4} $$ \returnType{Type: ContinuedFraction Integer} This display is a compact form of the bulkier \begin{verbatim} 3 + 1 ------------------------------- 7 + 1 --------------------------- 15 + 1 ---------------------- 1 + 1 ------------------ 25 + 1 ------------- 1 + 1 --------- 7 + 1 ----- 4 \end{verbatim} You can write any rational number in a similar form. The fraction will be finite and you can always take the ``numerators'' to be {\tt 1}. That is, any rational number can be written as a simple, finite continued fraction of the form \begin{verbatim} a(1) + 1 ------------------------- a(2) + 1 -------------------- a(3) + . . . 1 ------------- a(n-1) + 1 ---- a(n) \end{verbatim} The $a_i$ are called partial quotients and the operation \spadfunFrom{partialQuotients}{ContinuedFraction} creates a stream of them. \spadcommand{partialQuotients c } $$ \left[ 3, 7, {15}, 1, {25}, 1, 7, \ldots \right] $$ \returnType{Type: Stream Integer} By considering more and more of the fraction, you get the \spadfunFrom{convergents}{ContinuedFraction}. For example, the first convergent is $a_1$, the second is $a_1 + 1/a_2$ and so on. \spadcommand{convergents c } $$ \left[ 3, {{22} \over 7}, {{333} \over {106}}, {{355} \over {113}}, {{9208} \over {2931}}, {{9563} \over {3044}}, {{76149} \over {24239}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} Since this is a finite continued fraction, the last convergent is the original rational number, in reduced form. The result of \spadfunFrom{approximants}{ContinuedFraction} is always an infinite stream, though it may just repeat the ``last'' value. \spadcommand{approximants c } $$ \left[ 3, {{22} \over 7}, {{333} \over {106}}, {{355} \over {113}}, {{9208} \over {2931}}, {{9563} \over {3044}}, {{76149} \over {24239}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} Inverting {\tt c} only changes the partial quotients of its fraction by inserting a {\tt 0} at the beginning of the list. \spadcommand{pq := partialQuotients(1/c) } $$ \left[ 0, 3, 7, {15}, 1, {25}, 1, \ldots \right] $$ \returnType{Type: Stream Integer} Do this to recover the original continued fraction from this list of partial quotients. The three-argument form of the \spadfunFrom{continuedFraction}{ContinuedFraction} operation takes an element which is the whole part of the fraction, a stream of elements which are the numerators of the fraction, and a stream of elements which are the denominators of the fraction. \spadcommand{continuedFraction(first pq,repeating [1],rest pq) } $$ \zag{1}{3}+ \zag{1}{7}+ \zag{1}{{15}}+ \zag{1}{1}+ \zag{1}{{25}}+ \zag{1}{1}+ \zag{1}{7}+\ldots $$ \returnType{Type: ContinuedFraction Integer} The streams need not be finite for \spadfunFrom{continuedFraction}{ContinuedFraction}. Can you guess which irrational number has the following continued fraction? See the end of this section for the answer. \spadcommand{z:=continuedFraction(3,repeating [1],repeating [3,6]) } $$ 3+ \zag{1}{3}+ \zag{1}{6}+ \zag{1}{3}+ \zag{1}{6}+ \zag{1}{3}+ \zag{1}{6}+ \zag{1}{3}+\ldots $$ \returnType{Type: ContinuedFraction Integer} In 1737 Euler discovered the infinite continued fraction expansion \begin{verbatim} e - 1 1 ----- = --------------------- 2 1 + 1 ----------------- 6 + 1 ------------- 10 + 1 -------- 14 + ... \end{verbatim} We use this expansion to compute rational and floating point approximations of {\tt e}.\footnote{For this and other interesting expansions, see C. D. Olds, {\it Continued Fractions,} New Mathematical Library, (New York: Random House, 1963), pp. 134--139.} By looking at the above expansion, we see that the whole part is {\tt 0} and the numerators are all equal to {\tt 1}. This constructs the stream of denominators. \spadcommand{dens:Stream Integer := cons(1,generate((x+->x+4),6)) } $$ \left[ 1, 6, {10}, {14}, {18}, {22}, {26}, \ldots \right] $$ \returnType{Type: Stream Integer} Therefore this is the continued fraction expansion for $(e - 1) / 2$. \spadcommand{cf := continuedFraction(0,repeating [1],dens) } $$ \zag{1}{1}+ \zag{1}{6}+ \zag{1}{{10}}+ \zag{1}{{14}}+ \zag{1}{{18}}+ \zag{1}{{22}}+ \zag{1}{{26}}+\ldots $$ \returnType{Type: ContinuedFraction Integer} These are the rational number convergents. \spadcommand{ccf := convergents cf } $$ \left[ 0, 1, {6 \over 7}, {{61} \over {71}}, {{860} \over {1001}}, {{15541} \over {18089}}, {{342762} \over {398959}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} You can get rational convergents for {\tt e} by multiplying by {\tt 2} and adding {\tt 1}. \spadcommand{eConvergents := [2*e + 1 for e in ccf] } $$ \left[ 1, 3, {{19} \over 7}, {{193} \over {71}}, {{2721} \over {1001}}, {{49171} \over {18089}}, {{1084483} \over {398959}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} You can also compute the floating point approximations to these convergents. \spadcommand{eConvergents :: Stream Float } $$ \begin{array}{@{}l} \left[ {1.0}, {3.0}, {2.7142857142 857142857}, {2.7183098591 549295775}, \right. \\ \\ \displaystyle {2.7182817182 817182817}, {2.7182818287 356957267}, \\ \\ \displaystyle \left. {2.7182818284\ 585634113}, \ldots \right] \end{array} $$ \returnType{Type: Stream Float} Compare this to the value of {\tt e} computed by the \spadfunFrom{exp}{Float} operation in {\tt Float}. \spadcommand{exp 1.0} $$ 2.7182818284\ 590452354 $$ \returnType{Type: Float} In about 1658, Lord Brouncker established the following expansion for $4 / \pi$, \begin{verbatim} 1 + 1 ----------------------- 2 + 9 ------------------- 2 + 25 --------------- 2 + 49 ----------- 2 + 81 ------- 2 + ... \end{verbatim} Let's use this expansion to compute rational and floating point approximations for $\pi$. \spadcommand{cf := continuedFraction(1,[(2*i+1)**2 for i in 0..],repeating [2])} $$ 1+ \zag{1}{2}+ \zag{9}{2}+ \zag{{25}}{2}+ \zag{{49}}{2}+ \zag{{81}}{2}+ \zag{{121}}{2}+ \zag{{169}}{2}+\ldots $$ \returnType{Type: ContinuedFraction Integer} \spadcommand{ccf := convergents cf } $$ \left[ 1, {3 \over 2}, {{15} \over {13}}, {{105} \over {76}}, {{315} \over {263}}, {{3465} \over {2578}}, {{45045} \over {36979}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} \spadcommand{piConvergents := [4/p for p in ccf] } $$ \left[ 4, {8 \over 3}, {{52} \over {15}}, {{304} \over {105}}, {{1052} \over {315}}, {{10312} \over {3465}}, {{147916} \over {45045}}, \ldots \right] $$ \returnType{Type: Stream Fraction Integer} As you can see, the values are converging to $\pi = 3.14159265358979323846...$, but not very quickly. \spadcommand{piConvergents :: Stream Float } $$ \begin{array}{@{}l} \left[ {4.0}, {2.6666666666\ 666666667}, {3.4666666666\ 666666667}, \right. \\ \\ \displaystyle {2.8952380952\ 380952381}, {3.3396825396\ 825396825}, \\ \\ \displaystyle \left. {2.9760461760\ 461760462}, {3.2837384837\ 384837385}, \ldots \right] \end{array} $$ \returnType{Type: Stream Float} You need not restrict yourself to continued fractions of integers. Here is an expansion for a quotient of Gaussian integers. \spadcommand{continuedFraction((- 122 + 597*\%i)/(4 - 4*\%i))} $$ -{90}+{{59} \ i}+ \zag{1}{{1 -{2 \ i}}}+ \zag{1}{{-1+{2 \ i}}} $$ \returnType{Type: ContinuedFraction Complex Integer} This is an expansion for a quotient of polynomials in one variable with rational number coefficients. \spadcommand{r : Fraction UnivariatePolynomial(x,Fraction Integer) } \returnType{Type: Void} \spadcommand{r := ((x - 1) * (x - 2)) / ((x-3) * (x-4)) } $$ {{x \sp 2} -{3 \ x}+2} \over {{x \sp 2} -{7 \ x}+{12}} $$ \returnType{Type: Fraction UnivariatePolynomial(x,Fraction Integer)} \spadcommand{continuedFraction r } $$ 1+ \zag{1}{{{{1 \over 4} \ x} -{9 \over 8}}}+ \zag{1}{{{{{16} \over 3} \ x} -{{40} \over 3}}} $$ \returnType{Type: ContinuedFraction UnivariatePolynomial(x,Fraction Integer)} To conclude this section, we give you evidence that \begin{verbatim} z = 3 + 1 ----------------------- 3 + 1 ------------------- 6 + 1 --------------- 3 + 1 ----------- 6 + 1 ------- 3 + ... \end{verbatim} is the expansion of $\sqrt{11}$. \spadcommand{[i*i for i in convergents(z) :: Stream Float] } $$ \begin{array}{@{}l} \left[ {9.0}, {11.1111111111\ 11111111}, {10.9944598337\ 9501385}, \right. \\ \\ \displaystyle {11.0002777777\ 77777778}, {10.9999860763\ 98799786}, \\ \\ \displaystyle \left. {11.0000006979\ 29731039}, {10.9999999650\ 15834446}, \ldots \right] \end{array} $$ \returnType{Type: Stream Float} \section{CycleIndicators} \label{CycleIndicatorsXmpPage} This section is based upon the paper J. H. Redfield, ``The Theory of Group-Reduced Distributions'', American J. Math.,49 (1927) 433-455, and is an application of group theory to enumeration problems. It is a development of the work by P. A. MacMahon on the application of symmetric functions and Hammond operators to combinatorial theory. The theory is based upon the power sum symmetric functions $s_i$ which are the sum of the $i$-th powers of the variables. The cycle index of a permutation is an expression that specifies the sizes of the cycles of a permutation, and may be represented as a partition. A partition of a non-negative integer {\tt n} is a collection of positive integers called its parts whose sum is {\tt n}. For example, the partition $(3^2 \ 2 \ 1^2)$ will be used to represent $s^2_3 s_2 s^2_1$ and will indicate that the permutation has two cycles of length 3, one of length 2 and two of length 1. The cycle index of a permutation group is the sum of the cycle indices of its permutations divided by the number of permutations. The cycle indices of certain groups are provided. The operation {\tt complete} returns the cycle index of the symmetric group of order {\tt n} for argument {\tt n}. Alternatively, it is the $n$-th complete homogeneous symmetric function expressed in terms of power sum symmetric functions. \spadcommand{complete 1} $$ \left( 1 \right) $$ \returnType{Type: SymmetricPolynomial Fraction Integer} \spadcommand{complete 2} $$ {{1 \over 2} \ {\left( 2 \right)}}+{{1 \over 2} \ {\left( 1 \sp 2 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} \spadcommand{complete 3} $$ {{1 \over 3} \ {\left( 3 \right)}}+{{1 \over 2} \ {\left( {2 \sp {\ }} \ 1 \right)}}+{{1 \over 6} \ {\left( 1 \sp 3 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} \spadcommand{complete 7} $$ \begin{array}{@{}l} {{1 \over 7} \ {\left( 7 \right)}}+ {{1\over 6} \ {\left( {6 \sp {\ }} \ 1 \right)}}+ {{1\over {10}} \ {\left( {5 \sp {\ }} \ 2 \right)}}+ {{1\over {10}} \ {\left( {5 \sp {\ }} \ {1 \sp 2} \right)}}+ {{1\over {12}} \ {\left( {4 \sp {\ }} \ 3 \right)}}+ {{1\over 8} \ {\left( {4 \sp {\ }} \ {2 \sp {\ }} \ 1 \right)}}+ \\ \\ \displaystyle {{1\over {24}} \ {\left( {4 \sp {\ }} \ {1 \sp 3} \right)}}+ {{1\over {18}} \ {\left( {3 \sp 2} \ 1 \right)}}+ {{1\over {24}} \ {\left( {3 \sp {\ }} \ {2 \sp 2} \right)}}+ {{1\over {12}} \ {\left( {3 \sp {\ }} \ {2 \sp {\ }} \ {1 \sp 2} \right)}}+ {{1\over {72}} \ {\left( {3 \sp {\ }} \ {1 \sp 4} \right)}}+ \\ \\ \displaystyle {{1\over {48}} \ {\left( {2 \sp 3} \ 1 \right)}}+ {{1\over {48}} \ {\left( {2 \sp 2} \ {1 \sp 3} \right)}}+ {{1\over {240}} \ {\left( {2 \sp {\ }} \ {1 \sp 5} \right)}}+ {{1\over {5040}} \ {\left( 1 \sp 7 \right)}} \end{array} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The operation {\tt elementary} computes the $n$-th elementary symmetric function for argument {\tt n.} \spadcommand{elementary 7} $$ \begin{array}{@{}l} {{1 \over 7} \ {\left( 7 \right)}} -{{1 \over 6} \ {\left( {6 \sp {\ }} \ 1 \right)}} -{{1 \over {10}} \ {\left( {5 \sp {\ }} \ 2 \right)}}+ {{1\over {10}} \ {\left( {5 \sp {\ }} \ {1 \sp 2} \right)}} -{{1 \over {12}} \ {\left( {4 \sp {\ }} \ 3 \right)}}+ {{1\over 8} \ {\left( {4 \sp {\ }} \ {2 \sp {\ }} \ 1 \right)}} \\ \\ \displaystyle -{{1 \over {24}} \ {\left( {4 \sp {\ }} \ {1 \sp 3} \right)}}+ {{1\over {18}} \ {\left( {3 \sp 2} \ 1 \right)}}+ {{1\over {24}} \ {\left( {3 \sp {\ }} \ {2 \sp 2} \right)}} -{{1 \over {12}} \ {\left( {3 \sp {\ }} \ {2 \sp {\ }} \ {1 \sp 2} \right)}} +{{1\over {72}} \ {\left( {3 \sp {\ }} \ {1 \sp 4} \right)}} \\ \\ \displaystyle -{{1 \over {48}} \ {\left( {2 \sp 3} \ 1 \right)}}+ {{1\over {48}} \ {\left( {2 \sp 2} \ {1 \sp 3} \right)}} -{{1 \over {240}} \ {\left( {2 \sp {\ }} \ {1 \sp 5} \right)}}+ {{1\over {5040}} \ {\left( 1 \sp 7 \right)}} \end{array} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The operation {\tt alternating} returns the cycle index of the alternating group having an even number of even parts in each cycle partition. \spadcommand{alternating 7} $$ \begin{array}{@{}l} {{2 \over 7} \ {\left( 7 \right)}}+ {{1\over 5} \ {\left( {5 \sp {\ }} \ {1 \sp 2} \right)}}+ {{1\over 4} \ {\left( {4 \sp {\ }} \ {2 \sp {\ }} \ 1 \right)}}+ {{1\over 9} \ {\left( {3 \sp 2} \ 1 \right)}}+ {{1\over {12}} \ {\left( {3 \sp {\ }} \ {2 \sp 2} \right)}}+ {{1\over {36}} \ {\left( {3 \sp {\ }} \ {1 \sp 4} \right)}}+ \\ \\ \displaystyle {{1\over {24}} \ {\left( {2 \sp 2} \ {1 \sp 3} \right)}}+ {{1\over {2520}} \ {\left( 1 \sp 7 \right)}} \end{array} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The operation {\tt cyclic} returns the cycle index of the cyclic group. \spadcommand{cyclic 7} $$ {{6 \over 7} \ {\left( 7 \right)}}+ {{1\over 7} \ {\left( 1 \sp 7 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The operation {\tt dihedral} is the cycle index of the dihedral group. \spadcommand{dihedral 7} $$ {{3 \over 7} \ {\left( 7 \right)}}+ {{1\over 2} \ {\left( {2 \sp 3} \ 1 \right)}}+ {{1\over {14}} \ {\left( 1 \sp 7 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The operation {\tt graphs} for argument {\tt n} returns the cycle index of the group of permutations on the edges of the complete graph with {\tt n} nodes induced by applying the symmetric group to the nodes. \spadcommand{graphs 5} $$ \begin{array}{@{}l} {{1 \over 6} \ {\left( {6 \sp {\ }} \ {3 \sp {\ }} \ 1 \right)}}+ {{1\over 5} \ {\left( 5 \sp 2 \right)}}+ {{1\over 4} \ {\left( {4 \sp 2} \ 2 \right)}}+ {{1\over 6} \ {\left( {3 \sp 3} \ 1 \right)}}+ {{1\over 8} \ {\left( {2 \sp 4} \ {1 \sp 2} \right)}}+ \\ \\ \displaystyle {{1\over {12}} \ {\left( {2 \sp 3} \ {1 \sp 4} \right)}}+ {{1\over {120}} \ {\left( 1 \sp {10} \right)}} \end{array} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The cycle index of a direct product of two groups is the product of the cycle indices of the groups. Redfield provided two operations on two cycle indices which will be called ``cup'' and ``cap'' here. The {\tt cup} of two cycle indices is a kind of scalar product that combines monomials for permutations with the same cycles. The {\tt cap} operation provides the sum of the coefficients of the result of the {\tt cup} operation which will be an integer that enumerates what Redfield called group-reduced distributions. We can, for example, represent {\tt complete 2 * complete 2} as the set of objects {\tt a a b b} and {\tt complete 2 * complete 1 * complete 1} as {\tt c c d e.} This integer is the number of different sets of four pairs. \spadcommand{cap(complete 2**2, complete 2*complete 1**2)} $$ 4 $$ \returnType{Type: Fraction Integer} For example, \begin{verbatim} a a b b a a b b a a b b a a b b c c d e c d c e c e c d d e c c \end{verbatim} This integer is the number of different sets of four pairs no two pairs being equal. \spadcommand{cap(elementary 2**2, complete 2*complete 1**2)} $$ 2 $$ \returnType{Type: Fraction Integer} For example, \begin{verbatim} a a b b a a b b c d c e c e c d \end{verbatim} In this case the configurations enumerated are easily constructed, however the theory merely enumerates them providing little help in actually constructing them. Here are the number of 6-pairs, first from {\tt a a a b b c,} second from {\tt d d e e f g.} \spadcommand{cap(complete 3*complete 2*complete 1,complete 2**2*complete 1**2)} $$ 24 $$ \returnType{Type: Fraction Integer} Here it is again, but with no equal pairs. \spadcommand{cap(elementary 3*elementary 2*elementary 1,complete 2**2*complete 1**2)} $$ 8 $$ \returnType{Type: Fraction Integer} \spadcommand{cap(complete 3*complete 2*complete 1,elementary 2**2*elementary 1**2)} $$ 8 $$ \returnType{Type: Fraction Integer} The number of 6-triples, first from {\tt a a a b b c,} second from {\tt d d e e f g,} third from {\tt h h i i j j.} \spadcommand{eval(cup(complete 3*complete 2*complete 1, cup(complete 2**2*complete 1**2,complete 2**3)))} $$ 1500 $$ \returnType{Type: Fraction Integer} The cycle index of vertices of a square is dihedral 4. \spadcommand{square:=dihedral 4} $$ {{1 \over 4} \ {\left( 4 \right)}}+ {{3\over 8} \ {\left( 2 \sp 2 \right)}}+ {{1\over 4} \ {\left( {2 \sp {\ }} \ {1 \sp 2} \right)}}+ {{1\over 8} \ {\left( 1 \sp 4 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The number of different squares with 2 red vertices and 2 blue vertices. \spadcommand{cap(complete 2**2,square)} $$ 2 $$ \returnType{Type: Fraction Integer} The number of necklaces with 3 red beads, 2 blue beads and 2 green beads. \spadcommand{cap(complete 3*complete 2**2,dihedral 7)} $$ 18 $$ \returnType{Type: Fraction Integer} The number of graphs with 5 nodes and 7 edges. \spadcommand{cap(graphs 5,complete 7*complete 3)} $$ 4 $$ \returnType{Type: Fraction Integer} The cycle index of rotations of vertices of a cube. \spadcommand{s(x) == powerSum(x)} \returnType{Type: Void} \spadcommand{cube:=(1/24)*(s 1**8+9*s 2**4 + 8*s 3**2*s 1**2+6*s 4**2)} \begin{verbatim} Compiling function s with type PositiveInteger -> SymmetricPolynomial Fraction Integer \end{verbatim} $$ {{1 \over 4} \ {\left( 4 \sp 2 \right)}}+ {{1\over 3} \ {\left( {3 \sp 2} \ {1 \sp 2} \right)}}+ {{3\over 8} \ {\left( 2 \sp 4 \right)}}+ {{1\over {24}} \ {\left( 1 \sp 8 \right)}} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} The number of cubes with 4 red vertices and 4 blue vertices. \spadcommand{cap(complete 4**2,cube)} $$ 7 $$ \returnType{Type: Fraction Integer} The number of labeled graphs with degree sequence {\tt 2 2 2 1 1} with no loops or multiple edges. \spadcommand{cap(complete 2**3*complete 1**2,wreath(elementary 4,elementary 2))} $$ 7 $$ \returnType{Type: Fraction Integer} Again, but with loops allowed but not multiple edges. \spadcommand{cap(complete 2**3*complete 1**2,wreath(elementary 4,complete 2))} $$ 17 $$ \returnType{Type: Fraction Integer} Again, but with multiple edges allowed, but not loops \spadcommand{cap(complete 2**3*complete 1**2,wreath(complete 4,elementary 2))} $$ 10 $$ \returnType{Type: Fraction Integer} Again, but with both multiple edges and loops allowed \spadcommand{cap(complete 2**3*complete 1**2,wreath(complete 4,complete 2))} $$ 23 $$ \returnType{Type: Fraction Integer} Having constructed a cycle index for a configuration we are at liberty to evaluate the $s_i$ components any way we please. For example we can produce enumerating generating functions. This is done by providing a function {\tt f} on an integer {\tt i} to the value required of $s_i$, and then evaluating {\tt eval(f, cycleindex)}. \spadcommand{x: ULS(FRAC INT,'x,0) := 'x } $$ x $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} \spadcommand{ZeroOrOne: INT -> ULS(FRAC INT, 'x, 0) } \returnType{Type: Void} \spadcommand{Integers: INT -> ULS(FRAC INT, 'x, 0) } \returnType{Type: Void} For the integers 0 and 1, or two colors. \spadcommand{ZeroOrOne n == 1+x**n } \returnType{Type: Void} \spadcommand{ZeroOrOne 5 } \begin{verbatim} Compiling function ZeroOrOne with type Integer -> UnivariateLaurentSeries(Fraction Integer,x,0) \end{verbatim} $$ 1+{x \sp 5} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} For the integers {\tt 0, 1, 2, ...} we have this. \spadcommand{Integers n == 1/(1-x**n) } \returnType{Type: Void} \spadcommand{Integers 5 } \begin{verbatim} Compiling function Integers with type Integer -> UnivariateLaurentSeries(Fraction Integer,x,0) \end{verbatim} $$ 1+{x \sp 5}+{O \left( {{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of graphs with 5 nodes and {\tt n} edges. Note that there is an eval function that takes two arguments. It has the signature: \begin{verbatim} ((Integer -> D1),SymmetricPolynomial Fraction Integer) -> D1 from EvaluateCycleIndicators D1 if D1 has ALGEBRA FRAC INT \end{verbatim} This function is not normally exposed (it will not normally be considered in the list of eval functions) as it is only useful for this particular domain. To use it we ask that it be considered thus: \spadcommand{)expose EVALCYC} and now we can use it: \spadcommand{eval(ZeroOrOne, graphs 5) } $$ 1+x+ {2 \ {x \sp 2}}+ {4 \ {x \sp 3}}+ {6 \ {x \sp 4}}+ {6 \ {x \sp 5}}+ {6 \ {x \sp 6}}+ {4 \ {x \sp 7}}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of necklaces with {\tt n} red beads and {\tt n-8} green beads. \spadcommand{eval(ZeroOrOne,dihedral 8) } $$ 1+x+ {4 \ {x \sp 2}}+ {5 \ {x \sp 3}}+ {8 \ {x \sp 4}}+ {5 \ {x \sp 5}}+ {4 \ {x \sp 6}}+ {x \sp 7}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of partitions of {\tt n} into 4 or fewer parts. \spadcommand{eval(Integers,complete 4) } $$ 1+x+ {2 \ {x \sp 2}}+ {3 \ {x \sp 3}}+ {5 \ {x \sp 4}}+ {6 \ {x \sp 5}}+ {9 \ {x \sp 6}}+ {{11} \ {x \sp 7}}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of partitions of {\tt n} into 4 boxes containing ordered distinct parts. \spadcommand{eval(Integers,elementary 4) } $$ {x \sp 6}+ {x \sp 7}+ {2 \ {x \sp 8}}+ {3 \ {x \sp 9}}+ {5 \ {x \sp {10}}}+ {6 \ {x \sp {11}}}+ {9 \ {x \sp {12}}}+ {{11} \ {x \sp {13}}}+ {O \left({{x \sp {14}}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of different cubes with {\tt n} red vertices and {\tt 8-n} green ones. \spadcommand{eval(ZeroOrOne,cube) } $$ 1+x+ {3 \ {x \sp 2}}+ {3 \ {x \sp 3}}+ {7 \ {x \sp 4}}+ {3 \ {x \sp 5}}+ {3 \ {x \sp 6}}+ {x \sp 7}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of different cubes with integers on the vertices whose sum is {\tt n.} \spadcommand{eval(Integers,cube) } $$ 1+x+ {4 \ {x \sp 2}}+ {7 \ {x \sp 3}}+ {{21} \ {x \sp 4}}+ {{37} \ {x \sp 5}}+ {{85} \ {x \sp 6}}+ {{151} \ {x \sp 7}}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The coefficient of $x^n$ is the number of graphs with 5 nodes and with integers on the edges whose sum is {\tt n.} In other words, the enumeration is of multigraphs with 5 nodes and {\tt n} edges. \spadcommand{eval(Integers,graphs 5) } $$ 1+x+ {3 \ {x \sp 2}}+ {7 \ {x \sp 3}}+ {{17} \ {x \sp 4}}+ {{35} \ {x \sp 5}}+ {{76} \ {x \sp 6}}+ {{149} \ {x \sp 7}}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} Graphs with 15 nodes enumerated with respect to number of edges. \spadcommand{eval(ZeroOrOne ,graphs 15) } $$ 1+x+ {2 \ {x \sp 2}}+ {5 \ {x \sp 3}}+ {{11} \ {x \sp 4}}+ {{26} \ {x \sp 5}}+ {{68} \ {x \sp 6}}+ {{177} \ {x \sp 7}}+ {O \left({{x \sp 8}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} Necklaces with 7 green beads, 8 white beads, 5 yellow beads and 10 red beads. \spadcommand{cap(dihedral 30,complete 7*complete 8*complete 5*complete 10)} $$ 49958972383320 $$ \returnType{Type: Fraction Integer} The operation {\tt SFunction} is the S-function or Schur function of a partition written as a descending list of integers expressed in terms of power sum symmetric functions. In this case the argument partition represents a tableau shape. For example {\tt 3,2,2,1} represents a tableau with three boxes in the first row, two boxes in the second and third rows, and one box in the fourth row. {\tt SFunction [3,2,2,1]} counts the number of different tableaux of shape {\tt 3, 2, 2, 1} filled with objects with an ascending order in the columns and a non-descending order in the rows. \spadcommand{sf3221:= SFunction [3,2,2,1] } $$ \begin{array}{@{}l} {{1 \over {12}} \ {\left( {6 \sp {\ }} \ 2 \right)}} -{{1 \over {12}} \ {\left( {6 \sp {\ }} \ {1 \sp 2} \right)}} -{{1 \over {16}} \ {\left( 4 \sp 2 \right)}}+ {{1\over {12}} \ {\left( {4 \sp {\ }} \ {3 \sp {\ }} \ 1 \right)}}+ {{1\over {24}} \ {\left( {4 \sp {\ }} \ {1 \sp 4} \right)}} -{{1 \over {36}} \ {\left( {3 \sp 2} \ 2 \right)}}+ \\ \\ \displaystyle {{1\over {36}} \ {\left( {3 \sp 2} \ {1 \sp 2} \right)}} -{{1 \over {24}} \ {\left( {3 \sp {\ }} \ {2 \sp 2} \ 1 \right)}} -{{1 \over {36}} \ {\left( {3 \sp {\ }} \ {2 \sp {\ }} \ {1 \sp 3} \right)}} -{{1 \over {72}} \ {\left( {3 \sp {\ }} \ {1 \sp 5} \right)}} -{{1 \over {192}} \ {\left( 2 \sp 4 \right)}}+ \\ \\ \displaystyle {{1\over {48}} \ {\left( {2 \sp 3} \ {1 \sp 2} \right)}}+ {{1\over {96}} \ {\left( {2 \sp 2} \ {1 \sp 4} \right)}} -{{1 \over {144}} \ {\left( {2 \sp {\ }} \ {1 \sp 6} \right)}}+ {{1\over {576}} \ {\left( 1 \sp 8 \right)}} \end{array} $$ \returnType{Type: SymmetricPolynomial Fraction Integer} This is the number filled with {\tt a a b b c c d d.} \spadcommand{cap(sf3221,complete 2**4) } $$ 3 $$ \returnType{Type: Fraction Integer} The configurations enumerated above are: \begin{verbatim} a a b a a c a a d b c b b b b c d c d c c d d d \end{verbatim} This is the number of tableaux filled with {\tt 1..8.} \spadcommand{cap(sf3221, powerSum 1**8)} $$ 70 $$ \returnType{Type: Fraction Integer} The coefficient of $x^n$ is the number of column strict reverse plane partitions of {\tt n} of shape {\tt 3 2 2 1.} \spadcommand{eval(Integers, sf3221)} $$ {x \sp 9}+ {3 \ {x \sp {10}}}+ {7 \ {x \sp {11}}}+ {{14} \ {x \sp {12}}}+ {{27} \ {x \sp {13}}}+ {{47} \ {x \sp {14}}}+ {O \left({{x \sp {15}}} \right)} $$ \returnType{Type: UnivariateLaurentSeries(Fraction Integer,x,0)} The smallest is \begin{verbatim} 0 0 0 1 1 2 2 3 \end{verbatim} \section{DeRhamComplex} \label{DeRhamComplexXmpPage} The domain constructor {\tt DeRhamComplex} creates the class of differential forms of arbitrary degree over a coefficient ring. The De Rham complex constructor takes two arguments: a ring, {\tt coefRing,} and a list of coordinate variables. This is the ring of coefficients. \spadcommand{coefRing := Integer } $$ Integer $$ \returnType{Type: Domain} These are the coordinate variables. \spadcommand{lv : List Symbol := [x,y,z] } $$ \left[ x, y, z \right] $$ \returnType{Type: List Symbol} This is the De Rham complex of Euclidean three-space using coordinates {\tt x, y} and {\tt z.} \spadcommand{der := DERHAM(coefRing,lv) } $$ DeRhamComplex(Integer,[x,y,z]) $$ \returnType{Type: Domain} This complex allows us to describe differential forms having expressions of integers as coefficients. These coefficients can involve any number of variables, for example, {\tt f(x,t,r,y,u,z).} As we've chosen to work with ordinary Euclidean three-space, expressions involving these forms are treated as functions of {\tt x, y} and {\tt z} with the additional arguments {\tt t, r} and {\tt u} regarded as symbolic constants. Here are some examples of coefficients. \spadcommand{R := Expression coefRing } $$ \mbox{\rm Expression Integer} $$ \returnType{Type: Domain} \spadcommand{f : R := x**2*y*z-5*x**3*y**2*z**5 } $$ -{5 \ {x \sp 3} \ {y \sp 2} \ {z \sp 5}}+{{x \sp 2} \ y \ z} $$ \returnType{Type: Expression Integer} \spadcommand{g : R := z**2*y*cos(z)-7*sin(x**3*y**2)*z**2 } $$ -{7 \ {z \sp 2} \ {\sin \left({{{x \sp 3} \ {y \sp 2}}} \right)}}+ {y\ {z \sp 2} \ {\cos \left({z} \right)}} $$ \returnType{Type: Expression Integer} \spadcommand{h : R :=x*y*z-2*x**3*y*z**2 } $$ -{2 \ {x \sp 3} \ y \ {z \sp 2}}+{x \ y \ z} $$ \returnType{Type: Expression Integer} We now define the multiplicative basis elements for the exterior algebra over {\tt R}. \spadcommand{dx : der := generator(1) } $$ dx $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} \spadcommand{dy : der := generator(2)} $$ dy $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} \spadcommand{dz : der := generator(3)} $$ dz $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} This is an alternative way to give the above assignments. \spadcommand{[dx,dy,dz] := [generator(i)\$der for i in 1..3] } $$ \left[ dx, dy, dz \right] $$ \returnType{Type: List DeRhamComplex(Integer,[x,y,z])} Now we define some one-forms. \spadcommand{alpha : der := f*dx + g*dy + h*dz } $$ \begin{array}{@{}l} {{\left( -{2 \ {x \sp 3} \ y \ {z \sp 2}}+{x \ y \ z} \right)}\ dz}+ \\ \\ \displaystyle {{\left( -{7 \ {z \sp 2} \ {\sin \left({{{x \sp 3} \ {y \sp 2}}} \right)}}+ {y\ {z \sp 2} \ {\cos \left({z} \right)}} \right)}\ dy}+ \\ \\ \displaystyle {{\left( -{5 \ {x \sp 3} \ {y \sp 2} \ {z \sp 5}}+{{x \sp 2} \ y \ z} \right)}\ dx} \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} \spadcommand{beta : der := cos(tan(x*y*z)+x*y*z)*dx + x*dy } $$ {x \ dy}+ {{\cos \left({{{\tan \left({{x \ y \ z}} \right)}+{x\ y \ z}}} \right)} \ dx} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} A well-known theorem states that the composition of \spadfunFrom{exteriorDifferential}{DeRhamComplex} with itself is the zero map for continuous forms. Let's verify this theorem for {\tt alpha}. \spadcommand{exteriorDifferential alpha } $$ \begin{array}{@{}l} {{\left( {y \ {z \sp 2} \ {\sin \left({z} \right)}}+ {{14}\ z \ {\sin \left({{{x \sp 3} \ {y \sp 2}}} \right)}} -{2 \ y \ z \ {\cos \left({z} \right)}} -{2 \ {x \sp 3} \ {z \sp 2}}+{x \ z} \right)}\ dy \ dz}+ \\ \\ \displaystyle {{\left( {{25} \ {x \sp 3} \ {y \sp 2} \ {z \sp 4}} - {6 \ {x \sp 2} \ y \ {z \sp 2}}+ {y \ z} - {{x \sp 2} \ y} \right)}\ dx \ dz}+ \\ \\ \displaystyle {{\left( -{{21} \ {x \sp 2} \ {y \sp 2} \ {z \sp 2} \ {\cos \left({{{x \sp 3} \ {y \sp 2}}} \right)}}+ {{10}\ {x \sp 3} \ y \ {z \sp 5}} -{{x \sp 2} \ z} \right)}\ dx \ dy} \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} We see a lengthy output of the last expression, but nevertheless, the composition is zero. \spadcommand{exteriorDifferential \% } $$ 0 $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} Now we check that \spadfunFrom{exteriorDifferential}{DeRhamComplex} is a ``graded derivation'' {\tt D,} that is, {\tt D} satisfies: \begin{verbatim} D(a*b) = D(a)*b + (-1)**degree(a)*a*D(b) \end{verbatim} \spadcommand{gamma := alpha * beta } $$ \begin{array}{@{}l} {{\left( {2 \ {x \sp 4} \ y \ {z \sp 2}} - {{x \sp 2} \ y \ z} \right)}\ dy \ dz}+ \\ \\ \displaystyle {{\left( {2 \ {x \sp 3} \ y \ {z \sp 2}} -{x \ y \ z} \right)} \ {\cos \left( {{{\tan \left({{x \ y \ z}} \right)}+ {x\ y \ z}}} \right)}\ dx \ dz}+ \\ \\ \displaystyle \left( {{\left( {7 \ {z \sp 2} \ {\sin \left({{{x \sp 3} \ {y \sp 2}}} \right)}} -{y \ {z \sp 2} \ {\cos \left({z} \right)}} \right)} \ {\cos \left({{{\tan \left({{x \ y \ z}} \right)}+{x\ y \ z}}} \right)}}- \right. \\ \\ \left. \displaystyle {5 \ {x \sp 4} \ {y \sp 2} \ {z \sp 5}}+ {{x \sp 3} \ y \ z} \right)\ dx \ dy \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} We try this for the one-forms {\tt alpha} and {\tt beta}. \spadcommand{exteriorDifferential(gamma) - (exteriorDifferential(alpha)*beta - alpha * exteriorDifferential(beta)) } $$ 0 $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} Now we define some ``basic operators'' (see \ref{OperatorXmpPage} on page~\pageref{OperatorXmpPage}). \spadcommand{a : BOP := operator('a) } $$ a $$ \returnType{Type: BasicOperator} \spadcommand{b : BOP := operator('b) } $$ b $$ \returnType{Type: BasicOperator} \spadcommand{c : BOP := operator('c) } $$ c $$ \returnType{Type: BasicOperator} We also define some indeterminate one- and two-forms using these operators. \spadcommand{sigma := a(x,y,z) * dx + b(x,y,z) * dy + c(x,y,z) * dz } $$ {{c \left({x, y, z} \right)}\ dz}+ {{b \left({x, y, z} \right)}\ dy}+ {{a \left({x, y, z} \right)}\ dx} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} \spadcommand{theta := a(x,y,z) * dx * dy + b(x,y,z) * dx * dz + c(x,y,z) * dy * dz } $$ {{c \left({x, y, z} \right)}\ dy \ dz}+ {{b \left({x, y, z} \right)}\ dx \ dz}+ {{a \left({x, y, z} \right)}\ dx \ dy} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} This allows us to get formal definitions for the ``gradient'' \ldots \spadcommand{totalDifferential(a(x,y,z))\$der } $$ {{{a \sb {{,3}}} \left({x, y, z} \right)}\ dz}+ {{{a \sb {{,2}}} \left({x, y, z} \right)}\ dy}+ {{{a \sb {{,1}}} \left({x, y, z} \right)}\ dx} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} the ``curl'' \ldots \spadcommand{exteriorDifferential sigma } $$ \begin{array}{@{}l} {{\left( {{c \sb {{,2}}} \left({x, y, z} \right)} -{{b \sb {{,3}}} \left({x, y, z} \right)} \right)}\ dy \ dz}+ \\ \\ \displaystyle {{\left( {{c \sb {{,1}}} \left({x, y, z} \right)} -{{a \sb {{,3}}} \left({x, y, z} \right)} \right)}\ dx \ dz}+ \\ \\ \displaystyle {{\left( {{b \sb {{,1}}} \left({x, y, z} \right)} -{{a \sb {{,2}}} \left({x, y, z} \right)} \right)}\ dx \ dy} \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} and the ``divergence.'' \spadcommand{exteriorDifferential theta } $$ {\left( {{c \sb {{,1}}} \left({x, y, z} \right)} -{{b \sb {{,2}}} \left({x, y, z} \right)}+ {{a\sb {{,3}}} \left({x, y, z} \right)} \right)}\ dx \ dy \ dz $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} Note that the De Rham complex is an algebra with unity. This element {\tt 1} is the basis for elements for zero-forms, that is, functions in our space. \spadcommand{one : der := 1 } $$ 1 $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} To convert a function to a function lying in the De Rham complex, multiply the function by ``one.'' \spadcommand{g1 : der := a([x,t,y,u,v,z,e]) * one } $$ a \left( {x, t, y, u, v, z, e} \right) $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} A current limitation of Axiom forces you to write functions with more than four arguments using square brackets in this way. \spadcommand{h1 : der := a([x,y,x,t,x,z,y,r,u,x]) * one } $$ a \left( {x, y, x, t, x, z, y, r, u, x} \right) $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} Now note how the system keeps track of where your coordinate functions are located in expressions. \spadcommand{exteriorDifferential g1 } $$ \begin{array}{@{}l} {{{a \sb {{,6}}} \left({x, t, y, u, v, z, e} \right)}\ dz}+ \\ \\ \displaystyle {{{a \sb {{,3}}} \left({x, t, y, u, v, z, e} \right)}\ dy}+ \\ \\ \displaystyle {{{a \sb {{,1}}} \left({x, t, y, u, v, z, e} \right)}\ dx} \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} \spadcommand{exteriorDifferential h1 } $$ \begin{array}{@{}l} {{{a \sb {{,6}}} \left({x, y, x, t, x, z, y, r, u, x} \right)}\ dz}+ \\ \\ \displaystyle \begin{array}{@{}l} \left( {{a \sb {{,7}}} \left({x, y, x, t, x, z, y, r, u, x} \right)}+ \right. \\ \\ \displaystyle \left. {{a\sb {{,2}}} \left({x, y, x, t, x, z, y, r, u, x} \right)} \right)\ dy+ \end{array} \\ \\ \displaystyle \begin{array}{@{}l} \left( {{a \sb {{,{10}}}} \left({x, y, x, t, x, z, y, r, u, x} \right)}+ \right. \\ \\ \displaystyle {{a\sb {{,5}}} \left({x, y, x, t, x, z, y, r, u, x} \right)}+ \\ \\ \displaystyle {{a\sb {{,3}}} \left({x, y, x, t, x, z, y, r, u, x} \right)}+ \\ \\ \displaystyle \left. {{a\sb {{,1}}} \left({x, y, x, t, x, z, y, r, u, x} \right)} \right)\ dx \end{array} \end{array} $$ \returnType{Type: DeRhamComplex(Integer,[x,y,z])} In this example of Euclidean three-space, the basis for the De Rham complex consists of the eight forms: {\tt 1}, {\tt dx}, {\tt dy}, {\tt dz}, {\tt dx*dy}, {\tt dx*dz}, {\tt dy*dz}, and {\tt dx*dy*dz}. \spadcommand{coefficient(gamma, dx*dy) } $$ \begin{array}{@{}l} {{\left( {7 \ {z \sp 2} \ {\sin \left({{{x \sp 3} \ {y \sp 2}}} \right)}} -{y \ {z \sp 2} \ {\cos \left({z} \right)}}\right)}\ {\cos \left( {{{\tan \left({{x \ y \ z}} \right)}+ {x\ y \ z}}} \right)}} \\ \\ \displaystyle -{5 \ {x \sp 4} \ {y \sp 2} \ {z \sp 5}}+ {{x \sp 3} \ y \ z} \end{array} $$ \returnType{Type: Expression Integer} \spadcommand{coefficient(gamma, one) } $$ 0 $$ \returnType{Type: Expression Integer} \spadcommand{coefficient(g1,one) } $$ a \left( {x, t, y, u, v, z, e} \right) $$ \returnType{Type: Expression Integer} \section{DecimalExpansion} \label{DecimalExpansionXmpPage} All rationals have repeating decimal expansions. Operations to access the individual digits of a decimal expansion can be obtained by converting the value to {\tt RadixExpansion(10)}. More examples of expansions are available in \ref{BinaryExpansionXmpPage} on page~\pageref{BinaryExpansionXmpPage}, \ref{HexadecimalExpansionXmpPage} on page~\pageref{HexadecimalExpansionXmpPage}, and \ref{RadixExpansionXmpPage} on page~\pageref{RadixExpansionXmpPage}. The operation \spadfunFrom{decimal}{DecimalExpansion} is used to create this expansion of type {\tt DecimalExpansion}. \spadcommand{r := decimal(22/7) } $$ 3.{\overline {142857}} $$ \returnType{Type: DecimalExpansion} Arithmetic is exact. \spadcommand{r + decimal(6/7) } $$ 4 $$ \returnType{Type: DecimalExpansion} The period of the expansion can be short or long \ldots \spadcommand{[decimal(1/i) for i in 350..354] } $$ \begin{array}{@{}l} \left[ {0.{00}{\overline {285714}}}, {0.{\overline {002849}}}, {0.{00284}{\overline {09}}}, {0.{\overline {00283286118980169971671388101983}}}, \right. \\ \\ \displaystyle \left. {0.0{\overline {0282485875706214689265536723163841807909604519774011299435}}} \right] \end{array} $$ \returnType{Type: List DecimalExpansion} or very long. \spadcommand{decimal(1/2049) } $$ \begin{array}{@{}l} 0.{\overline {000488042947779404587603709126403123474865788189360663738408979990239}} \\ \\ \displaystyle \ \ {\overline{ 141044411908247925817471937530502684236212786725231820400195217179111}} \\ \\ \displaystyle \ \ {\overline{ 761835041483650561249389946315275744265495363591996095656417764763299}} \\ \\ \displaystyle \ \ {\overline{ 170326988775012201073694485114690092728160078086871644704734016593460}} \\ \\ \displaystyle \ \ {\overline{ 22449975597852611029770619814543679843826256710590531966813079551}} \end{array} $$ \returnType{Type: DecimalExpansion} These numbers are bona fide algebraic objects. \spadcommand{p := decimal(1/4)*x**2 + decimal(2/3)*x + decimal(4/9) } $$ {{0.{25}} \ {x \sp 2}}+{{0.{\overline 6}} \ x}+{0.{\overline 4}} $$ \returnType{Type: Polynomial DecimalExpansion} \spadcommand{q := differentiate(p, x) } $$ {{0.5} \ x}+{0.{\overline 6}} $$ \returnType{Type: Polynomial DecimalExpansion} \spadcommand{g := gcd(p, q) } $$ x+{1.{\overline 3}} $$ \returnType{Type: Polynomial DecimalExpansion} \section{DistributedMultivariatePolynomial} \label{DistributedMultivariatePolynomialXmpPage} \hyphenation{Homo-gen-eous-Dis-tributed-Multi-var-i-ate-Pol-y-nomial} {\tt DistributedMultivariatePolynomial} which is abbreviated as {\tt DMP} and {\tt HomogeneousDistributedMultivariatePolynomial}, which is abbreviated as {\tt HDMP}, are very similar to {\tt MultivariatePolynomial} except that they are represented and displayed in a non-recursive manner. \spadcommand{(d1,d2,d3) : DMP([z,y,x],FRAC INT) } \returnType{Type: Void} The constructor {\tt DMP} orders its monomials lexicographically while {\tt HDMP} orders them by total order refined by reverse lexicographic order. \spadcommand{d1 := -4*z + 4*y**2*x + 16*x**2 + 1 } $$ -{4 \ z}+{4 \ {y \sp 2} \ x}+{{16} \ {x \sp 2}}+1 $$ \returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)} \spadcommand{d2 := 2*z*y**2 + 4*x + 1 } $$ {2 \ z \ {y \sp 2}}+{4 \ x}+1 $$ \returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)} \spadcommand{d3 := 2*z*x**2 - 2*y**2 - x } $$ {2 \ z \ {x \sp 2}} -{2 \ {y \sp 2}} -x $$ \returnType{Type: DistributedMultivariatePolynomial([z,y,x],Fraction Integer)} These constructors are mostly used in Gr\"{o}bner basis calculations. \spadcommand{groebner [d1,d2,d3] } $$ \begin{array}{@{}l} \left[ {z - {{{1568} \over {2745}} \ {x \sp 6}} - {{{1264} \over {305}} \ {x \sp 5}}+ {{6 \over {305}} \ {x \sp 4}}+ {{{182} \over {549}} \ {x \sp 3}} -{{{2047} \over {610}} \ {x \sp 2}} - {{{103} \over {2745}} \ x} - {{2857} \over {10980}}}, \right. \\ \\ \displaystyle {{y \sp 2}+ {{{112} \over {2745}} \ {x \sp 6}} - {{{84} \over {305}} \ {x \sp 5}} - {{{1264} \over {305}} \ {x \sp 4}} - {{{13} \over {549}} \ {x \sp 3}}+ {{{84} \over {305}} \ {x \sp 2}}+ {{{1772} \over {2745}} \ x}+ {2 \over {2745}}}, \\ \\ \displaystyle \left. {{x \sp 7}+ {{{29} \over 4} \ {x \sp 6}} - {{{17} \over {16}} \ {x \sp 4}} - {{{11} \over 8} \ {x \sp 3}}+ {{1 \over {32}} \ {x \sp 2}}+ {{{15} \over {16}} \ x}+ {1 \over 4}} \right] \end{array} $$ \returnType{Type: List DistributedMultivariatePolynomial([z,y,x],Fraction Integer)} \spadcommand{(n1,n2,n3) : HDMP([z,y,x],FRAC INT) } \returnType{Type: Void} \spadcommand{n1 := d1 } $$ {4 \ {y \sp 2} \ x}+{{16} \ {x \sp 2}} -{4 \ z}+1 $$ \returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)} \spadcommand{n2 := d2 } $$ {2 \ z \ {y \sp 2}}+{4 \ x}+1 $$ \returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)} \spadcommand{n3 := d3 } $$ {2 \ z \ {x \sp 2}} -{2 \ {y \sp 2}} -x $$ \returnType{Type: HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)} Note that we get a different Gr\"{o}bner basis when we use the {\tt HDMP} polynomials, as expected. \spadcommand{groebner [n1,n2,n3] } $$ \begin{array}{@{}l} \left[ {{y \sp 4}+ {2 \ {x \sp 3}} - {{3 \over 2} \ {x \sp 2}}+ {{1 \over 2} \ z} - {1 \over 8}}, \right. \\ \\ \displaystyle {{x \sp 4}+ {{{29} \over 4} \ {x \sp 3}} - {{1 \over 8} \ {y \sp 2}} - {{7 \over 4} \ z \ x} - {{9 \over {16}} \ x} - {1 \over 4}}, \\ \\ \displaystyle {{z \ {y \sp 2}}+ {2 \ x}+ {1 \over 2}}, \\ \\ \displaystyle {{{y \sp 2} \ x}+ {4 \ {x \sp 2}} - z+ {1 \over 4}}, \\ \\ \displaystyle {{z \ {x \sp 2}} - {y \sp 2} - {{1 \over 2} \ x}}, \\ \\ \displaystyle \left. {{z \sp 2} - {4 \ {y \sp 2}}+ {2 \ {x \sp 2}} - {{1 \over 4} \ z} - {{3 \over 2} \ x}} \right] \end{array} $$ \returnType{Type: List HomogeneousDistributedMultivariatePolynomial([z,y,x],Fraction Integer)} {\tt GeneralDistributedMultivariatePolynomial} is somewhat more flexible in the sense that as well as accepting a list of variables to specify the variable ordering, it also takes a predicate on exponent vectors to specify the term ordering. With this polynomial type the user can experiment with the effect of using completely arbitrary term orderings. This flexibility is mostly important for algorithms such as Gr\"{o}bner basis calculations which can be very sensitive to term ordering. For more information on related topics, see \ref{ugIntroVariablesPage} on page~\pageref{ugIntroVariablesPage} in Section \ref{ugIntroVariablesNumber} on page~\pageref{ugIntroVariablesNumber}, \ref{ugTypesConvertPage} on page~\pageref{ugTypesConvertPage} in Section \ref{ugTypesConvertNumber} on page~\pageref{ugTypesConvertNumber}, \ref{PolynomialXmpPage} on page~\pageref{PolynomialXmpPage}, \ref{UnivariatePolynomialXmpPage} on page~\pageref{UnivariatePolynomialXmpPage}, and \ref{MultivariatePolynomialXmpPage} on page~\pageref{MultivariatePolynomialXmpPage}. \section{DoubleFloat} \label{DoubleFloatXmpPage} Axiom provides two kinds of floating point numbers. The domain {\tt Float} (abbreviation {\tt FLOAT}) implements a model of arbitrary precision floating point numbers. The domain {\tt DoubleFloat} (abbreviation {\tt DFLOAT}) is intended to make available hardware floating point arithmetic in Axiom. The actual model of floating point {\tt DoubleFloat} that provides is system-dependent. For example, on the IBM system 370 Axiom uses IBM double precision which has fourteen hexadecimal digits of precision or roughly sixteen decimal digits. Arbitrary precision floats allow the user to specify the precision at which arithmetic operations are computed. Although this is an attractive facility, it comes at a cost. Arbitrary-precision floating-point arithmetic typically takes twenty to two hundred times more time than hardware floating point. The usual arithmetic and elementary functions are available for {\tt DoubleFloat}. Use {\tt )show DoubleFloat} to get a list of operations or the HyperDoc browse facility to get more extensive documentation about {\tt DoubleFloat}. By default, floating point numbers that you enter into Axiom are of type {\tt Float}. \spadcommand{2.71828} $$ 2.71828 $$ \returnType{Type: Float} You must therefore tell Axiom that you want to use {\tt DoubleFloat} values and operations. The following are some conservative guidelines for getting Axiom to use {\tt DoubleFloat}. To get a value of type {\tt DoubleFloat}, use a target with {\tt @}, \ldots \spadcommand{2.71828@DoubleFloat} $$ 2.71828 $$ \returnType{Type: DoubleFloat} a conversion, \ldots \spadcommand{2.71828 :: DoubleFloat} $$ 2.71828 $$ \returnType{Type: DoubleFloat} or an assignment to a declared variable. It is more efficient if you use a target rather than an explicit or implicit conversion. \spadcommand{eApprox : DoubleFloat := 2.71828 } $$ 2.71828 $$ \returnType{Type: DoubleFloat} You also need to declare functions that work with {\tt DoubleFloat}. \spadcommand{avg : List DoubleFloat -> DoubleFloat } \returnType{Type: Void} \begin{verbatim} avg l == empty? l => 0 :: DoubleFloat reduce(_+,l) / #l \end{verbatim} \returnType{Type: Void} %\spadcommand{avg [] } % this complains but succeeds \spadcommand{avg [3.4,9.7,-6.8] } \begin{verbatim} Compiling function avg with type List Float -> DoubleFloat \end{verbatim} $$ 2.1 $$ \returnType{Type: DoubleFloat} Use package-calling for operations from {\tt DoubleFloat} unless the arguments themselves are already of type {\tt DoubleFloat}. \spadcommand{cos(3.1415926)\$DoubleFloat} $$ -{0.999999999999999} $$ \returnType{Type: DoubleFloat} \spadcommand{cos(3.1415926 :: DoubleFloat)} $$ -{0.999999999999999} $$ \returnType{Type: DoubleFloat} By far, the most common usage of {\tt DoubleFloat} is for functions to be graphed. For more information about Axiom's numerical and graphical facilities, see Section \ref{ugGraph} on page~\pageref{ugGraph}, \ref{ugProblemNumeric} on page~\pageref{ugProblemNumeric}, and \ref{FloatXmpPage} on page~\pageref{FloatXmpPage}. \section{EqTable} \label{EqTableXmpPage} The {\tt EqTable} domain provides tables where the keys are compared using \spadfunFrom{eq?}{EqTable}. Keys are considered equal only if they are the same instance of a structure. This is useful if the keys are themselves updatable structures. Otherwise, all operations are the same as for type {\tt Table}. See \ref{TableXmpPage} on page~\pageref{TableXmpPage} for general information about tables. The operation \spadfunFrom{table}{EqTable} is here used to create a table where the keys are lists of integers. \spadcommand{e: EqTable(List Integer, Integer) := table() } $$ table() $$ \returnType{Type: EqTable(List Integer,Integer)} These two lists are equal according to \spadopFrom{=}{List}, but not according to \spadfunFrom{eq?}{List}. \spadcommand{l1 := [1,2,3] } $$ \left[ 1, 2, 3 \right] $$ \returnType{Type: List PositiveInteger} \spadcommand{l2 := [1,2,3] } $$ \left[ 1, 2, 3 \right] $$ \returnType{Type: List PositiveInteger} Because the two lists are not \spadfunFrom{eq?}{List}, separate values can be stored under each. \spadcommand{e.l1 := 111 } $$ 111 $$ \returnType{Type: PositiveInteger} \spadcommand{e.l2 := 222 } $$ 222 $$ \returnType{Type: PositiveInteger} \spadcommand{e.l1} $$ 111 $$ \returnType{Type: PositiveInteger} \section{Equation} \label{EquationXmpPage} The {\tt Equation} domain provides equations as mathematical objects. These are used, for example, as the input to various \spadfunFrom{solve}{TransSolvePackage} operations. Equations are created using the equals symbol, \spadopFrom{=}{Equation}. \spadcommand{eq1 := 3*x + 4*y = 5 } $$ {{4 \ y}+{3 \ x}}=5 $$ \returnType{Type: Equation Polynomial Integer} \spadcommand{eq2 := 2*x + 2*y = 3 } $$ {{2 \ y}+{2 \ x}}=3 $$ \returnType{Type: Equation Polynomial Integer} The left- and right-hand sides of an equation are accessible using the operations \spadfunFrom{lhs}{Equation} and \spadfunFrom{rhs}{Equation}. \spadcommand{lhs eq1 } $$ {4 \ y}+{3 \ x} $$ \returnType{Type: Polynomial Integer} \spadcommand{rhs eq1 } $$ 5 $$ \returnType{Type: Polynomial Integer} Arithmetic operations are supported and operate on both sides of the equation. \spadcommand{eq1 + eq2 } $$ {{6 \ y}+{5 \ x}}=8 $$ \returnType{Type: Equation Polynomial Integer} \spadcommand{eq1 * eq2 } $$ {{8 \ {y \sp 2}}+{{14} \ x \ y}+{6 \ {x \sp 2}}}={15} $$ \returnType{Type: Equation Polynomial Integer} \spadcommand{2*eq2 - eq1 } $$ x=1 $$ \returnType{Type: Equation Polynomial Integer} Equations may be created for any type so the arithmetic operations will be defined only when they make sense. For example, exponentiation is not defined for equations involving non-square matrices. \spadcommand{eq1**2 } $$ {{{16} \ {y \sp 2}}+{{24} \ x \ y}+{9 \ {x \sp 2}}}={25} $$ \returnType{Type: Equation Polynomial Integer} Note that an equals symbol is also used to {\it test} for equality of values in certain contexts. For example, {\tt x+1} and {\tt y} are unequal as polynomials. \spadcommand{if x+1 = y then "equal" else "unequal"} $$ \mbox{\tt "unequal"} $$ \returnType{Type: String} \spadcommand{eqpol := x+1 = y } $$ {x+1}=y $$ \returnType{Type: Equation Polynomial Integer} If an equation is used where a {\tt Boolean} value is required, then it is evaluated using the equality test from the operand type. \spadcommand{if eqpol then "equal" else "unequal" } $$ \mbox{\tt "unequal"} $$ \returnType{Type: String} If one wants a {\tt Boolean} value rather than an equation, all one has to do is ask! \spadcommand{eqpol::Boolean } $$ {\tt false} $$ \returnType{Type: Boolean} \section{Exit} \label{ExitXmpPage} A function that does not return directly to its caller has {\tt Exit} as its return type. The operation {\tt error} is an example of one which does not return to its caller. Instead, it causes a return to top-level. \spadcommand{n := 0 } $$ 0 $$ \returnType{Type: NonNegativeInteger} The function {\tt gasp} is given return type {\tt Exit} since it is guaranteed never to return a value to its caller. \begin{verbatim} gasp(): Exit == free n n := n + 1 error "Oh no!" Function declaration gasp : () -> Exit has been added to workspace. \end{verbatim} \returnType{Type: Void} The return type of {\tt half} is determined by resolving the types of the two branches of the {\tt if}. \begin{verbatim} half(k) == if odd? k then gasp() else k quo 2 \end{verbatim} Because {\tt gasp} has the return type {\tt Exit}, the type of {\tt if} in {\tt half} is resolved to be {\tt Integer}. \spadcommand{half 4 } \begin{verbatim} Compiling function gasp with type () -> Exit Compiling function half with type PositiveInteger -> Integer \end{verbatim} $$ 2 $$ \returnType{Type: PositiveInteger} \spadcommand{half 3 } \begin{verbatim} Error signalled from user code in function gasp: Oh no! \end{verbatim} \spadcommand{n } $$ 1 $$ \returnType{Type: NonNegativeInteger} For functions which return no value at all, use {\tt Void}. See \ref{ugUserPage} on page~\pageref{ugUserPage} in Section \ref{ugUserNumber} on page~\pageref{ugUserNumber} and \ref{VoidXmpPage} on page~\pageref{VoidXmpPage} for more information. \section{Expression} \label{ExpressionXmpPage} {\tt Expression} is a constructor that creates domains whose objects can have very general symbolic forms. Here are some examples: This is an object of type {\tt Expression Integer}. \spadcommand{sin(x) + 3*cos(x)**2} $$ {\sin \left({x} \right)}+{3\ {{\cos \left({x} \right)}\sp 2}} $$ \returnType{Type: Expression Integer} This is an object of type {\tt Expression Float}. \spadcommand{tan(x) - 3.45*x} $$ {\tan \left({x} \right)}-{{3.45} \ x} $$ \returnType{Type: Expression Float} This object contains symbolic function applications, sums, products, square roots, and a quotient. \spadcommand{(tan sqrt 7 - sin sqrt 11)**2 / (4 - cos(x - y))} $$ {-{{\tan \left({{\sqrt {7}}} \right)}\sp 2}+ {2 \ {\sin \left({{\sqrt {{11}}}} \right)} \ {\tan \left({{\sqrt {7}}} \right)}} -{{\sin \left({{\sqrt {{11}}}} \right)}\sp 2}} \over {{\cos \left({{y -x}} \right)} -4} $$ \returnType{Type: Expression Integer} As you can see, {\tt Expression} actually takes an argument domain. The {\it coefficients} of the terms within the expression belong to the argument domain. {\tt Integer} and {\tt Float}, along with {\tt Complex Integer} and {\tt Complex Float} are the most common coefficient domains. The choice of whether to use a {\tt Complex} coefficient domain or not is important since Axiom can perform some simplifications on real-valued objects \spadcommand{log(exp x)@Expression(Integer)} $$ x $$ \returnType{Type: Expression Integer} ... which are not valid on complex ones. \spadcommand{log(exp x)@Expression(Complex Integer)} $$ \log \left({{e \sp x}} \right) $$ \returnType{Type: Expression Complex Integer} Many potential coefficient domains, such as {\tt AlgebraicNumber}, are not usually used because {\tt Expression} can subsume them. \spadcommand{sqrt 3 + sqrt(2 + sqrt(-5)) } $$ {\sqrt {{{\sqrt {-5}}+2}}}+{\sqrt {3}} $$ \returnType{Type: AlgebraicNumber} \spadcommand{\% :: Expression Integer } $$ {\sqrt {{{\sqrt {-5}}+2}}}+{\sqrt {3}} $$ \returnType{Type: Expression Integer} Note that we sometimes talk about ``an object of type {\tt Expression}.'' This is not really correct because we should say, for example, ``an object of type {\tt Expression Integer}'' or ``an object of type {\tt Expression Float}.'' By a similar abuse of language, when we refer to an ``expression'' in this section we will mean an object of type {\tt Expression R} for some domain {\tt R}. The Axiom documentation contains many examples of the use of {\tt Expression}. For the rest of this section, we'll give you some pointers to those examples plus give you some idea of how to manipulate expressions. It is important for you to know that {\tt Expression} creates domains that have category {\tt Field}. Thus you can invert any non-zero expression and you shouldn't expect an operation like {\tt factor} to give you much information. You can imagine expressions as being represented as quotients of ``multivariate'' polynomials where the ``variables'' are kernels (see \ref{KernelXmpPage} on page~\pageref{KernelXmpPage}). A kernel can either be a symbol such as {\tt x} or a symbolic function application like {\tt sin(x + 4)}. The second example is actually a nested kernel since the argument to {\tt sin} contains the kernel {\tt x}. \spadcommand{height mainKernel sin(x + 4)} $$ 2 $$ \returnType{Type: PositiveInteger} Actually, the argument to {\tt sin} is an expression, and so the structure of {\tt Expression} is recursive. \ref{KernelXmpPage} on page~\pageref{KernelXmpPage} demonstrates how to extract the kernels in an expression. Use the HyperDoc Browse facility to see what operations are applicable to expression. At the time of this writing, there were 262 operations with 147 distinct name in {\tt Expression Integer}. For example, \spadfunFrom{numer}{Expression} and \spadfunFrom{denom}{Expression} extract the numerator and denominator of an expression. \spadcommand{e := (sin(x) - 4)**2 / ( 1 - 2*y*sqrt(- y) ) } $$ {-{{\sin \left({x} \right)}\sp 2}+ {8 \ {\sin \left({x} \right)}} -{16}} \over {{2 \ y \ {\sqrt {-y}}} -1} $$ \returnType{Type: Expression Integer} \spadcommand{numer e } $$ -{{\sin \left({x} \right)}\sp 2}+ {8 \ {\sin \left({x} \right)}} -{16} $$ \returnType{Type: SparseMultivariatePolynomial(Integer,Kernel Expression Integer)} \spadcommand{denom e } $$ {2 \ y \ {\sqrt {-y}}} -1 $$ \returnType{Type: SparseMultivariatePolynomial(Integer,Kernel Expression Integer)} Use \spadfunFrom{D}{Expression} to compute partial derivatives. \spadcommand{D(e, x) } $$ {{{\left( {4 \ y \ {\cos \left({x} \right)}\ {\sin \left({x} \right)}}- {{16} \ y \ {\cos \left({x} \right)}}\right)}\ {\sqrt {-y}}} - {2 \ {\cos \left({x} \right)}\ {\sin \left({x} \right)}}+ {8\ {\cos \left({x} \right)}}} \over {{4 \ y \ {\sqrt {-y}}}+{4 \ {y \sp 3}} -1} $$ \returnType{Type: Expression Integer} See \ref{ugIntroCalcDerivPage} on page~\pageref{ugIntroCalcDerivPage} in Section \ref{ugIntroCalcDerivNumber} on page~\pageref{ugIntroCalcDerivNumber} for more examples of expressions and derivatives. \spadcommand{D(e, [x, y], [1, 2]) } $$ \left( \begin{array}{@{}l} {{\left( {{\left( -{{2304} \ {y \sp 7}}+{{960} \ {y \sp 4}} \right)} \ {\cos \left({x} \right)}\ {\sin \left({x} \right)}}+ {{\left({{9216} \ {y \sp 7}} -{{3840} \ {y \sp 4}} \right)} \ {\cos \left({x} \right)}}\right)}\ {\sqrt {-y}}}+ \\ \\ \displaystyle {{\left( -{{960} \ {y \sp 9}}+{{2160} \ {y \sp 6}} -{{180} \ {y \sp 3}} -3 \right)}\ {\cos \left({x} \right)}\ {\sin \left({x} \right)}}+ \\ \\ \displaystyle {{\left( {{3840} \ {y \sp 9}} -{{8640} \ {y \sp 6}}+{{720} \ {y \sp 3}}+{12} \right)}\ {\cos \left({x} \right)}} \end{array} \right) \over \left( \begin{array}{@{}l} {{\left( {{256} \ {y \sp {12}}} -{{1792} \ {y \sp 9}}+{{1120} \ {y \sp 6}} -{{112} \ {y \sp 3}}+1 \right)}\ {\sqrt {-y}}} - \\ \\ \displaystyle {{1024} \ {y \sp {11}}}+{{1792} \ {y \sp 8}} -{{448} \ {y \sp 5}}+{{16} \ {y \sp 2}} \end{array} \right) $$ \returnType{Type: Expression Integer} See \ref{ugIntroCalcLimitsPage} on page~\pageref{ugIntroCalcLimitsPage} in Section \ref{ugIntroCalcLimitsNumber} on page~\pageref{ugIntroCalcLimitsNumber} and \ref{ugIntroSeriesPage} on page~\pageref{ugIntroSeriesPage} in Section \ref{ugIntroSeriesNumber} on page~\pageref{ugIntroSeriesNumber} for more examples of expressions and calculus. Differential equations involving expressions are discussed in \ref{ugProblemDEQPage} on page~\pageref{ugProblemDEQPage} in Section \ref{ugProblemDEQNumber} on page~\pageref{ugProblemDEQNumber}. Chapter 8 has many advanced examples: see \ref{ugProblemIntegrationPage} on page~\pageref{ugProblemIntegrationPage} in Section \ref{ugProblemIntegrationNumber} on page~\pageref{ugProblemIntegrationNumber} for a discussion of Axiom's integration facilities. When an expression involves no ``symbol kernels'' (for example, {\tt x}), it may be possible to numerically evaluate the expression. If you suspect the evaluation will create a complex number, use {\tt complexNumeric}. \spadcommand{complexNumeric(cos(2 - 3*\%i))} $$ -{4.1896256909\ 688072301}+{{9.1092278937\ 55336598} \ i} $$ \returnType{Type: Complex Float} If you know it will be real, use {\tt numeric}. \spadcommand{numeric(tan 3.8)} $$ 0.7735560905\ 0312607286 $$ \returnType{Type: Float} The {\tt numeric} operation will display an error message if the evaluation yields a calue with an non-zero imaginary part. Both of these operations have an optional second argument {\tt n} which specifies that the accuracy of the approximation be up to {\tt n} decimal places. When an expression involves no ``symbolic application'' kernels, it may be possible to convert it a polynomial or rational function in the variables that are present. \spadcommand{e2 := cos(x**2 - y + 3) } $$ \cos \left({{y -{x \sp 2} -3}} \right) $$ \returnType{Type: Expression Integer} \spadcommand{e3 := asin(e2) - \%pi/2 } $$ -y+{x \sp 2}+3 $$ \returnType{Type: Expression Integer} \spadcommand{e3 :: Polynomial Integer } $$ -y+{x \sp 2}+3 $$ \returnType{Type: Polynomial Integer} This also works for the polynomial types where specific variables and their ordering are given. \spadcommand{e3 :: DMP([x, y], Integer) } $$ {x \sp 2} -y+3 $$ \returnType{Type: DistributedMultivariatePolynomial([x,y],Integer)} Finally, a certain amount of simplication takes place as expressions are constructed. \spadcommand{sin \%pi} $$ 0 $$ \returnType{Type: Expression Integer} \spadcommand{cos(\%pi / 4)} $$ {\sqrt {2}} \over 2 $$ \returnType{Type: Expression Integer} For simplications that involve multiple terms of the expression, use {\tt simplify}. \spadcommand{tan(x)**6 + 3*tan(x)**4 + 3*tan(x)**2 + 1 } $$ {{\tan