Computational objects

## 3 Computational objects

### 3.1 Numbers

Operations
+ | addition
- | subtraction
* | multiplication
/ | division
^ | power

Conversions
evalf | approximate a number
exact | find an exact number close to the given number
epsilon | determine how close a fraction has to be to a floating point number to be returned by exact

Constants
pi | π≃ 3.14159265359
e | e ≃ 2.71828182846
i | i=√−1
infinity or inf | ∞
+infinity or +inf | +∞
-infinity or -inf | −∞

There are two types of numbers in Xcas, approximate and exact.

Computer programs like Xcas regard floating point numbers, which are numbers displayed with decimal points, as approximations. Other numbers will be regarded as exact. For example, the number 2 is exactly 2, while 2.0 represents a number that equals 2 to within the current precision, which by default is about 12 significant digits (see section 2.3, “Configuration”). Approximate numbers can be entered by typing in a number with a decimal point or in scientific notation (which is a decimal number followed by e and then an integer, where the integer represents the power of 10). So 2000.0, 2e3 and 2.0e3 all represent the same approximate number.

Exact numbers are integers, symbolic constants (like e and π), and numeric expressions which only involve exact numbers. For example, sin(1) will be exact, and so won’t be given a decimal approximation; if you enter

> sin(1)

you will get

sin(1)

However, sin(1.0) involves the approximate number 1.0, and so will be regarded as approximate itself. If you enter

> sin(1.0)

you will get

0.841470984808

As with many computer languages, if you enter an integer beginning with the digit 0, the Xcas will regard it as an integer base 8; if you enter

> 011

you will get

9

since 11 is the base 8 representation of the decimal number 9. Similarly, if you write 0x at the beginning of an integer, Xcas will regard it as a hexadecimal (base 16) integer. If you enter

> 0x11

you will get

17

since 11 is the base 16 representation of the decimal number 17.

The symbolic constants that are built in to Xcas are pi, e, i, infinity, +infinity and -infinity. Note that Xcas distinguishes between +infinity, -infinity and infinity, which is unsigned infinity. The distinction can be noted in the following calculations:

> 1/0

will result in infinity,

∞

while

> (1/0)^2

will result in +infinity,

+∞

and

> -(1/0)^2

will result in -infinity,

−∞

These variables cannot be reassigned; in particular, the variable i can’t be used as a loop index.

Xcas can handle integers of arbitrary length; if, for example, you enter

> 500!

you will be given all 1135 digits of the factorial of 500.

When Xcas combines two numbers, the result will be exact unless one of the numbers is approximate, in which case the result will be approximate. For example, entering

> 3/2 + 1

will return the exact value

5
2

while entering

> 1.5 + 1

will return

2.5

The evalf function will transform a number to an approximate value. While entering

> sqrt(2)

will return

| √ |
2

entering

> evalf(sqrt(2))

will return

1.41421356237

which is the square root of two to the default precision, in this case 12 digits. The evalf function can also take a second argument which you can use to specify how many digits of precision that you want; for example if you want to know the square root of two to 50 digits, you can enter

> evalf(sqrt(2),50)

and get

1.4142135623730950488016887242096980785696718753770

The exact function will turn an approximate value into a nearby exact value. Specifically, given an approximate value x, exact(x) will be a rational number r with |x − r| < є, where є is the value of the variable epsilon, which has a default value of 10−12. This value is configurable (see section 2.3, “Configuration”).

### 3.2 Variables

Variables
:= | assignment
subst | give a variable a value for a single instance
assume | put assumptions on variables
and | combine assumptions
or | combine assumptions
purge | remove values and assumptions attached to variables

A variable in Xcas begins with a letter and can contain letters, numbers and underscores.

A variable can be given a value with the assignment operator :=. If you enter

> a := 3

then a will be replaced by 3 in all later calculations. If you later enter

> 4*a^2

you will get

36

The purge command will unassign a variable; if you enter

> purge(a)

and then

> 4*a^2

you will get

4· a2

The assignment operator := is one of three types of equalities used in Xcas. They are

- The assignment operator, :=, which is used to assign values.
- The Boolean equality, ==, which tells you whether two quantities are equal to each other or not. If you enter A==B, then you will get either true or false as a result. The predefined constants true and True are equal to 1, the predefined constants false and False are equal to 0.
- The equal sign = is used to define an equation. In this case, the equation will be the expression.

If you want to replace a variable by a value for a single expression, you can use the subst command. This command takes an expression and an equation var = value as a second argument. If a is an unassigned variable, for example, then entering

> subst(a^2 + 2, a=3)

will result in

11

Afterwards, a will still be unassigned.

Even without giving a variable a value, you can still tell Xcas some of its properties with the assume command. For example, for a real number a, the expression √a2 simplifies to |a|, since a could be positive or negative. If you enter

> sqrt(a^2)

you will get

|a|

If you enter

> assume(a<0)

beforehand, then Xcas will work under the assumption that a is negative, and so entering

> sqrt(a^2)

will result in

−a

As well as assuming that a variable satifies an equation or inequality, you can use the keywords and and or to assume that a variable satisifies more than one inequality. Some assumptions on a variable require a second argument; for example, to assume that a is an integer you can enter

> assume(a,integer)

Afterwards

> sin(a*pi)

will result in

0

The purge command will remove any assumptions about a variable as well as any assigned values.

### 3.3 Expressions

Conversions
expand | expand powers and distribute multiplication
normal | reduce to lowest terms
ratnormal | reduce to lowest terms
factor | factor
simplify | reduce an expression to simpler form
tsimplify | reduce and expression to simpler form
convert | convert an expression to a different type

An expression is a combination of numbers and variables combined by arithmetic operators. For example, x^2 + 2*x + c is an expression.

When you enter an expression, Xcas will perform some automatic simplifications, such as

- Any variables that have been assigned are replaced by their values.
- Operations on numbers are performed.
- Trivial simplifications, such as x+0=x and x· 0 = 0, are made.
- Some trigonometric forms are rewritten; for example, cos(-x) is replaced by cos(x) and cos(pi/4) is replaced by √2/2.

Other simplifications are not done automatically, since it isn’t always clear what sort of simplifications the user might want, and besides non-trivial simplifications are time-consuming. The most used commands for simplifying and transforming commands are:

expand
  This will expand integer powers and more generally distribute multiplication across addition. For example, if you enter

  > expand((x+1)^3)

  you will get

  x3 + 3*x2 + 3*x + 1

normal and ratnormal
  These commands will reduce a rational function to lowest terms. For example, if you enter

  > normal((x^3-1)/(x^2-1))

  then Xcas will cancel a common factor of x−1 from the top and bottom and return

  x2+x+1
  x+1

  ratnormal will have the same behavior on this expression. The difference between the two commands is that ratnormal does not take into account reductions with algebraic numbers, while normal does. If you enter

  > ratnormal((x^2-2)/(x-sqrt(2)))

  you will get

  x2−2
  x− | √ |
  2

  but if you enter

  > normal((x^2-2)/(x-sqrt(2)))

  you will get

  x+ | √ |
  2

  Neither of these commands will take into account relationships between transcendental functions such as sin and cos.

factor
  This will factor polynomials and reduce rational expressions. This is a little slower than normal and ratnormal and different in that it will give the result in factored form. For example, if you enter

  > factor(x^2 + 3*x + 2)

  you will get

  (x + 1)*(x + 2)

simplify
  This command will try to reduce an expression to algebraically independent variables, then it will apply normal. Simplifications requiring algebraic extensions (such as roots) may require two calls to simplify and possibly adding some assumptions with assume.
tsimplify
  Like simplify, this will try to reduce an expression to algebraically independent variables, but will not apply normal afterwards.

The convert command will rewrite expressions to different formats; the first argument will be the expression and the second argument will indicate the format to convert the expression to. For example, you can convert ei θ to sines and cosines with

> convert(exp(i*theta),sincos)

the result will be

cos(θ) + i*sin(θ)

You can use convert to find the partial fraction decomposition of a rational expression with a second argument of partfrac; for example, if you enter

> convert((x-1)/(x^2 - x -2), partfrac)

you will get

2
(x+1)*3
| + |
1
(x−2)*3

### 3.4 Functions

Common functions
abs | absolute value
sign | sign (-1,0,+1)
max | maximum
min | minimum
round | round to the nearest integer
floor | greatest integer less than or equal to
frac | fractional part
ceil | least integer greater than or equal to
re | real part
im | imaginary part
abs | absolute value
arg | argument
conj | conjugate
coordinates | the coordinates of a point
factorial | factorial
! | factorial
sqrt | square root
exp | exponential
log | natural logarithm
ln | natural logarithm
log10 | logarithm base 10
sin | sine
cos | cosine
tan | tangent
cot | cotangent
asin | arcsine
acos | arccosine
atan | arctangent
sinh | hyperbolic sine
cosh | hyperbolic cosine
tanh | hyperbolic tangent
asinh | inverse hyperbolic sine
acosh | inverse hyperbolic cosine
atanh | inverse hyperbolic tangent

Create functions
:= | assign an expression to a function
-> | define a function
unapply | turn an expression into a function

Xcas has many built in functions; you can get a complete list with the help index. You can also define your own functions with the assignment (:=) operator. To define a function f given by f(x) = x*exp(x), for example, you can enter

> f(x) := x*exp(x)

Note that in this case the name of the function is f; f(x) is the value of the function evaluated at x. The function is a rule which takes an input x and returns x*exp(x). This rule can be written without giving it a name as x -> x*exp(x). In fact, another way you can define the function f as above is

> f := x ->x*exp(x)

In either case, if you enter

> f(2)

you will get

2*exp(2)

You can similarly define functions of more than one variable. For example, to convert polar coordinates to rectangular coordinates, you could define

> p(r,theta) := (r*cos(theta), r*sin(theta))

or equivalently

> p := (r, theta) -> (r*cos(theta),r*sin(theta))

The unapply command will transform an expression into a function. It takes as arguments an expression and a variable, it will return the function defined by the expression. If you enter

> unapply(x*exp(x),x)

you will get

x −>x*exp(x)

The unapply command will return the function written in terms of built in functions; for example, for the function f defined above, if you enter

> unapply(f(x),x)

you will also get

x −>x*exp(x)

You can define a function in terms of a function that you previously defined, but it’s probably better to define any new functions in terms of built-in functions. For example, if you define

> f(x) := exp(x)*sin(x)

you can define a new function

> g(x) := x*f(x)

but it might be better to write

> g(x) := x*exp(x)*sin(x)

Perhaps a better alternative is to use unapply; you can define g by g := unapply(x*f(x),x)

In some cases, it will be necessary to use unapply to define a function. For example (see section 4.1, “Derivatives”), the diff command will find the derivative of an expression; if you enter

> diff(x*sin(x),x)

you will get

sin(x) + x * cos(x)

However, you cannot simply define a function g(x) := diff(x*sin(x),x) if you tried to do this, then evaluating g(0) for example would give you diff(0*sin(0),0), which is not what you want. Instead, you could define g by

> g := unapply(diff(x*sin(x),x)

Another case where you need to use unapply to define a function is when you have a function of two variables and you want to use it to define a function of one variable, where the other variable is a parameter. For example, consider the polar coordinate function

> p(r,theta) := (r*cos(theta), r*sin(theta))

If you want to use this to define C(r) as a function of θ for any value of r, you cannot simply define it as

> C(r) := p(r,theta)

Doing this will define C(r) as an expression involving θ, not a function of θ. Entering

> C(1)(pi/4)

would be the same as

> (cos(theta),sin(theta))(pi/4)

which is not what you want. To define C(r), you would have to use unapply:

> C(r) := unapply(p(r,theta),theta)

The necessity of using unapply in these cases is because when you define a function, the right hand side of the assignment is not evaluated. For example, if you try to define the squaring function by

> sq := x^2

> f(x) := sq

it will not work; if you enter f(5), for example, it will get the value sq, which will then be replaced by its value. You will end up getting x^2 and not 5^2. You should either define the function f by

> f(x) := x^2

or perhaps

> f := unapply(sq,x)

Functions (not just expressions) can be added and multiplied. To define a function which is the sine function times the exponential, instead of defining f(x) as the expression sin(x)*exp(x), you could simply enter

> f := sin*exp

Functions can also be composed with the @ symbol. For example, if you define functions f and g by

> f(x) := x^2 + 1

> g(x) := sin(x)

then

> f @ g

will result in

x −>(sin(x))2 + 1

You can use the @ operator to compose a function with itself; f@f(x) is the same as f(f(x)), but if you want to compose a function with itself several times, you can use the @@ operator. Entering f @@ n for a positive integer n will give you the composition of f with itself n times; for example, if you enter

> sin @@ 3

you will get

x −> sin(sin(sin(x)))

### 3.5 Lists, sequences and sets

Sequences and lists
( ) | sequence delimiters
[ ] | list delimiters
%{ %} | set delimiters
NULL | empty sequence
E$(k=n..m) | create a sequence
seq(E,k=n..m) | create a sequence
[E$(k=n..m)] | create a list
makelist(f,k,n,m,p) | create a list
append | append an element to a list
op(li) | convert a list to a sequence
nop(se) | convert a sequence to a list
nops(li) | the number of elements
size(li) | the number of elements
mid(li) | extract a subsequence
sum | the sum of the elements
product | the product of the elements
cumSum | the cumulative sums
apply(f,li) | apply a function to the list elements
map(li,f) | apply a function to the list elements
map(li,f,matrix) | apply a function to the elements of a matrix
poly2symb | convert a polynomial expression to a polynomial list
symb2poly | convert a polynomial list to a polynomial expression

Xcas can combine objects in several different ways.

sequences
  A sequence is simply several items between parentheses, separated by commas. For example, (1,2,x,4) is a sequence. (The parentheses can be omitted, but it’s a good idea to use them.) Sequences are flat, meaning an element in a sequence cannot be another sequence. The empty sequence is denoted NULL.
lists
  A list consists of several items between square brackets, separated by commas. For example, [1,2,x,4] is a list. A list can contain other lists as elements. Matrices, which will be discussed later, are lists of lists. The empty list is denoted [].
sets
  A set consists of several items between %{ and %}, separated by commas. For example, %{1,2,3%} is a set. In a set, order doesn’t matter and each item only counts once. The sets %{1,2,3%} %{3,2,1%} and %{1,2,2,3%} are all the same set.
tables
  Tables are described later.

A sequence can be turned into a list or a set by putting it between the appropriate delimiters. For example, if you define a sequence

> se := (1,2,4,2)

then if you enter

> [se]

you will get the list

[1,2,4,2]

You can turn a set or list into a sequence with the op command; if you define a set

> st := %{1,2,3%}

and then enter

> op(st)

you will get the sequence

(1,2,3)

You can find the number of elements in a sequence, list or set with the size command; with st as above,

> size(st)

will return

3

Sequences can be built using one of the iteration commands seq or $. The seq command takes an expression as the first argument, the second argument will be a variable followed by a range in the form variable=beginning value..ending value. The resulting sequence will be the values of the expression with the variable replaced by the sequence of values. For example,

> seq(k^2,k=-2..2)

will result in the sequence

(4,1,0,1,4)

The $ operator is an infix version of seq. If you enter

> k^2$k=-2..2

you will get, as above,

(4,1,0,1,4)

A list can be built by putting a sequence in brackets; if you enter

> [k^3,k=1..3]

you will get the list

[1,8,27]

You can also create a list with the makelist command. It takes three arguments; a function (not an expression), an initial value for the variable and an ending value for the variable. If you enter

> makelist(x -> x^2,-2,2)

you will get the list

[4,1,0,1,4]

There is an optional fourth argument, which will be the step size.

You can add an element to the end of a list with the append command. If you enter

> append([1,5],3)

you will get

[1,5,3]

The elements of sequences and lists are indexed, beginning with the index 0. You can get an element by following the sequence or list with the index number in square brackets; if you enter

> ls := [A,B,C,D,E,F]

then

> ls[1]

will return

B

You can get a subsequence (or sublist) by putting an interval (a beginning value and an ending values separated by two dots) in brackets. If you enter

> ls[2..4]

you will get

[C,D,E]

The mid command is another way to get a subsequence or sublist. Given a sequence or list, a beginning index and a length, then mid will return the subsequence of the sequence beginning at the given index of the given length. With ls as above, if you enter

> mid(ls,2,3)

you will get

[C,D,E]

If the length is left off, then the subsequence will go to the end of the given sequence; if you enter

> mid(ls,2)

you will get

[C,D,E,F]

You can change the element in a particular position with the := operator; for example, to change the second element in ls, you can enter

> ls[1] := 7

The value of ls will then be

[A,7,C,D,E,F]

If a variable var is not a list or sequence and you assign a value to var[n], then var becomes a table. A table is like a list, but the indices don’t have to be integers. If you define

> newls := []

and then set

> newls[2] := 5

then since newls was previous a list, it will now be equal to the list

[0,0,5]

If nols is an undefined variable and you set

> nols[2] := 5

then nols will be a table,

table(2=5)

When changing an element of a list (or sequence or table) using :=, the entire list is copied. This can be inefficient. To save copy time and modify the list element in place, you can use =<. If you have

> ls := [a,b,c]

and then enter

> ls[2] =< 3

then ls will be equal to

[a,b,3]

Polynomials are typically given by expressions, but they can also be given by a list of the coefficients in decreasing order, delimited with poly1[ and ]. The symb2poly will transform a polynomial written as an expression to the list form of the polynomial. If you enter

> symb2poly(2*x^3 - 4*x + 1)

you will get

poly1[2,0,−4,1]

The poly2symb will transform in the other direction; if you enter

> poly2symb(poly1[2,0,-4,1])

you will get

2*x3 − 4*x + 1

There is also a way to represent a multivariable polynomial with lists; see the manual for more information.

### 3.6 Characters and strings

String commands
asc | convert a string to a list of ASCII codes
char | convert a list of ASCII codes to a string
size | the number of characters
concat or + | concatenation
mid | substring
head | first character
tail | the string without the first character
string | convert a number or expression to a string
expr | convert a string to a number or expression

A string is simply text enclosed within quotation marks. You can find out how many characters are in a string with the size command; if you enter

> size("this string")

you will get

11

A character is simply a string with length 1. The char command will take an ASCII code (or a list of ASCII codes) and return the character or string determined by the codes. For example, the letter “a” has ASCII code 65, so

> char(65)

will return

A

The asc command will turn a string into the list of ASCII codes; if you enter

> asc("A")

you will get

[65]

The characters in a string are indexed starting with 0. To get the first character, for example, you can enter a string, or the name of a string, followed by [0]. If you enter

> str := "abcde"

> str[0]

you will get

a

You can choose a substring from a string by putting the beginning and ending indices in the brackets, separated by two periods ... If you enter

> str[1..3]

you will get

bcd

An alternate way of getting the first character from a string is with the head command. With str as above,

> head(str)

will return

a

The tail command will produce the remaining characters;

> tail(str)

will return

bcde

Strings can be combined with the concat command or the infix + operator. Both

> concat("abc","def")

and

> "abc" + "def"

will return

abcdef

If a string represents a number, then the expr command will convert the string to the number. For example,

> expr("123")

will return the number 123. More generally, expr will convert a string representing an expression or command into the corresponding expression or command. The string command works in the opposite direction; it will take an expression and convert it to a string.

### 3.7 Calculation time and memory space

One major issue with symbolic calculations is the complexity of the intermediate calculations. This complexity takes the form of the amount of time required for the calculations and the amount of computer memory needed. The algorithms used by Xcas are efficient, but not necessarily optimal. The time command will tell you how long a calculation takes. For very quick calculations, Xcas will execute it several times and return the average for a more accurate result. The amount of memory used by Xcas is shown in the status line of the Unix version of Xcas.

If a command that you are timing takes more than a few seconds, you could have made an input error and you may have to interrupt the command (with the red STOP button on the status line, for example). It is a good idea to make a backup of your session beforehand.