Computer computations
(a short introduction to Mathematica computer algebra system)

The goal of the course is not to teach the language of Mathematica but to give a rough overview of numerous opportunities provided by it. The actual syntax of one or another command can be found in the Help (addressed at any place of the code by the F1 button)

Lecture 1

Simplest operations, variables, and functions

Type a command. To evaluate it press ⇧+⌤ simultaneously. The result will show up in the output cell.

(2^2)

Sin[(π/4)]

To type the exponent I pressed Ctrl^. To get the letter π I typed EscpEsc. In general, to type special symbols and forms one can use Palettes called from the Mathematica menu. The required form can be chosen with a mouse. The pop-up menu provides a hint how to type the same form with the keyboard without using menu.

∫((\[DifferentialD]x)/(Sin[x]+1))

(∑_(n=1)^∞)(1/(n^2))

Integers used by Mathematica can be arbitrary large, overflow never occurs. Also there is no restriction on the specified precision of numerical computations

200!
N[E,300]

Commands, once input, can be edited and evaluated again. A cell can contain a sequence of commands. If a command ends with “;”, then the result is not printed to the output. If a command ends with a new line, then the result is printed.

b=(((a+3))^2);
b+5
a=2;
b+5

The result of the last executed command can be referred to as “%”:

((%)^2)

(Pay attention to the fact that the symbol “%” refers to the result of the last executed command rather
than to the command printed immediately before the one to be executed).
In addition to the usual assignments “=”, there are also so called delayed ones “:=”. Compare:

a=1;
b=a+1;
b
a=20;
b

a=1;
b:=a+1;
b
a=20;
b

Delayed assignments are worth to be used to define functions (with arguments). The arguments are put in the square brackets and separated by commas (and the parentheses are only used to group compound expressions).

f[x_,y_]:=(((x+y))^2);
f[(z^2),1]

The underscore symbols mean that x and y can stand for arbitrrary expressions. Without those signs the definition would be applied to the symbols x and y themselves only.

g[x]:=(((x+1))^2);
g[6]
g[x]

It is possible to supply patterns of the form “x_”  with various conditions following the “/;” symbol. If these conditions are not satisfied, then the expression remains unevaluated.

Clear[f];
f[n_Integer]/;n>0:=n f[n-1];
f[n_Integer]/;n<0:=∞;
f[0]=1;
(1/(f[5]))
(1/(f[-5]))
(1/(f[c]))

Here the “Clear” command is used to erase all the previous definitions related to the symbol “f”. 
Active assignments can be shown using the “?” symbol:

?f

Mathematica (М.) examines the expression to be evaluated and searches for its parts for which there are defined assignments, and then applies them. The order in which these definitions are applied is chosen so that more specific ones are applied prior to more general ones. Thus, observing “f[-5]” M. checks first if the argument “-5” is “0”. Since this is not the case, the first definition is not applicable. Then it checks if it is a positive integer. Since it is not, the second definition neither is applicable. Finally, the third definition is applicable and we get the result (1/∞)=0.

When calling a function with arguments, along with the usual notation, one can also use prefix and postfix notation indicated by the symbols “@” and “//”, respectively

f[5]
f@5
5//f

Together with named functions there are also so called pure functions (with no name associated to them). A pure function is denoted by the symbol “&” at the end and its argument is denoted by “#”. Compare:

g[x_]:=(((x+1))^2);
g[q]
(((#+1))^2)&[q]

Pure functions in combination with postfix notation are convinient for final formatting of the computed expressions

b=((((c^3)+7+x))^2);
(b^2)  //Expand
(b^2)  //Collect[#,x]&

Lists and other expressions

Arrays, vectors, matricies, and tables are realized in Mathematica as lists and nested lists. A list is a sequence of its components separated by commas and enclosed into figure brackets “{“,”}”. A matrix can be input as a table but it is still interpreted internally as a nested list.

{1,3,a,x+5}
(({{1, z, u+1}, {0, 1, 0}, {(d^2), 0, 1}}))

A list is a simplest example of what is considered as an expression. In fact everything in Mathematica is an expression. An expression consists of a head and a sequence of its elemets. Each element, in turn, can be either an atom (a number, a variable etc.) or again an expression with its own head, a list of its elemends, and so on. As a result we get a tree-like expression. For example, the operations “+“, “×”, or taking a power have the heads “Plus”, “Times”, and “Power”, respectively, and a list has the head “List”.

Plus[c,4]
Times[c,4]
Power[c,4]
List[c,4]

The actual structure of an expression can be viewed using “FullForm” or “TreeForm” commands.

{x,(((2y+1))^2)}//FullForm

{x,(((2y+1))^2)}//TreeForm

All special symbols that we met before and will meet later, like  “&”, “>”, “_”, and including “=”, “:=”, and even “;”, are just shorthands of the corresponding expressions with appropriate heads. The next example uses the command Hold that prevents an expression from evaluation, in order to see its structure.

Hold[
g[x_]:=x+1;
g[2]             ]//TreeForm

An element of a list (or a matrix) can be refferred to using double square brackets. Here are several equivalent (from the point of view of interpretation) ways to do this

M=(({{1, z, u+1}, {0, 1, 0}, {(d^2), 0, 1}}))
M[[1,3]]
M[[1,3]]
(Subscript[M, [[1,3]]])
M[[1]][[3]]

The expression “M[[1,3]]” means that we take the first element “M[[1]]” in the expression “M”, and then, in turn, take the 3rd element in “M[[1]]”. Unexpectedly, similar rules are applicable to expressions with arbitrary heads, not necessary lists!

b
b[[1,2]]
b[[1,2,2]]

The head of an expression can be obtained either using “Head” command or as its 0th element,

b
Head[b]
b[[0]]

Replacements

The replacement is one of the most efficient operations in Mathematica. It consists in replacing some the parts in a given expression with new ones.

b
b/.x->y
b/.Plus->Times
b/.Power->pow

Similarly to the delayed assignments, patterns for the substituted parts can use “_” and conditions. In that case instead of usual replacement symbol “->” it is better to use the symbol “:>” of delayed replacement (approximately by the same reason that causes to use the delayed assignment command “:=” instead of the usual assignment “=” in the definitions of new functions). Here is an example of how the geometric progression can be turned into an exponent!

(1/(1-ϵ x))+((O[ϵ])^8)
%/.(x^(k_)):>((x^k)/(k!))
Log[%]

The symbol “((O[ϵ])^8)” is used here for the power expansion. Now we collect all the commands together:

(1/(1-ϵ x))+((O[ϵ])^8)/.(x^(k_.)):>((y^k)/(k!)) //Log

We also replaced here the variable “x with “y”. The point in the pattern “k_.” means that it is applyed for the optional value of “k” which is equal to 1 in the case of the exponent. Without this point the replacenment would not be applied to the linear term x=(x^1). There is a reason to Introducing a supplementary variable ϵ as the expansion parameter has a reason of its own. The following version does not work :

(1/(1-x))+((O[x])^8)
%/.(x^(k_)):>((x^k)/(k!))

The reason is in the internal form of representation of power series in Mathematica.

(1/(1-2x))+((O[x])^5)
%//FullForm

We see that the series is represented by the expansion variable, the center on the expansion, the list of coefficients and the range of their exponents. Neither the monomials “(x^k)” themselves nor the symbol “O” are used in the internal representation. They are only used for formatting of the output.

In the next example, we use replacements to create the list of all partitions of a given number n.

n=6;
(∏_(i=1)^n)(1/(1-(Subscript[x, i])(s^i)))//
SeriesCoefficient[#,{s,0,n}]&//Expand//
#/.Plus->List&//
#//.{(Subscript[x, i__])(Subscript[x, j__]):>(Subscript[x, i,j]),(Subscript[x, i__]^(k_)):>(Subscript[x, i,i])(Subscript[x, i]^(k-2))}&//
#/.(Subscript[x, k__]):>Sort[{k},Greater]&//
Sort

Now the same in detail
1) Take the product of geometric progressions and select its homogeneous term of degree n. It is the sum of all monomials of the quasihmogeneous degree n, with the degree of the variable (Subscript[x, i])set to be i, i=1,2,3,...

(∏_(i=1)^n)(1/(1-(Subscript[x, i])(s^i)))// 
SeriesCoefficient[#,{s,0,n}]&//Expand

2) Convert the sum into a list

%/.Plus->List

3) Replace the product of several variables with indicies by a single variable with the corresponding multiindex. The command  “//.” means “apply the replacement repeatedly untill the replacement rule is applicable”. The list of replacement rules consists of two elements, therefore, we enclose it into figure brackets. The pattern “i__” (with two underscore characters) means “a sequence of one or more elements”.

%//.{(Subscript[x, i__])(Subscript[x, j__]):>(Subscript[x, i,j]),(Subscript[x, i__]^(k_)):>(Subscript[x, i,i])(Subscript[x, i]^(k-2))}

4) It remains to convert the multiindices thus obtained, after sorting them, to partitions

%/.(Subscript[x, k__]):>Sort[{k},Greater]//
Sort

Note that the same goal can be achieved in a slightly simpler way...

IntegerPartitions[n]

Lecture 2

Along  with the input and output cells, it is handfull to use the title cells of different levels whose style can be modified by means of the menu. There are also text cells that can be used for comments. Comments can be placed also inside the input cell with the help of pairs “(*” and “*)”.

The cells with the common title can be closed temporary in order to reduce the space on the screen. For example, if the reader does not need the content of the first lecture any longer, he or she can close it. In order to close or to open a cell one can doubleclick the corresponding blue bracket on the right border of the window. Alternatively, one can use the menue Cell->Grouping->Open All Subgroups.

Programming

Standard programming tools like branching (If, Which, Switch) and cycles (Do, While, For) are available also in Mathematica. The precise syntax can be checked through the Help (in order to call Help, put the mouse on the name of the command and press the F1 button on the keyboard); here we only point out several specific details. Being commands in Mathematica, they consist of the Head and the list of arguments in the square brackets.

Z[a_]:=If[a==0,"zero","non-zero"];
Z[0]
Z[1]
Z[x]

Note that if the result of the test a==0 is neither True nor False, then the result of the If command remains unevaluated. To fix this, one can add the 4th argument to the If command or to use  “===” instead of “==”

x==0
x===0

Let us look now at the followig four commands, namely, Do, Sum, Product, and Table having a similar syntax

Clear[a];
tot=0;
Do[tot=tot+(Subscript[a, i]),{i,5}]
tot
Sum[(Subscript[a, i]),{i,5}]
Product[(Subscript[a, i]),{i,5}]
Table[(Subscript[a, i]),{i,5}]

The action of these commands is also similar: they evaluate the expression for the subsequent values of the iterator in turn. The only difference is that they substitute different heads to the resulting list of values, namely: Plus (for Sum), Times (for Product), List (for Table) or no head for Do. 
Let us point out two specific features. First, the Sum and the Product commands admit nice 2D versions

(∑_(i=1)^5)(Subscript[a, i])

Second, the range of values of the iterator can be represented explicitely by a list. This could be rather convenient

list={1,q,Sin};
tot=0;
Do[tot=tot+(Subscript[a, i]),{i,list}]
tot
(∑_i^list)(Subscript[a, i])

The variables used for the iterator are `local’ meaning that they do not change the values of these variables assigned outside of the cycle. Such local variables can be organized explicitely in one of the following ways

tot=0;
Block[{tot=5},tot]
Module[{tot=6},tot]
With[{tot=7},tot]
tot

As one can see, the result is the same in all three cases. The difference of these commands is in their implementation. I recommend to use Block, and a concerned reader can figure out the details in the Help.

Here is an example of using While for finding the Taylor expansion of an implicit function. Note that the While command has two arguments (the continuation test and the body of the cycle) but each argument may contain a  sequence of several commands separated by a semicolon. This is a manifestation of a general (even though somewhat unexpected) principle in Mathematic:

the comma is more important than the semicolon

Namely, the comma separates the arguments of functions, and the semicolon collects a sequence of commands inside an argument.

Clear[f,y]
f[x_,y_]:=Sin[ x y]+(x^3)-(y^2);
y==f[x,y]
y=Block[{y=0,k=0,ynew,z,eq,sol},
While[k=k+1;
k≤10,
ynew=y+a (x^k);
z=ynew-f[x,ynew];
eq=SeriesCoefficient[z,{x,0,k}]==0;
sol=Solve[eq];
y=ynew/.sol[[1]]];
y+((O[x])^11)]
(* check *)
f[x,y]-y

Such a big number of auxiliary variables is used here to demonstrate the usage of “;”. One can readily manage without them in this particular case:

Block[{y=0},
Do[
y=y+a (x^k);
y-f[x,y]//
SeriesCoefficient[#,{x,0,k}]&//
Solve[#==0]&//
(y=y/.#[[1]])&,
{k,10}];
y+((O[x])^11)]

Mathematica provides also a number of variations of cycles that have no analogues in other programming languages. These are the cycles Nest, NestWhile, and FixedPoint. An interesting proprety of these cycles is that they use a function as one of their arguments.

Nest[g,x,5]

The command Nest applies the function to the initial value a given number of times, NestWhile applies it until a condition remains True, and FixedPoint does while application of the function changes the result. Here are examples of how these cycles can be used to compute the Taylor expansion of an implicit function.

Clear[y];
y==f[x,y]
Nest[f[x,#]&,O[x],10]
NestWhile[f[x,#]&,O[x],#[[5]]<11&]
FixedPoint[(f[x,#]+((O[x])^11))&,0]

Manipulation with lists

In spite of the fact that Mathematica has all standard attributes of programming languages like cycles of different kinds, the programming style in Mathematica has its own specific character. In particular, it shows up in a wide range of tools of manipulation with lists. The lists can be joined, cut, rearranged and so on. Here are, for example, several ways to select elements of a given list starting from the 3rd one.

list=Table[(Subscript[a, k]),{k,7}]
Drop[list,2]
Take[list,-5]
list[[3;;]]

All other tools can easily be found in the Help in the section `See Also’ of any already known command.
Let us recall the convenient replacement operation “/.”, and also mention existence of two important commands Map “/@” and Apply “@@”. The first one applies the function to each element of the list in turn, the second applies the function to the whole list (i.e. it uses the elements of the list as arguments of the function).

g/@{a,b,c}
g@@{a,b,c}

Example. Enumeration of trees

The “tree-like” structute of data in Mathematica is well adapted to the problem of enumeration of (plane) trees. Here is an example of a plane tree. Its vertices are denoted by the symbol “v”.

t=v[v[v[],v[v[v[]],v[v[]]],v[]]]
TreeForm[t,VertexLabeling->False]

In order not to transform the output of a tree each time to a specific form one can use the Format command. It does not affect the result of computations but just changes automatically the formatting of the output expressions.

Format[t_v]:=TreeForm[t,
VertexRenderingFunction->({Blue,Point[#]}&),
ImageSize->Scaled[0.08]]
t

In fact, the trees used in our enumeration are rooted. It is worth, therefoe, to mark somehow the root vertex in the output.

Format[t_v]:=TreeForm[u@@t,
VertexRenderingFunction->(
If[#2===u,Text[" ☺",#],{Blue,Point[#]}]&),
ImageSize->Scaled[0.08]]
t

We turn now to enumeration of trees. Let tlist[k] produce the list of plane trees with k edges.

tlist[0]=v[]
tlist[1]=v[v[]]

Introduce the “gluing” operation of two subtrees along the top right edge. Every tree with n edges can be obtained by glung of two subtrees whose total number of edges is equal to n-1.

a_v·b_v:=Append[a,b];
tlist[k_]:=(∑_(j=0)^(k-1))tlist[j]·tlist[k-1-j];
tlist[2]
tlist[3]

To make this operation working it remains to add the distributivity property to the introduced gluing operation.

a___·b_Plus·c___:=a·#·c&/@b;
a___·(k_ b_)·c___/;FreeQ[k,v]:=k a·b·c;
tlist[3]
tlist[4]

Let the weight of a vertex of valency k be the formal variable (Subscript[x, k]), and the weight of a tree be the product of the weights of its internal vertices (i.e. excluding the root). Let us enumerate the trees together with their weights. To do that, we insert the corresponding coefficient into the definition of the gluing operation. Here is the final code (consisting of just 5 lines!)

Clear[tlist];
a_v·b_v:=(Subscript[x, Length[b]+1])Append[a,b];
a___·b_Plus·c___:=a·#·c&/@b;
a___·(k_ b_)·c___/;FreeQ[k,v]:=k a·b·c;
tlist[0]=v[];
tlist[k_]:=(∑_(j=0)^(k-1))tlist[j]·tlist[k-1-j];

Collect[tlist[5],(Subscript[x, _])]

We are ready now to start experiments. The generating function T given below for the numbers of (unrooted) plane trees satisfies a number of interesting identities that we are going to check experimentally. For a given tree, its root and the initial edge exiting the root can be chosen in 2n different ways (by the number of halfedges). This explains the coefficient (1/(2n)) used in the definition of the function T below.

ord=6;
T=(∑_(n=1)^ord)(1/(2n))(tlist[n]/.t_v:>(Subscript[x, Length[t]]))(s^n)+((O[s])^(ord+1))

The derivative over (Subscript[x, k]) enumerates rooted trees having a root of valency k:

Y=(∂_(Subscript[x, 1]))T

Here is the identity illustrating the gluing operation for trees

(∑_(k=1)^ord)k (Subscript[x, k])(∂_(Subscript[x, k]))T-(s^(-1))(Y^2)

The following identities are called the `equations of the dispersionless KdV hierarchy’. They mean that erasing a root of valency k we get k trees all of which have a root of valency 1.

Table[
k(∂_(Subscript[x, k]))T-(Y^k),
{k,5}]

Given a tree with a leaf as a root (i.e. a root of valency 1), erasing this root together with the edge exiting from it, we get a tree with a root of arbitrary valency. This provides an implicit equation on the function Y (the so called string equation)

Y-s(∑_(k=0)^ord)(Subscript[x, k+1])(Y^k)
(s^(-1))Y==(Subscript[x, 1])+(Subscript[x, 2])Y+(Subscript[x, 3])(Y^2)+(Subscript[x, 4])(Y^3)+(Subscript[x, 5])(Y^4)+(Subscript[x, 6])(Y^5)+((O[s])^6)//ExpandAll

Finally, there is an explicit closed factorial formula for the coefficients of the series T.

(Subscript[x, μ_List]):=(∏_i^μ)(Subscript[x, i])/.(Subscript[x, k_]^(i_)):>((Subscript[x, k]^i)/(i!));
T== (∑_(n=1)^ord)(n-1)!(s^n)(∑_μ^(IntegerPartitions[2n,{n+1}]))(Subscript[x, μ])+((O[s])^(ord+1))//ExpandAll

Debugging and performance acceleration

If the program `hangs up’ or if the computing time is too big, there is a way to interrupt computations by pressing  “Alt,” or “Alt.”. In the last resort, one can use the menu item Evaluation->Quit Kernel. In order to reduce the usage of such extreme means it is useful to control the course of computations. The simplest recommendation is to include debugging prints to the code. A more advanced tool is the usage of dynamic expressions

Dynamic[n]

The output value of such expression is updated authomatically in real time together with the changes of the expression itself

n=0
Do[++n;Pause[0.2],{20}]

Let us mention a number of workarounds whose aim is to increase the performance of Mathematica (I mention only those that appeared in my practical research; the number of simiar tricks is certainly much bigger).

It was already mentioned that there is no restriction in Mathematica in the size of integers. On one hand, it is convenient: overflow never occurs. On the other hand, this causes unnecessary waste of resources. Many commands manipulating with polynomials provide an option of computation modulo some prime integer. In many cases, this is quite sufficient for applications but increases substantially the speed of computations.

PolynomialRemainder[(x^1000),(x^3)-x+1,x]

PolynomialRemainder[(x^1000),(x^3)-x+1,x,Modulus->113]

Combinatorics deals often with matrices of big size with a relatively small number of non-zero entries. It is convenient to store matrices of this type using the command SparseArray. Most matrix operations like summation, multiplication, computing determinant, taking eigenvectors and eigenvalues are typically set up to work as they do with usual matrices.

M=SparseArray[{{i_,i_}->1,{2,5}->5},{6,6}]

M//MatrixForm
M.M//MatrixForm

If the results of computations are stores in the replacement list of huge size, then, in order to increase the efficiency, it is worth to apply to this list the command Dispatch. This command packs the replacement list making a more efficient handling of it by the Mathematica kernel.

repl=Table[(Subscript[x, i])->(i^2),{i,10000}];

Short[repl]

Timing[(∑_(i=1)^10000)(Subscript[x, i])/.repl]

disp=Dispatch[repl];

Timing[(∑_(i=1)^10000)(Subscript[x, i])/.disp]

By the way, we used here the Timing command, yet another useful tool to control the efficiency of computations.

For a function defined recursively, it makes sence to store the computed values in order not to cause the program to call the recursion every time when the function is referred to. This may increase the speed of computations to several orders. For example, here is the definition of the Chebyshev polynomials.

Clear[T];
T/:(Subscript[T, 1])=x;
T/:(Subscript[T, n_]):=x (Subscript[T, n-1])-((1-(x^2))/(n-1))(∂_x)(Subscript[T, n-1])//Expand;
Timing[(Subscript[T, 20])]

Compare with the timing used when the intermediate values are stored:

Clear[T];
T/:(Subscript[T, 1])=x;
T/:(Subscript[T, n_]):=T/:(Subscript[T, n])=x (Subscript[T, n-1])-((1-(x^2))/(n-1))(∂_x)(Subscript[T, n-1])//Expand;
Timing[(Subscript[T, 20])]

The symbol “/:” is used here in order to relate the definition of (Subscript[T, n]) with the symbol T so that the command Clear[T] could be used to clear the definition in the course of debugging.

If there is a need to store the results of computations to a file and to use them in another session of Mathematica, this can be done in the following way:

SetDirectory[NotebookDirectory[]]
DumpSave["tmp.mx",{T}]

Without indication of the directory, Mathematica tries to use the system one (which is, most probably, write-protected).
The DumpSave can be replaced by just Save. The difference is that Save stores the data in the readable text form but DumpSave does this in the binary machine-dependent form which is less compatible with different systems but is certainly more efficient. We can now stop the kernel or even exit the Mathematica program.

SetDirectory[NotebookDirectory[]];
<<tmp.mx

All definitions related to the symble T (both the commands defining the Chebyshev polynomials and the computed values) are restored completely.

?T

Lecture 3

Input and output

One can ouput the results of computations omitting the “;” symbol at the end of the line. Another, more explicit way to do that is to use the Print command. It prints out to the output cell all its arguments one after another without spaces. In order to separate the fields, they can be alternated with text strings (enclosed into double quotes). The text strings, in turn, can include expressions using the StringForm command.

Do[Print["n = ",n,StringForm[",  (2^(`1`)) = `2`",n,(2^n)]],{n,5}];

If the visual presentation of data in Mathematica does not satisfy your needs, it can be changed using the Format command. It does not change the expression itself but just the way it appears in the output. Assume that we have a power series (or a polynomial) whose coefficients are labelled by partitions (Young diagrams).

F=(∑_(n=1)^5)(∑_λ^(IntegerPartitions[n]))Y[λ](∏_i^λ)(Subscript[x, i])

Here is the way to enhance the visualization of this expression

Format[Y[λ_List]]:=(Subscript[Y, Row[λ]])
F

Mathematica contains a lot of nice commands with reduced infix or prefix notations without built-in meaning. These are brackets of different kinds, binary operations like ·,∘,⋀,⊗,⊕, and many others. They can be used and defined according to the needs (similarly to the way we defined the gluing operation for trees in the previous lecture). It is worth to recall, however, that these commands are just reduced notations for the corresponding functions with their own heads and the lists of arguments etc.

a⋀b//FullForm

Finally, if this is still insufficient, Mathematica provides the opportunity to introduce your own notation. To use it, one needs to load an additional Notation package

Needs["Notation`"]

Here is an example of an invented notation for the limit:

Notation[(NotationTemplateTag[(lim_(x_-> a_))f_]) ⟺ (NotationTemplateTag[Limit[f_,x_->a_]])]

(lim_(x->0))(Sin[Tan[x]]-Tan[Sin[x]])/(ArcSin[ArcTan[x]]-ArcTan[ArcSin[x]])

And here is an example of a new notation for the operation of taking square

Notation[(NotationTemplateTag[■ x_]) ⟺ (NotationTemplateTag[((x_)^2)])]
■ 5

Clear[a,b];
(((a+b))^3)//Expand

RemoveNotation[(NotationTemplateTag[■ x_]) ⟺ (NotationTemplateTag[((x_)^2)])]

Graphics

Features of woking with graphics are boundless in Mathematica. Being unable to describe all details, we will restrict ourselves to just consideration of several elementary examples. The reader is encouraged to develop and to enhance these examples.

The simplest graphic command is Plot. It is used to draw the graph of a function in one variable

Plot[x Sin[1/x],{x,-1.2,1.2}]

Let us make a number of enhancements. 1) Add two more functions x and -x for better visualization; 2) Add the option PlotRange to specify the Range of the values of the function and AspectRatio to specify the scaling of the axis; 3) Add a parameter and a simple manipulator for  variating its values

Manipulate[
Plot[{x Sin[a/x],x,-x},{x,-1.2,1.2},
PlotRange->{-1.2,1.2},AspectRatio->1],
{a,0,10}]

Here are the familiar Chebyshev polynomials. They have the property that all critical points are real, half of them have the critical value 1, and the remaining ones have the critical value -1. The Plot command works better if the function is computed in advance rather than while plotting the graph.

Manipulate[y=(Subscript[T, n]);
Plot[{y,1,-1},{x,-1.2,1.2},
PlotRange->{-1.2,1.2},AspectRatio->1],
{n,1,30,1}]

Here I use the ParametricPlot command to plot the cycloid.

r[ϕ_]:={Cos[ϕ],Sin[ϕ]};
n=4;
ParametricPlot[n r[ϕ]+r[-n ϕ],{ϕ,0,2π}]

In order to plot something by hand, one uses the Graphics command. Its argument consists of a sequence of `primitives’ and `directives’ grouped by curly braces. Primitives are the elementary objects to be drawn: a point, a line, a circle, a rectangle etc. A directive describes the way to draw the objects: colour, dashing, thickness of the lines etc. Here is a simple graphics consisting of two circles and a point.

Manipulate[
Graphics[{Circle[{0,0},n+1],Circle[n r[ψ],1],
{PointSize[Large],Red,Point[n r[ψ]+r[-n ψ]]}}],
{ψ,-2π,2π},{n,2,10,1}]

The cycloid drawn above is the trace of a given point on the small circle rolling along the big one. How to combine two graphics in one picture? It can be done using the Show command. Besides, the Show command can be supplied with graphics options valid for all graphics command to which it is applied.

Manipulate[
Show[
ParametricPlot[n r[ϕ]+r[-n ϕ],{ϕ,0,ψ}],
Graphics[{Circle[{0,0},n+1],Circle[n r[ψ],1],
{PointSize[Large],Red,Point[n r[ψ]+r[-n ψ]]}
}],
Axes->False,PlotRange->(n+1){{-1,1},{-1,1}}],
{ψ,-2π,2π},{n,2,10,1}]

The next example illustrates some interactivity opportunities. Let us consider a matrix composed of units and zeroes.

n=10;
A=RandomInteger[1,{n,n}];
MatrixForm[A]

Let us represent this matrix as a checkboard whose fields are colored in two colors depending on the value of the component. Remark that graphics uses traditional orientation of the axes (the first one from left to right, the second one from bottom to top). In order to put this in accrodance with the traditional numeration of rows and columns of matrices we have to rotate the coordinates by (90^∘).

Graphics[Table[{EdgeForm[Thin],If[(Subscript[A, [[n+1-j,i]]])==0,Cyan,Pink],Rectangle[{i,j}]},{i,n},{j,n}],ImageSize->150] //
Row[{#,"  A = ",MatrixForm[A]}]&

And now we would like to realize the possibility to change the colour of a cell (and the corresponding values of the matrix) by just clicking it with the mouse. For this aim we use the command ClickPane. Its first argument is the graphics itself (to which Dynamic is applied), and the second argument is the function which is applied each time the mouse is clicked. The argument of the function is the list of the coordinates of the mouse. In our case we round the coordinates to the integers and change the corresponding entry of the matrix.

ClickPane[Dynamic[
{Graphics[Table[{EdgeForm[Thin],If[(Subscript[A, [[n+1-j,i]]])==0,Cyan,Pink],Rectangle[{i,j}]},{i,n},{j,n}],ImageSize->150],"  A = ",MatrixForm[A]}//Row],
({i,j}=Round[#-(1/2)];If[1≤i≤n&&1≤j≤n,(Subscript[A, [[n+1-j,i]]])=1-(Subscript[A, [[n+1-j,i]]])])&]

Along with the 2D graphics Mathematica provides tools generating 3D graphics. Commands like Plot3D or ParametricPlot3D draw surfaces, and using Graphics3d one can compose 3D graphic objects by hand. 3D graphics can be rotated using the mouse.

Clear[pp];
pp[a_]:=Join@@Table[{Cos[2π (i+a z)/3],Sin[2π (i+a z)/3],z},
{i,0,2},{z,{-1,1}}]//Append[#,#[[1]]]&;
pp[0]

Graphics3D[{Tube[pp[1.1],0.1]},Boxed->False]

Manipulate[
Graphics3D[{Tube[pp[a],.1]},Boxed->False],{{a,1.1},0,3}]

Conclusion

We have shown a very small portion of tools provided by Mathematica. More information can be obtained from the Help as well as by studying various examples collected in the Demonstrations project on the Wolfram Website (a reference is avalable in the Help item of the menu).

Some more examples

Enumeration of Chord diagrams

A chord diagram is a collection of 2n points on the circle split into n pairs (represented by chords). Two diagrams are isomorphic (or just the same) if they can be obtained from one another by an orientation-preserving diffeomorphism of the circle.

pt[α_]:={Cos[2π α],Sin[2π α]};
Format[diag[λ___]]:=Block[{n=Length[{λ}]},
Graphics[{Circle[{0,0},1],
Thick,Table[Point[pt[k/(2n)]],{k,2n}],
Blue,Table[Line[pt/@(s/(2n))],{s,{λ}}]},ImageSize->60]];
diag[{1,2},{3,4},{5,6}]

smplf[λ_]:=Table[Sort[Sort/@(λ/.j_Integer:>Mod[j+k,2Length[λ]]+1)],{k,1,2Length[λ]}]//Sort//First;
diag[{1,3},{2,5},{4,6}];
dlist[0]={diag[]};
dlist[n_]:=dlist[n]=
Table[Append[λ/.{j_Integer/;j≥k:>j+1},{k,2n}]//smplf,
{k,1,2n-1},{λ,dlist[n-1]}]//Flatten//DeleteDuplicates;
dlist[4]
Length[%]

Inversion of a series

x=y+(Subscript[a, 1])(y^2)+(Subscript[a, 2])(y^3)+…

Clear[a,y];
Block[{c,y},
y=x;
Do[
y=y+c (x^k);
y=y/.(SeriesCoefficient[y+(∑_(i=1)^(k-1))(Subscript[a, i])(y^(i+1))-x,{x,0,k}]==0//
Solve[#,c]&//First),
{k,2,6}];
y]

y=x-(Subscript[a, 1])(y^2)-(Subscript[a, 2])(y^3)+…

Y=Nest[(x-(∑_(i=1)^5)(Subscript[a, i])((#)^(i+1)))&,O[x],6]//ExpandAll
Y-FixedPoint[ExpandAll[x-(∑_(i=1)^6)(Subscript[a, i])((#)^(i+1))+((O[x])^7)]&,0]
Y-InverseSeries[y+(∑_(i=1)^5)(Subscript[a, i])(y^(i+1))+((O[y])^7),x]