Informatics to Students of Cognitive Science
 Budapest University of Technology and Economics

Lajos Lóczi  and  Nóra Sándor
2013

.. The purpose and structure of these notes

The primary purpose of these interactive notes is to cover the material corresponding to the one-semester course Informatics to Students of Cognitive Science at the Budapest University of Technology and Economics.

Interactivity is made possible by the computer system Mathematica, on which the Informatics Course is based—therefore, the current notes try to serve as a gentle introduction to this software as well.

We will be led into different aspects of Mathematica through examples, simultaneously illustrating various concepts in informatics, although, due to time limitations, only a small fraction of the capabilities of the software can be covered (we are going to encounter only a few percent of the current Mathematica commands). Interactivity means that you can (and should!) easily reproduce or modify the examples given in this document—also called Mathematica notebook. In fact, in our opinion, the best way to learn these concepts is to freely change the given inputs (adjust the parameters, play with the sliders, and so on) and explore the consequences.

Let us also point out that the name Mathematica is a bit narrowly defined, because nowadays, as we will see, it is much more than a tool for doing traditional mathematics. Together with Mathematica we are going to learn some parts of its underlying language, the Wolfram Language. Mathematica has been one of the earliest manifestations of the Wolfram Language, but in the near future we will meet this language more and more often—e.g., in mobile applications, or in the computational knowledge engine Wolfram Alpha introduced in 2009. Wolfram Alpha is already used, for example, by hundreds of thousands of students to help solving their homeworks, but it can even easily analyze your connections within your favorite social networking site.

A list of the main themes of these notes in each chapter is given below (Mathematica commands or code pieces in the text will most often be denoted by this style).

In Chapter 2, we will focus on how to create simple but non-trivial 2D or 3D, static or interactive visualizations by using the Manipulate and Animate commands. Our visualizations will include classical geometric shapes (the graphics primitives), but we will also explore the bones of a foot, design smileys, flags, rings or a solar system, deform a doughnut, fade images, create a clock, or play some music. Chapter 3 deals with string manipulation and shows some simple applications in linguistics. The central theme in Chapter 4 is classical algebra but from a more interactive viewpoint. In Chapter 5, we are going to interactively explore some properties of sequences, series, functions or iterations. In Chapter 6 we present two, more involved applications: one on charting data and one on music recognition. Finally, in the last chapter, serving as an Appendix, a brief but broader overview of Mathematica is presented: after some historical remarks, some current and typical application areas are collected, together with the most important elements of Mathematica syntax and language, and several useful tips on the efficient use of the software.

For your reference, at the end of each chapter, a

Summary

section is given where we have collected the most important Mathematica commands newly covered in that chapter.

Sections within each chapter typically begin with one more complex initial example or its variants, motivated by real-life applications. These working code examples will be denoted by this background color:

Manipulate[ImageTake[,{startingslice,Min[startingslice+layerthickness,51]},{1,34},{1,35}],{startingslice,1,51,1},{layerthickness,0,50,1}]

Your instructor will show you how to evaluate these pieces of code. After discussing the significance of the example, we will deconstruct these compound commands into some simpler building blocks and study them  individually in more detail as well as in different contexts to understand their behavior and what concept they illustrate. This phase will generally take place after an  Explanation: details and variants  sign.

Exercise.  Many additional exercises (without solutions) will appear within each chapter. These exercises are marked with this background color. Your instructor will let you know whether you have to study and solve them on your own or in a group.

As a general rule, the approach taken in these notes is the following: instead of a systematic treatment or introduction to the software, we are going to analyze several examples in each section. In other words, we are going to follow an application-oriented “right in the middle approach” rather than a more exhaustive “from bottom to top approach”.

Throughout this document it is assumed that you are already familiar with the basics of Mathematica syntax. Hence, during your Informatics Course, and especially in the first weeks, your instructor may direct you to the Appendix at the end of this document from time to time to study or discuss some relevant paragraphs.

A note on the software and hardware.  This notebook has been created in Mathematica version 9, so in order to take full advantage of all the interactive features discussed in this document, it is recommended that you have the latest available Mathematica version. Moreover, some examples—especially the ones dealing with 3D imaging—require a fast enough computer to run smoothly. Other examples may require Internet connectivity. Finally, as we sometimes also generate music, a machine with audio capabilities is recommended.

.. Additional resources

There are thousands of pages on the web concerning Mathematica. Let us list only four of them as further references. Active hyperlinks throughout this document are marked as usual.

A complete Mathematica documentation in English is available on-line at http://reference.wolfram.com/mathematica/guide/Mathematica.html.

A 396-page overview on the software (published in 1996 in Hungarian) can be freely downloaded from http://www.math.bme.hu/~jtoth/Mma/M_M_ 2008.pdf.

A rich source of various Mathematica-related documents is found at http://www.math.bme.hu/~jtoth/Mma/mma.html.

Finally, many interesting teaching materials written in Mathematica are collected at  http://www.model.u-szeged.hu.

.. Acknowledgement and sources

The authors of these notes are indebted to their colleagues  J á n o s   T ó t h  and  G e r g e l y   G y e b r ó s z k i  for sharing their expertise and experiences, and providing us with several Mathematica code examples that have been used in the current document.

Other code pieces, graphs, and 2D or 3D images shown in this document (as tasks, exercises or illustrations) were taken from the public domain; typically, from the Mathematica documentation itself or from the http://demonstrations.wolfram.com site—otherwise, credit is given to the original source. We then freely modified or transformed some of these objects to illustrate our goals better.

The topmost image of this notebook is part of a sliced, false-color image of nanoflowers made from zinc-doped tin oxide (downloaded from http://www.wired.com/wiredscience and sliced with Mathematica).

.. Let the curtain rise—slicing 2D images

Our first example illustrates how to reveal a given image automatically. The animation should start after evaluating the following example cell and pressing the Play button.

Animate[
ImageTake[,All,{1,horizontal}],{horizontal,1,266},
AnimationRunning->False,AnimationRepetitions->1]

Exercise.  Try and experiment with the controls (play, pause, faster, slower, forward or backward) in the above window. You can grab and drag the  slider manually as well.

In the following similar command, the Play button is somewhat hidden, but you can still drag the slider by yourself.

Manipulate[
ImageTake[,All,{1,horizontal}],
{horizontal,1,ImageDimensions[][[1]]}
]

By pressing the plus button   in the above window, more controls will appear that you have just seen in the case of the Animate command.

Explanation: details and variants

The core command in the examples is ImageTake

?ImageTake

to cut out a specified region of an image:

ImageTake[,{90,180},{95,135}]

With the All option in ImageTake[image,All,{1,horizontal}] we do not have to worry about the true image dimensions, i.e., all rows will be taken into account.

Nevertheless, we can use ImageDimensions to determine the size of an image

?ImageDimensions

ImageDimensions[]

This gives you a list containing the horizontal and vertical dimensions. The number 266 is then used in the Animate or Manipulate commands to specify where the slider should stop: the command ImageDimensions[][[1]] thus simply returns the first element of the list {266, 190}. Hence,

Manipulate[ImageTake[,All,{1,horizontal}],{horizontal,1,ImageDimensions[][[1]]}]

is now equivalent to

Manipulate[ImageTake[,All,{1,horizontal}],{horizontal,1,266}]

The other key commands above have been Manipulate  and Animate, into which ImageTake is embedded:

?Manipulate

?Animate

With these commands you can easily create interactive computations with sliders or buttons. Some simple illustrations will follow (only with Manipulate, because Animate is analogous).

A “continuous” increment of a variable from 1 to 10:

Manipulate[n,{n,1,10}]

Increment in discrete steps from 1 to 10 (with step-size 1):

Manipulate[n,{n,1,10,1}]

You can also change the name of the slider. Moreover, the default starting value is now 2, but the range is again the interval from 1 to 10 in discrete steps.

Manipulate[n,{{n,2,"number"},1,10,1}]

The buttons can have non-numeric values as well (notice that quotation marks are used to denote strings):

Manipulate[n+2013,{n,{1,α,∞, "some text"}}]

Exercise.  Why is ∞  displayed instead of ∞+2013?

There is no restriction on the data types: even a graphics can be a button or part of a formula. And Mathematica can perform addition with graphical objects—showing how flexible the system is.

Exercise.  Before evaluating the following line, try and predict the output.

Manipulate[n+,{n,{1,,α,∞, Plot[Sin[x],{x,0,π}]}}]

With a simple modification of one of the examples above, you can move the curtain vertically:

Manipulate[ImageTake[,{1,vertical},All],{vertical,190,1},ContentSize->(6/5)ImageDimensions[]]

Exercise.  Why does the curtain go upward and not downward as the slider is moved to the right?

Here, the ContentSize->(6/5)ImageDimensions[] option was added to prevent the outer window from shrinking. Compare the above command with

Manipulate[ImageTake[,{1,vertical},All],{vertical,190,1}]

Exercise.  What is the meaning of the AnimationRunning->False and AnimationRepetitions->1 options in the first animation example?

.. Medical imaging in 3D

In newer Mathematica versions, support for 3D images is fully incorporated into the system. As an example, let us consider the following part of a human foot.

foot=;

Exercise.  By using the mouse, try and rotate the 3D object. Your instructor will also tell you how to zoom the image.

The following command creates some slices.

Manipulate[
ImageTake[,{startingslice,Min[startingslice+layerthickness,128]},{1,128},{1,128}],
{startingslice,1,108,1},{layerthickness,20,100,1}]

Exercise.  By similarly manipulating (rotating, zooming or slicing) this 3D medical image, , can you recognize what it represents? How many voxels (= 3D pixels) does it have?

Explanation: details and variants

Of course, we have used ImageDimensions

ImageDimensions[foot]

before setting up the example to figure out the upper bounds for the sliders: the image consists of (128^3)=2097152 voxels, that is, more than 2 megavoxels.

Notice how easy it is to create 2 sliders with Manipulate:

Manipulate[{startingslice,Min[startingslice+layerthickness,128]},{startingslice,1,108,1},{layerthickness,20,100,1}]

Let us examine the vertical range which is cut out by ImageTake. We have used self-explanatory variable names for determining the position of the starting slice, and for the thickness of the layer our “scanner” sees.

Manipulate[{startingslice,Min[startingslice+layerthickness,128]},{startingslice,1,108,1},{layerthickness,20,100,1}]

The Min command guarantees that the larger component of the vertical slice never exceeds 128.

In light of the previous 2D examples, now it is not hard to understand the 3D extension: ImageTake can seamlessly be extended to handle 3D images.

Hint.  The answer to the last exercise can be found in your mouth.

.. Graphics primitives in 2D: circles

The following command produces 72 random circles having various colors, and arranges them in a grid.

Grid@Table[
Graphics@Table[
{
RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink, Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]
},{12}],
{2},{3}]

Explanation: details and variants

Notice first that we have used the @ symbol (pronounced as “at”) to reduce the number of square brackets: in Mathematica, Command[argument] is equivalent to Command@argument.

To draw a circle, you can give the coordinates and the radius, for example, as

Circle[{-1,1},3]

?Circle

but you need the Graphics command to actually display this graphics primitive:

Graphics@Circle[{-1,1},3]

In the example, the coordinates of the centers and the radii are random numbers between 0 and 1

?RandomReal

so this is a “random” circle:

Graphics@Circle[{RandomReal[],RandomReal[]},RandomReal[]]

Next we specify the possible colors: Lighter@Purple, for example, is a lighter shade of the built-in purple color. Notice that colors are represented differently within Mathematica:

FullForm[Red]

FullForm[Darker@Yellow]

RandomChoice just picks a random element of the list of 7 colors (try and evaluate the command several times):

RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink,Blue,Darker@Blue}

So one random circle with a random color:

Graphics@{RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink,Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]}

We can use the Table command to create lists:

?Table

In our case, a nested list of 12 elements is created by the inner Table command: each sublist is a color specification plus a circle object.

Table[{RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink,Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]},{12}]

Let us display the above:

Graphics@Table[{RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink,Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]},{12}]

The outer Table command creates a matrix of the previously defined objects:

Table["something",{2},{3}]

Finally, Grid arranges these objects into a grid, according to the matrix dimensions, and we are ready:

Grid@Table["something",{2},{3}]

.. Graphics primitives in 2D: rectangles, disks and sliders

Column@
{
Grid@
{
{Graphics[{Red,Rectangle[]},ImageSize->30],Slider[Dynamic@red,Appearance->"Labeled"]},{Graphics[{Green,Rectangle[]},ImageSize->30],Slider[Dynamic[green],Appearance->"Labeled"]},
{Graphics[{Blue,Rectangle[]},ImageSize->30],Slider[Dynamic[blue],Appearance->"Labeled"]}
},
Dynamic@Graphics@{RGBColor[red,green,blue],Disk[]}
}

Exercise.  Modify the above code to get a result similar to this figure:

Explanation: details and variants

After the previous examples, the following graphics primitive is easy to understand (the ImageSize command should be self-explanatory):

Graphics[{Red,Rectangle[]},ImageSize->30]

The interesting new command is Slider here, producing a slider that you can move. Here the starting value within the [0,1] interval is set to 0.3:

Slider[0.3]

Of course you want to store the current value of the slider. We can do this by the Dynamic command: it assigns the current slider value to a variable named “red”, and dynamically updates “red” as the slider is varied.

Slider[Dynamic@red]

Now we display the value of the “red” variable as well:

Slider[Dynamic@red,Appearance->"Labeled"]

Let us connect the colored square to the slider in a list:

{Graphics[{Red,Rectangle[]},ImageSize->30],Slider[Dynamic@red,Appearance->"Labeled"]}

Since we have 3 sliders, let us arrange them into a grid:

Grid@{{Graphics[{Red,Rectangle[]},ImageSize->30],Slider[Dynamic@red,Appearance->"Labeled"]},{Graphics[{Green,Rectangle[]},ImageSize->30],Slider[Dynamic[green],Appearance->"Labeled"]},{Graphics[{Blue,Rectangle[]},ImageSize->30],Slider[Dynamic[blue],Appearance->"Labeled"]}}

Now we display the colored disk. Since we also use Dynamic below, you can change its color by any of the above 3 sliders.

Dynamic@Graphics@{RGBColor[red,green,blue],Disk[]}

The final Column command just aligns the 3 sliders and the disk vertically as a group.

.. Application: design your face. Part I

Graphics@
{
Red,Thick,Circle[{0,0},1],Black,Disk[{-0.5,0.5},0.2],Yellow,Dashed,Circle[{0.5,0.5},0.2],Green,Polygon[{{0,-0.5},{-0.5,0},{0.5,0}}]
}

Explanation: details and variants

The above code is very easy to understand: just read sequentially.

We instruct Mathematica to draw some graphics primitives. First, draw a red circle of the given size by using thick line type. Then it should draw a black disk (notice the difference between “circle” and “disk”). Then a yellow circle should follow by using dashed line type. Finally, it should produce a green (filled) polygon with 3 vertices (each of them is specified by 2 coordinates).

Exercise.  Try and modify the above graphics primitives to make a more interesting face.

.. Application: design your face. Part II

Now let us add some more controls so that the user can experiment with the 7 sliders to create their favorite character.

Manipulate[
Plot[
-t+(-1+2 t) (x^2),{x,-1,1},
Axes->False,
PlotStyle->Black,
PlotLabel->Column[{Style["  I'm sad.",GrayLevel[t]],Style["I'm happy.",GrayLevel[1-t]]}],Epilog->{Circle[{0,1},3],Line[{{0,noseposition},{0,noseposition+noselength}}],RGBColor[{red,green,blue}],Disk[{1,2},eyeradius],Disk[{-1,2},eyeradius]},
PlotRange->{{-4,4},{-4,4}},AspectRatio->1
],
{{t,0.9,"happiness factor"},0,1},
{{eyeradius,0.5,"eye size"},0,1},
{{red,0.1,"eye color: red component"},0,1},
{{green,0.2,"eye color: green component"},0,1},
{{blue,0.6,"eye color: blue component"},0,1},
{{noseposition,0.6,"nose position"},0.1,1.7},
{{noselength,0.6,"nose length"},0.1,2}
]

Explanation: details and variants

The structure of the above example is simply: manipulate a plot with 7 controls.

Let us understand the controls first. For simplicity, we consider just the first and the last controls.

The first control is {{t,0.9,"happiness factor"},0,1} responsible for the happiness factor with values between 0 and 1 and with default value 0.9. The corresponding variable is t, which is controlled by the happiness slider. The last control is {{noselength,0.6,"nose length"},0.1,2} determining the value of the noselength variable; its name on the final figure is "nose length", given as a string; it can take values between 0.1 and 2; finally, its predefined value is 0.6.

Let us focus on the remaining part:

Plot[-t+(-1+2 t) (x^2),{x,-1,1},Axes->False,PlotStyle->Black,
PlotLabel->Column[{Style["  I'm sad.",GrayLevel[t]],Style["I'm happy.",GrayLevel[1-t]]}],Epilog->{Circle[{0,1},3],Line[{{0,noseposition},{0,noseposition+noselength}}],RGBColor[{red,green,blue}],Disk[{1,2},eyeradius],Disk[{-1,2},eyeradius]},PlotRange->{{-4,4},{-4,4}},AspectRatio->1]

Upon evaluating the above command directly, we get some error messages (in a red box), because no predefined values have been given to the variables.

Therefore we temporarily set some values with the With command for testing purposes so that we can deconstruct the Plot command completely, and see the effects of each part. Notice that you should use the defining equality symbol = within With. It is also important that the assignment t=0.9 is only local, that is, the value of t outside the With command is not affected.

To create the mouth, we draw a parabola segment between -1≤x≤1. We do not need any axes, and we want it in black.

With[{t=0.9},Plot[-t+(-1+2 t) (x^2),{x,-1,1},Axes->False,PlotStyle->Black]]

We would like to display the mouth in a window. The horizontal coordinates of the window range between (-4,4), the vertical coordinates between (-4,4). (So which is the horizontal and which is the vertical range?) If you modify the AspectRatio command, the mouth is distorted.

With[{t=0.9},Plot[-t+(-1+2 t) (x^2),{x,-1,1},Axes->False,PlotStyle->Black,PlotRange->{{-4,4},{-4,4}},AspectRatio->1]]

Now we add some label to the plot. The label consists of two strings (sad and happy) in quotation marks arranged in a column form. When the value of the variable t is modified by the slider, a fading effect is created by the GrayLevel commands.

With[{t=0.9},Plot[-t+(-1+2 t) (x^2),{x,-1,1},Axes->False,PlotStyle->Black,
PlotLabel->Column[{Style["  I'm sad.",GrayLevel[t]],Style["I'm happy.",GrayLevel[1-t]]}],PlotRange->{{-4,4},{-4,4}},AspectRatio->1]]

Finally, with the Epilog command, we add some more graphics primitives after the main plot has been drawn. The first Circle command within Epilog draws the head. The Line command then draws the nose. The RGBColor command sets the colors for the remaining primitives: for the right eye and for the left eye, both given as disks.

With[{t=0.9,eyeradius=0.5,red=0.1,green=0.2, blue=0.6,noseposition=0.6,noselength=0.6},Plot[-t+(-1+2 t) (x^2),{x,-1,1},Axes->False,PlotStyle->Black,
PlotLabel->Column[{Style["  I'm sad.",GrayLevel[t]],Style["I'm happy.",GrayLevel[1-t]]}],Epilog->{Circle[{0,1},3],Line[{{0,noseposition},{0,noseposition+noselength}}],RGBColor[{red,green,blue}],Disk[{1,2},eyeradius],Disk[{-1,2},eyeradius]},PlotRange->{{-4,4},{-4,4}},AspectRatio->1]]

.. Graphics primitives in 3D: cubes

Graphics3D@
{
Opacity[.5],
Raster3D@RandomReal[1,{5,5,5,3}]
}

Graphics3D[
{
EdgeForm[Opacity[.3]],
Table[
{Hue[RandomReal[],.8],Cuboid[{#[[1]],#[[2]],-n}]}&/@
Tuples[Range[-n,n],2],
{n,0,10}]
},
Lighting->"Neutral",Boxed->False]

Explanation: details and variants

In the first example, the RandomReal command creates some random data representing the 5x5x5=125 cubes to be displayed. The Raster3D command just tells Mathematica to interpret the nested list produced by RandomReal as cubes.

Raster3D[RandomReal[1,{5,5,5,3}]]

Since this is a 3-dimensional graphics, instead of Graphics we use Graphics3D to display it.

Exercise.  Try and experiment with the Opacity parameter with values between 0 and 1 (notice that .5 is just 0.5).

In the second example, we make the edges of the cubes less visible by using EdgeForm[Opacity[.3]]. We specify the type of light sources by Lighting->”Neutral”,  and we do not want to see a bounding box around the 3D graphics (Boxed->False).

The remaining piece of the code

Table[{Hue[RandomReal[],.8],Cuboid[{#[[1]],#[[2]],-n}]}&/@Tuples[Range[-n,n],2],{n,0,10}]

produces a large output, hence it is suppressed.

The outer Table command gives the number of layers (from 0 to 10, that is, 11 layers).

Let us examine the first layer, for example. (Which is the first layer on the graphics?)

With[{n=1},{Hue[RandomReal[],.8],Cuboid[{#[[1]],#[[2]],-n}]}&/@Tuples[Range[-n,n],2]]

The 1st layer contains 9 cubes. Each cube has a random color code (Hue) and the appropriate coordinates.

With Tuples we can generate a nested list, consisting of sublists of length 2 in our case. In the first layer of the pyramid, each element of each sublist is either -1, or 0, or 1. Tuples generates all the possibilities.

With[{n=1},Tuples[Range[-n,n],2]]

Finally, we use the #[[1]] and #[[2]] symbols together with the &/@ symbols to take the first and second elements of each sublist generated by Tuples, and substitute those coordinates in the first and second arguments of Cubes. The /@ operator tells Mathematica to repeat this procedure with each sublist in the nested list.

Exercise.  How many little cubes are there altogether in the pyramid?

.. Graphics primitives in 3D: spheres and cones

Graphics3D@Table[
{
Hue[RandomReal[]],Sphere[RandomReal[1,{3}],RandomReal[0.1]]
},
{400}]

Graphics3D[
Sphere[#,(1/(Sqrt[2]))]&/@
Select[Tuples[Range[-3,3],3],Mod[Total[#],2]==0&]
]

Graphics3D@Table[
{
EdgeForm[Opacity[.3]],Hue[RandomReal[]],Cone[RandomReal[10,{2,3}]]
},
{20}]

Graphics3D[
{
Opacity[.3],EdgeForm[Opacity[.3]],Table[Cone[{{0,0,0},{0,0,2r}},r],{r,1,5}]
},
Boxed->False
]

Explanation: details and variants

In the first example, the Table command creates a nested list of 400 elements. Let us reduce the number of elements to 10 for simplicity:

Table[{Hue[RandomReal[]],Sphere[RandomReal[1,{3}],RandomReal[0.1]]},{10}]

Each sublist will represent a sphere:

Graphics3D@{Hue[RandomReal[]],Sphere[RandomReal[1,{3}],RandomReal[0.1]]}

Each sphere has a random color, a random center (consisting of 3 random coordinates), and a random radius.

Exercise.  Determine the intervals in which the color, the center coordinates and the radius are located.

In the second example, we generate a nested list by Tuples representing the coordinates of the sphere centers.

Tuples[Range[-3,3],3]

As we already mentioned before, Tuples generates all the possibilities, so we use the Select command to keep only some of them satisfying the Mod[Total[#],2]==0& condition: this way the array of spheres will have a regular packing structure. In more detail, we have

?Select

To select only the even numbers you can write

Select[{1,2,3,4,5,6,7,8,9,10},EvenQ]

or

Select[{1,2,3,4,5,6,7,8,9,10},Mod[#,2]==0&]

because

?Mod

{Mod[1,2],Mod[2,2],Mod[3,2],Mod[4,2],Mod[5,2],Mod[6,2], Mod[7,2],Mod[8,2],Mod[9,2],Mod[10,2]}

The Total command sums the elements of a list:

Total[{1,2,3,4}]

So

Select[Tuples[Range[-3,3],3],Mod[Total[#],2]==0&]

keeps only those sphere centers for which the coordinate sum is even.

Note that in the Mod[Total[#],2]==0& function, we have used the == symbol to test equailty. Instead of ==, you cannot use the = or := symbols.

All the spheres will have a radius equal to 1/(Sqrt[2]):

Sphere[#,(1/(Sqrt[2]))]&/@Select[Tuples[Range[-3,3],3],Mod[Total[#],2]==0&]

Again, the Sphere command is applied to each element to the (nested) list produced by Select: this is achieved by the command[#]&  /@ nestedlist construction. Here, sublists of the nested list are substituted in place of the # mark.

To summarize, in Mathematica terminology, function[#]& is a pure function (# denotes the “variable” into which we substitute something; & is just an “end of the pure function” mark), while the /@ command is equivalent to the Map command (that is, elementwise application of some function to some data).

Exercise.  Study how the Cone command works in the third example. Then you should immediately understand the position of the 5 cones in the fourth example.

.. Graphics primitives in 3D: polyhedra

Grid@
{
Table[
Graphics3D@{Yellow,Opacity[.9],PolyhedronData[p,"Faces"]},
{p,{"Dodecahedron","Icosahedron","Cube","Tetrahedron","Octahedron"}}
]
}

Show[PolyhedronData["Spikey"],ImageSize->200,Boxed->False]

Explanation: details and variants

The first example arranges some 3D graphics into a grid. The Table command is used here to substitute the names of the 5 Platonic solids into the variable p.

Let us pick only one member:

Graphics3D@{Yellow,Opacity[.9],PolyhedronData["Octahedron","Faces"]}

The PolyhedronData command knows a lot about various polyhedra.

Exercise.  Study the help page of the PolyhedronData command. Also have a look at the Details section.

The second example displays the famous “spikey” polyhedron, being the official Mathematica logo in the first versions.

.. Water waves

Manipulate[
Plot3D[((Sin[(x^2)+(y^2)])/((((x^2)+(y^2)))^parameter))//Evaluate,{x,-2,2},{y,-2,2},BoxRatios->1,Mesh->None,PerformanceGoal->"Quality"],
{parameter,0,1}]

Explanation: details and variants

The Plot3D command displays a 3D graphics that can be described by the graph of a two-variable function. (Now you do not have to understand the particular function ((Sin[(x^2)+(y^2)])/((((x^2)+(y^2)))^parameter)) used here.)

When you use Plot or Plot3D to display symbolic formulae, it is sometimes necessary to use the Evaluate command (but the rules when to use it are not easy to describe). So if you get error messages like

Plot[D[Sin[x],x],{x,0,1}]

you may want to consider using Evaluate:

Plot[Evaluate[D[Sin[x],x]],{x,0,1}]

Remember, the command1//command2 syntax is the same as command2[command1].

Exercise.  What is the role of the {x,-2,2},{y,-2,2} part of the code? Then try to set Mesh->True. Also explain PerformanceGoal->”Speed”. In what situations would you use this last option?

.. Obama’s flag rotated

If you are concerned about the previous example being too mathematical, then, with only a simple addition, you can turn it into a wavy flag.

Manipulate[
Plot3D[
((Sin[(x^2)+(y^2)])/((((x^2)+(y^2)))^wavyness)),{x,-3wavyness,1},{y,-1,2},
BoxRatios->1,PlotRange->{-2,2},Mesh->None,PerformanceGoal->"Quality",
PlotStyle->Texture[Rotate[,π/2]],
Axes->False,Boxed->False,ViewPoint->{0.5,-.5,3}
],
{wavyness,-0.4,.5}]

Remember that you can also rotate the whole 3D image at any stage with your mouse.

Explanation: details and variants

As opposed to the previous example, we have adjusted the range of the first variable a bit ({x,-3wavyness,1}), extended the plot range (PlotRange->{-2,2}), chosen a different viewpoint (ViewPoint->{0.5,-.5,3}), and cleared the axes and the bounding box (Axes->False,Boxed->False) to make the output a little prettier.

However, the main novelty here is the PlotStyle->Texture[...] part: an arbitrary 2D image can be used to serve as a texture deformed onto the surface. Now you have a tool to easily create spectacular figures: first by creating a surface, then applying a texture. We will meet the Texture directive again soon.

The last twist in the code is Rotate, turning the President by the specified angle π/2 on the surface. But Mathematica is flexible, so you can rotate any Mathematica expression, not just Barack Obama.

For example, a text.

Rotate["What is the rotation angle in degrees here?",1]

Exercise.  Compute the answer to the above question.

Or a plot.

Manipulate[Rotate[Plot[Sin[x],{x,0,1}],angle],{angle,0,2π},ContentSize->{500,450}]

Or even complete Manipulate objects, iteratively, with sliders and content.

Nest[Manipulate[Rotate[#,angle],{angle,0,2π}]&,"Try and move each slider separately. Do not be afraid of the strange temporary variable names.",3]

In the last piece of code, we have applied the Nest command to evaluate the same function several times (in the example, 3 times, so the level of nesting is 3).

If your function does not have any additional parameters, you can simply write

Nest[myfunction,"initial argument",3]

but if myfunction depends on some parameter, then it is convenient to use again a pure function

Nest[myfunction[#, parameter]&,"initial argument",3]

In the example, the corresponding parameter is of course the rotation angle, while myfunction is a Manipulate object acting on Rotate.

.. More flags

The following example may require Internet connectivity.

countryFlag[name_]:=
Labeled[ImageResize[CountryData[name,"Flag"],50],Text[Style[name,20]],Right];
Flags[listOfCountries_]:=
Column[countryFlag[#]&/@listOfCountries,ItemSize->15,Frame->True,Background->Gray];
Flags[{"France","Hungary","Italy","Japan","Russia","United Kingdom"}]

Explanation: details and variants

The example above is composed of several commands: we can use the ; (semicolon) to create a compound command. So now we analyze the code sequentially.

The last command

Flags[{"France","Hungary","Italy","Japan","Russia","United Kingdom"}]

just calls the Flags function defined earlier, with some countries as arguments.

We remark that traditionally we use lowercase names for user-defined functions and we know that in Mathematica all built-in commands are capitalized. But, of course, as the example shows, you can capitalize your own function as long as its name does not conflict with any other existing built-in symbol.

The second command is the actual definition of the Flags function.

Flags[listOfCountries_]:=Column[countryFlag[#]&/@listOfCountries,ItemSize->15,Frame->True,Background->Gray]

The symbol := here is the so-called delayed assignment, typically used when setting up some function with arguments, together with the _ (Blank) symbol. Let us give an example.

Suppose you want to define your function myfunction that computes the square of the input. Then you may write

myfunction[argument_]:=(argument^2)

and it is working as expected:

myfunction[12]

myfunction[x]

or even with the Spikey

myfunction[+1]

However, the following definition does not seem to work.

malfunction[argument]:=(argument^2)

malfunction[x]

malfunction[12]

Actually, it only recognizes argument as an argument:

malfunction[argument]

The reason that the above definition does not work as expected is the omission of the Blank symbol from the definition. Note that malfunction[argument]:= defines malfunction only when the argument is literally the expression argument. If you want argument to represent any expression in the function definition, you should use the blank symbol, just as in myfunction. In other words, the pattern something_ can represent any Mathematica expression—and you have named it as something, so that you can refer to it later when necessary.

We remark that both symbols  = and := can be used in definitions. Let us point out however that there is a slight (but sometimes important) difference between the = and the := assignments. When you write

immediate=12

the right-hand side is immediately evaluated. However, upon writing

delayed:=12

the expression on the right is evaluated only when the variable delayed is used. The following example clarifies the difference.

immediate=RandomReal[]

{immediate,immediate,immediate}

So the value of immediate has been fixed: it is that particular random number. But

delayed:=RandomReal[]

{delayed,delayed,delayed}

so the value of delayed is a different random number each time the variable is accessed.

After these remarks, let us return to the original example. It is now clear that the Flags function

Flags[listOfCountries_]:=Column[countryFlag[#]&/@listOfCountries,ItemSize->15,Frame->True,Background->Gray]

just applies the countryFlag function to each element of the list listOfCountries given as argument by the user. The output of the countryFlag function is arranged in a column format with some graphical elements added.

So the last part we have to understand is

countryFlag[name_]:=Labeled[ImageResize[CountryData[name,"Flag"],50],Text[Style[name,20]],Right]

The CountryData function accepts a country name as an argument and downloads some data (in this case, the flag) from the Internet. The country flag, as an image, is suitably resized, and the country name is added as a label.

?Labeled

Finally, since we do not want the variable and function names to interfere with our later work, we can delete their definition from Mathematica, for example by

ClearAll[myfunction,malfunction,immediate,delayed]

Now Mathematica no longer knows about the given definition:

?myfunction

.. Interlocking tori

Animate[
ParametricPlot3D[
{{4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},{8+(3+Cos[v]) Cos[u],3+Sin[v],4+(3+Cos[v]) Sin[u]}},
{u,0,2 Pi},{v,0,2 Pi},
PlotStyle->{Purple,Yellow},Axes->False,Boxed->False,ViewPoint->{1,viewpoint,1},PerformanceGoal->"Quality"
],
{viewpoint,-1,1},
ContentSize->{400,450},
AnimationRunning->False,AnimationRepetitions->1]

Explanation: details and variants

The essential part in the above animation is ParametricPlot3D. Let us create only one torus first.

ParametricPlot3D[{4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},{u,0,2 Pi},{v,0,2 Pi},PlotStyle->Specularity[White,50],Mesh->None]

Each surface can be described by two parameters, in our case, by u and v. Their range is the interval [0,2π].

We do not draw any mesh, and add some special light source information by the Specularity command.

Exercise.  By using some elementary trigonometry, you can explain why the set {4+(3+Cos[v]) Sin[u], 4+(3+Cos[v]) Cos[u], 4+Sin[v]} describes the surface of a torus. What are the radii of the circles when you make cross sections?

Exercise.  Can you create a sphere with ParametricPlot3D?

In the animation, we generate two tori, {4+(3+Cos[v]) Sin[u], 4+(3+Cos[v]) Cos[u], 4+Sin[v]} and {8+(3+Cos[v]) Cos[u], 3+Sin[v], 4+(3+Cos[v]) Sin[u]}. We color them differently with PlotStyle->{Purple,Yellow}. We do not draw axes, neither a bounding box, and in the example below we want a faster animation (PerformanceGoal->”Speed” versus PerformanceGoal->”Quality”).

The tori will “move” because we continuously change the Viewpoint as the slider is moving (in fact, the tori are fixed within the coordinate frame).

Animate[ParametricPlot3D[{{4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},{8+(3+Cos[v]) Cos[u],3+Sin[v],4+(3+Cos[v]) Sin[u]}},{u,0,2 Pi},{v,0,2 Pi},PlotStyle->{Purple,Yellow},Axes->False,Boxed->False,ViewPoint->{1,viewpoint,1},PerformanceGoal->"Speed"],{viewpoint,-1,1},ContentSize->{400,450},AnimationRunning->False,AnimationRepetitions->1]

Exercise.  Experiment with different viewpoints.

With slight modifications, we can also deform the rings.

Animate[ParametricPlot3D[{{4+(3+Abs[viewpoint]Cos[v]) Sin[u],4+(3+Abs[viewpoint]Cos[v]) Cos[u],4+Abs[viewpoint]Sin[v]},{8+Abs[viewpoint](3+Cos[v]) Cos[u],3+Sin[v],4+(3+Cos[v]) Sin[u]}},{u,0,2 Pi},{v,0,2 Pi},PlotStyle->{Purple,Yellow},Axes->False,Boxed->False,ViewPoint->{1,viewpoint,1},PerformanceGoal->"Speed"],{viewpoint,-1,1},ContentSize->{500,400},AnimationRunning->False,AnimationRepetitions->1]

.. Design your ring

Manipulate[
ParametricPlot3D[
{4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},
{u,0,2 Pi},{v,0,2 Pi},
Mesh->None,Axes->False,Boxed->False,PerformanceGoal->"Quality",
PlotStyle->
Texture@Grid@Table[
Graphics@Table[
{RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink, Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]},
{number}],
{2},{3}]
],
{{number,10,"draw more circles"},1,40}]

Explanation: details and variants

The current example illustrates how simple it is to build a more complex code from previously defined pieces.

The inner part of the above code is now clear: we use again ParametricPlot3D to display the same torus (or ring, if you like) as in the previous example.

But we also use the colored circles (the piece with Grid@Table[...], see our earlier example with the 72 circles): this 2D graphics is applied as a texture on the torus, just as in the Obama and the flag example, with the PlotStyle->Texture[...] part.

The whole construction is embedded into a Manipulate, so that we can change the number of circles drawn as the slider is varied.

Let us finally add one more feature: in the code below, the user can change also the viewpoint.

Manipulate[ParametricPlot3D[{{4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},{8+(3+Cos[v]) Cos[u],3+Sin[v],4+(3+Cos[v]) Sin[u]}},{u,0,2 π},{v,0,2 π},Mesh->None,Axes->False,Boxed->False,ViewPoint->{1,viewpoint,1},PlotStyle->Texture@Grid@Table[Graphics@Table[{RandomChoice@{Lighter@Purple,Darker@Yellow,Red,Pink,Darker@Pink, Blue,Darker@Blue},Circle[{RandomReal[],RandomReal[]},RandomReal[]]},{number}],{2},{3}],PerformanceGoal->"Speed"],{{number,2,"draw more circles"},1,10},{viewpoint,-1,1}]

.. Homotopy: do we live on a sphere or on a doughnut?

Homotopy is a mathematical term for continuous deformation.

Manipulate[
ParametricPlot3D[
α{Sin[u] Sin[v], Cos[u]Sin[v], Cos[v]}+(1-α){4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]},
{u,0,2 Pi},{v,0,2 Pi},
Mesh->None,Boxed->False,Axes->False,PerformanceGoal->"Quality",PlotStyle->Texture[]
],
{α,0.999,0}]

Explanation: details and variants

In the example we have two objects: the torus {4+(3+Cos[v]) Sin[u],4+(3+Cos[v]) Cos[u],4+Sin[v]} we met earlier, and a sphere {Sin[u] Sin[v], Cos[u]Sin[v], Cos[v]} (you met earlier if you successfully solved one of the exercises above).

We then form the convex combination of these two objects by

α (Subscript[object, 1])+(1-α)(Subscript[object, 2])

When α runs through the interval [0,1], and the above objects are graphical objects, then this useful trick, the convex combination, is nothing else geometrically than a homotopy. In other words, as α changes, (Subscript[object, 1]) is continuously deformed into (Subscript[object, 2]).

At the end, some texture is applied to make the graphics a bit more colorful.

Exercise.  Choose two 3D graphics you like, and create a homotopy between them to visualize continuous deformation.

.. Earth eclipse does exist

In the following (fictional!) example we deform our beloved planet.

Manipulate[
Plot3D[
{(Sqrt[1-(x^2)-(y^2)]),-(Sqrt[1-(x^2)-(y^2)])},{x,-1,1},{y,-1,1},
PlotRange->{-1,1},Mesh->None,Boxed->False,
Axes->False,PlotStyle->Texture[],Background->Black,
RegionFunction->Function[{x,y,z},eclipse<(x^2)+(y^2)<1-eclipse],
PerformanceGoal->"Quality",ImageSize->{400,400},AspectRatio->1
],
{eclipse,0.5,0}]

Explanation: details and variants

The skeleton of the example is

Plot3D[{(Sqrt[1-(x^2)-(y^2)]),-(Sqrt[1-(x^2)-(y^2)])},{x,-1,1},{y,-1,1}]

to create an upper and a lower hemisphere that fit together.

Exercise.  Explain why the function z=(Sqrt[1-(x^2)-(y^2)]) defines an upper hemisphere.

We can add an AspectRatio, to make the shape more proportional:

Plot3D[{(Sqrt[1-(x^2)-(y^2)]),-(Sqrt[1-(x^2)-(y^2)])},{x,-1,1},{y,-1,1},AspectRatio->1]

With the RegionFunction command, you can cut out some regions from the plot: points in the (x,y) plane are ignored (hence the plot will be empty there) if they do not satisfy the double inequality 0.25<(x^2)+(y^2)<1-0.25.

Plot3D[{(Sqrt[1-(x^2)-(y^2)]),-(Sqrt[1-(x^2)-(y^2)])},{x,-1,1},{y,-1,1},AspectRatio->1,RegionFunction->Function[{x,y,z},0.25<(x^2)+(y^2)<1-0.25]]

Finally, with a Manipulate, we can interactively change the region to be kept or cut out. The Earth texture has been downloaded from the Internet and copy and pasted in this Mathematica notebook directly.

Since we do not need mesh, axes or boxes around the planet, only a black background, we set Mesh->None, Boxed->False, Axes->False, Background->Black.

.. Lena or the mandrill?

Manipulate[
ImageAdd[ImageMultiply[ ,fading],ImageMultiply[,1-fading]],
{fading,0,1},ContentSize->200]

Explanation: details and variants

In the example we superimpose two images. As their name suggest, ImageAdd and ImageMultiply are analogous operations to the ordinary addition and multiplication but acting on images.

The situation here is completely analogous to the one with the sphere and the doughnut. There we used the homotopy

α (Subscript[object, 1])+(1-α)(Subscript[object, 2])

Here, the parameter α is the fading parameter controlled by Manipulate; the addition is ImageAdd, while the multiplication is ImageMultiply.

Exercise.  Download two interesting images from the Internet, copy and paste them into this notebook, then superimpose them with a fading effect.

.. Image tiling

tiles=ImagePartition[,100]

Grid[tiles,Spacings->{0,0}]

tilelist=Flatten[tiles]

ImageAssemble@Partition[
RandomSample[tilelist,Length[tilelist]],Length[tiles[[1]]]
]

Explanation: details and variants

The above command ImagePartition[..., 100] decomposes the given image into subimages of size 100x100 pixels, and puts them into a list. We store the list in the tiles variable.

We can assemble the tiles into the original image with

Grid[tiles]

but in the example, we did not want any spaces between the tiles, hence we set Spacings->{0,0}.

The tiles variable is represented internally in Mathematica as a nested list:

tiles//Shallow

The Flatten command destroys the nested structure and produces a one-level list:

tilelist=Flatten[tiles]

Finally, we determine the length of the list tilelist by

Length[tilelist]

and do a random reordering of this list:

RandomSample[tilelist,Length[tilelist]]

If we know the number of rows of the matrix represented by tiles

Length[tiles[[1]]]

then we can regenerate the nested list structure present in the original tiles list by using Partition: each sublist will have length equal to Length[tiles[[1]]].

Partition[RandomSample[tilelist,Length[tilelist]],Length[tiles[[1]]]]

The above nested list of course consists of the shuffled version of the image, assembled by ImageAssemble as

ImageAssemble@Partition[RandomSample[tilelist,Length[tilelist]],Length[tiles[[1]]]]

Alternatively, we can use Grid here again as above:

Grid[Partition[RandomSample[tilelist,Length[tilelist]],Length[tiles[[1]]]],Spacings->{0,0}]

Let us free up the variable names we have used:

ClearAll[tiles,tilelist]

.. What is the time? Part I

Dynamic@Refresh[
ClockGauge[
AbsoluteTime[],GaugeStyle->Red,Method->{"SegmentWidth"->.15,"SegmentSeparation"->.08,"SegmentSlant"->0}
],
UpdateInterval->1]

Explanation: details and variants

The system time is obtained by

AbsoluteTime[]

Its result is the number of seconds since the beginning of January 1, 1900 in our time zone.

The ClockGauge command

ClockGauge[AbsoluteTime[],GaugeStyle->Red,Method->{"SegmentWidth"->.15,"SegmentSeparation"->.08,"SegmentSlant"->0}]

is one of the newer Mathematica commands that produce gauges and meters for displaying information. With the GaugeStyle and Method options we can fine-tune the gauge appearance.

The Dynamic@Refresh[..., UpdateInterval->1] part asks Mathematica to update the inner part (that is, the clock gauge) in each second.

.. What is the time? Part II: the spherical clock

Dynamic@Plot3D[
(Sqrt[1-(x^2)-(y^2)]),{x,-1,1},{y,-1,1},
PlotRange->{0,1},Mesh->None,Boxed->False,Axes->False,PlotStyle->Texture[Refresh[ClockGauge[AbsoluteTime[],GaugeStyle->Red,Method->{"SegmentWidth"->.15,"SegmentSeparation"->.08,"SegmentSlant"->0}],UpdateInterval->1]
],
Background->Black,RegionFunction->Function[{x,y,z},(x^2)+(y^2)<1]]

Explanation: details and variants

We have used the upper hemisphere from the Earth eclipse example as a surface (with black background), on which the clock gauge from the previous example is applied as a texture.

Exercise.  What is the region represented by the function in RegionFunction here?

.. Design your solar system

Animate[
ParametricPlot3D[
{
{2Cos[ϕ]Cos[θ],2Sin[ϕ]Cos[θ],2Sin[θ]},
{5Cos[3/2revolution]+1/2Cos[ϕ]Cos[θ],5Sin[3/2revolution]+1/2Sin[ϕ]Cos[θ],1/2Sin[θ]},{7Cos[revolution+1]+1/3Cos[ϕ]Cos[θ],7Sin[revolution+1]+1/3Sin[ϕ]Cos[θ],1/3Sin[θ]}
},
{ϕ,0,2π},{θ,-π/2,π/2},
PlotRange->{{-8,8},{-8,8},{-8,8}},
PlotStyle->
{
{Texture@ImageAdjust[, {0,1}],Specularity[White,10]},
{Texture@,Specularity[Blue,10]},
{Texture@,Specularity[Brown,8]}
},
Mesh->False,Axes->False,Boxed->False,Lighting->"Neutral",
ViewVector->{60Cos[(revolution/(3π))+1],1+60Sin[(revolution/(3π))+2],4},
SphericalRegion->True,PerformanceGoal->"Speed",
Prolog->Inset[,Center,Center,2]
],
{revolution,0,4π},
AnimationRate->(1/20),AnimationRunning->False,AnimationRepetitions->1]

Explanation: details and variants

The core part in the code is ParametricPlot3D, producing 3 spheres. Here is a simpler version of the above code:

Manipulate[ParametricPlot3D[{{2Cos[ϕ]Cos[θ],2Sin[ϕ]Cos[θ],2Sin[θ]},{5Cos[3/2revolution]+1/2Cos[ϕ]Cos[θ],5Sin[3/2revolution]+1/2Sin[ϕ]Cos[θ],1/2Sin[θ]},{7Cos[revolution+1]+1/3Cos[ϕ]Cos[θ],7Sin[revolution+1]+1/3Sin[ϕ]Cos[θ],1/3Sin[θ]}},{ϕ,0,2π},{θ,-π/2,π/2},PlotRange->{{-8,8},{-8,8},{-8,8}},Mesh->False,Axes->False,Background->Darker@Darker@Gray,Lighting->"Neutral",PerformanceGoal->"Speed",SphericalRegion->True],{revolution,0,4π}]

We need no mesh, no axes, a darker (or even darker) background and some neutral light sources: Mesh->False, Axes->False, Background->Darker@Darker@Gray, Lighting->”Neutral”.

The SphericalRegion->True option gives us a graphics in which the bounding box is better visible. We put the 3D graphics in a large enough viewing window by PlotRange->{{-8,8},{-8,8},{-8,8}}.

We also need a fast animation (PerformanceGoal->"Speed").

Exercise.  Change each of the above options to see what happens.

The central sphere is fixed in the coordinate system. The other two smaller spheres are set to orbit on a circle around the central object. The Manipulate slider controls the position of the smaller objects along their orbit.

Exercise.  Which number(s) is / are responsible for the radius of the central sphere?

Exercise.  Which number(s) is / are responsible for the radii of the orbiting spheres?

Exercise.  Which numbers describe the orbit radii?

Exercise.  Can you modify the code so that the planets orbit on elliptical orbits?

Exercise.  What should we change in the code so that we do not have complete spheres just lower hemispheres?

Then with the ViewVector command, we can change the camera position along a given curve segment.

Manipulate[ParametricPlot3D[{{2Cos[ϕ]Cos[θ],2Sin[ϕ]Cos[θ],2Sin[θ]},{5Cos[3/2revolution]+1/2Cos[ϕ]Cos[θ],5Sin[3/2revolution]+1/2Sin[ϕ]Cos[θ],1/2Sin[θ]},{7Cos[revolution+1]+1/3Cos[ϕ]Cos[θ],7Sin[revolution+1]+1/3Sin[ϕ]Cos[θ],1/3Sin[θ]}},{ϕ,0,2π},{θ,-π/2,π/2},PlotRange->{{-8,8},{-8,8},{-8,8}},Mesh->False,Axes->False,Background->Darker@Darker@Gray,Lighting->"Neutral",PerformanceGoal->"Speed",SphericalRegion->True, ViewVector->{60Cos[(revolution/(3π))+1],1+60Sin[(revolution/(3π))+2],4}],{revolution,0,4π}]

We add the galaxy in the background by an Inset command:

Manipulate[ParametricPlot3D[{{2Cos[ϕ]Cos[θ],2Sin[ϕ]Cos[θ],2Sin[θ]},{5Cos[3/2revolution]+1/2Cos[ϕ]Cos[θ],5Sin[3/2revolution]+1/2Sin[ϕ]Cos[θ],1/2Sin[θ]},{7Cos[revolution+1]+1/3Cos[ϕ]Cos[θ],7Sin[revolution+1]+1/3Sin[ϕ]Cos[θ],1/3Sin[θ]}},{ϕ,0,2π},{θ,-π/2,π/2},PlotRange->{{-8,8},{-8,8},{-8,8}},Mesh->False,Axes->False,Background->Darker@Darker@Gray,Lighting->"Neutral",PerformanceGoal->"Speed",SphericalRegion->True, ViewVector->{60Cos[(revolution/(3π))+1],1+60Sin[(revolution/(3π))+2],4},Prolog->Inset[,Center,Center,2]],{revolution,0,4π}]

Exercise.  Change Prolog to Epilog and explain what you get.

Finally, with

PlotStyle->{{Texture@ImageAdjust[, {0,1}],Specularity[White,10]},{Texture@,Specularity[Blue,10]},{Texture@,Specularity[Brown,8]}}

we apply a texture to the Sun and to the planets.

Exercise.  Which are the two planets here?

.. Some more visualization functions

Study the following graphics containing 8 selected applications in each of the 4 groups. Click on the tabs “3D plots”, “Charting” or “Statistical visualizations” to see the other pages.

Explanation: details and variants

The above chart can be generated by the following command, for example:

TabView[{
Style["2D plots",FontFamily->"Arial",FontSize->14]->,
Style["3D plots",FontFamily->"Arial",FontSize->14]->,
Style["Charting",FontFamily->"Arial",FontSize->14]->,
Style["Statistical visualizations",FontFamily->"Arial",FontSize->14]->
}]

TabView produces a clickable dialog box. Notice that we have 4 predefined 2D images. They are static, so you cannot click on the individual items.

The structure of the TabView command is easier to understand if some images are replaced by text. We have also changed the number of items displayed and the font sizes. Notice that, similarly to an earlier Manipulate example, the button in the third case is the output of a Plot command (flexibility!). This 3rd button represents a parabola with a smaller image size (50x50) and without axes.

TabView[{
Style["This is the button text and below is the figure. Try zooming it.",FontFamily->"Arial",FontSize->14]->Plot[(x^2),{x,-3,3}],
Style["This is the 2nd tab",FontSize->Tiny]->"This is the second item. Can you create some nice image here?",
Style[Plot[-(x^2),{x,-3,3},ImageSize->{50,50},Axes->False],FontSize->Large]->"The tab is a figure and here is the text."
},ImageSize->{200,200}]

.. Let us play some music

In the first example, you or your group is requested to recognize the following (simplified) music.

Exercise.  Before playing the music, can you guess the title of the movie or the name of the composer just by looking at the code?

Sound@{SoundNote["C3"],SoundNote["C3",2/3],SoundNote["C3",1/3],SoundNote["C3"],SoundNote["G#2",2/3],SoundNote["D#3",1/3],SoundNote["C3"],SoundNote["G#2",2/3],SoundNote["D#3",1/3],SoundNote["C3",2],SoundNote["G3"],SoundNote["G3",2/3],SoundNote["G3",1/3],SoundNote["G3"],SoundNote["G#3",2/3],SoundNote["D#3",1/3],SoundNote["B2",1],SoundNote["G#2",2/3],SoundNote["D#3",1/3],SoundNote["C3",2]}

Exercise.  The evaluatable property of the above cell has intentionally been deleted. To listen to the music, first you have to restore that property (for example, visit the Cell/Cell Properties menu).

Exercise.  After playing the music, can you answer the question?

As a second example, let us listen to the following piece of code.

Manipulate[
EmitSound@Sound@SoundNote[{pitch,pitch+difference}];
BarChart[{pitch,pitch+difference},PlotRange->{-60,60},ChartStyle->"SolarColors"],
{pitch,-48,48,difference},{difference,-12,12,1}]

Explanation: details and variants

In both examples, the Sound and EmitSound commands play the notes given by SoundNote. The note can have pitch and duration, for example.

In the second example, the sound is produced by EmitSound@Sound[SoundNote[{pitch,pitch+difference}]]. You can manipulate the pitches with the sliders.

Manipulate[EmitSound@Sound@SoundNote[{pitch,pitch+difference}],{pitch,-48,48,difference},{difference,-12,12,1}]

Notice that we play two notes simultaneously.

To get only the graphics without sound, you may write

Manipulate[BarChart[{pitch,pitch+difference},PlotRange->{-60,60},ChartStyle->"SolarColors"],{pitch,-48,48,difference},{difference,-12,12,1}]

Exercise.  Study the help page of the BarChart command to see some of its capabilities.

.. Summary

.. Spheres everywhere

spheres=RandomChoice[{,,},10]

First@spheres

Last[spheres]

spheres//Most

Rest@spheres

spheres//Tally

Sort@spheres

Explanation: details and variants

An important message of the example is that Mathematica treats objects in a uniform manner: a list can contain not only numbers, but formulae, text, graphics or even sound—and you do not have to worry about different data type specifications.

We already know that RandomChoice here chooses 10 random elements from the given list of length 3.

The First, Last, Most and Rest commands keep or omit the appropriate element(s).

Tally groups identical elements, then counts them.

The Sort command is based on the internal representation of the objects when it produces a canonical order. With FullForm, you can study how Mathematica sees a sphere:

FullForm@spheres

Finally, if you need some intermediate elements from the list, you can use the general command Part:

?Part

Exercise.  Based on the above help, explain to the others what you get below (one command will intentionally produce an error message):

spheres[[1]]

spheres[[-1]]

spheres[[11]]

spheres[[{1,3,5,7,9}]]

spheres[[2;;10]]

spheres[[2;;Length@spheres]]

spheres[[2;;-1]]

spheres[[1;;-2;;2]]

ClearAll[spheres]

.. Dictionaries

You need Internet connection to run the following two examples properly.

Panel[
TabView[
{
"Languages:\nDictionaryLookup[All]"-> DictionaryLookup[All],
"English:\n\"hit\"~~_"->DictionaryLookup["hit"~~_],
 "Hungarian:\n\"hit\"~~_"->DictionaryLookup[{"Hungarian","hit"~~_}],
"\"hit\"~~__"-> DictionaryLookup["hit"~~__],
"\"hit\"~~___"-> DictionaryLookup["hit"~~___],
"(\"b\"~~_ ).."-> DictionaryLookup[{"Hungarian",("b"~~_ )..}],
"..."->Hyperlink["StringExpression","paclet:ref/StringExpression"]
},
ControlPlacement->Left],
Hyperlink["DictionaryLookup","paclet:ref/DictionaryLookup"],ImageSize->600]

Panel[
Grid[
{#,Length[DictionaryLookup[{#,All}]]}&/@
((DictionaryLookup[All])[[1;;7]])
],
"Size of the dictionaries"]

Explanation: details and variants

This example simultaneously covers two main topics: pattern matching and string expressions.

Pattern matching is an abstract way of describing classes of expressions by their structure. Pattern matching is used when you want to find something in a given set and you know the structure of the object you are looking for. Pattern matching can be very powerful and it is used throughout the whole Mathematica system internally. Since patterns can be abstract, they are best illustrated in connection with some concrete objects: mathematical expressions or string expressions, for example. Here we illustrate pattern matching with strings. We remark that you have already seen some patterns earlier (not connected to strings): in the More flags example we defined  myfunction[argument_]:=(argument^2), where argument_ is again a pattern—it can stand for any Mathematica expression, so this time there is no restriction on the structure.

You can think of a string in Mathematica as any kind of text. Strings are surrounded by quotation marks of the type shown in the example. Notice that there are different types of quotation marks in Mathematica. There are several possible operations on strings.

Strings naturally occur in dictionaries, that is why we use the DictionaryLookup command now to produce several examples.

After these introductory remarks, we can analyze the first example.

The Panel command does some formatting of the output data (also specifying the size of the image): it displays a TabView (we have seen earlier), and a Hyperlink object.

The paclet:ref/DictionaryLookup hyperlink points to the DictionaryLookup command itself in the Mathematica help:

?DictionaryLookup

Hyperlinks can also point to the Internet (as we have seen and will see many examples in this Mathematica notebook).

The \n symbols in the code are new line characters.

Therefore, the “Languages:\nDictionaryLookup[All]” -> DictionaryLookup[All] piece lists all the dictionaries known by Mathematica. The actual command doing the task is DictionaryLookup[All], but we know that for TabView, we also need some labels (here “Languages:\nDictionaryLookup[All]”) to click on, and we should use an arrow (that is, a Rule) between them.

The ~~ symbol, or StringExpression command, yields a sequence of strings.

In the example, the ~~ symbols are used in connection with the single blank (_),  double blank (__)  and triple blank (___) pattern objects:

?Blank

?BlankSequence

?BlankNullSequence

Hence the “English:\n\”hit\”~~_”->DictionaryLookup[“hit”~~_] tab, when you click on its label “English:\n\”hit\”~~_” having string type, will display the words of the default English dictionary having some structure. In our case, we are looking for all words in the English dictionary that begin with the string “hit” and contain one more character.

Similarly,

DictionaryLookup[{"Hungarian","hit"~~_}]

displays all words in the Hungarian dictionary that begin with “hit” and contain one more character.

The command

DictionaryLookup["hit"~~__]

uses the default dictionary to find all words that begin with the string “hit” and contain one or more characters. If you would like to find all words that begin with “hit” and contain zero or more characters, then you can use

DictionaryLookup["hit"~~___]

Finally, we illustrate the .. pattern object: it represents a pattern repeated one or more times. The following command thus finds all Hungarian words that have the structure “b” and one more character, then this block of two characters is repeated one or more times.

DictionaryLookup[{"Hungarian",("b"~~_)..}]

Exercise.  Study and explain the DictionaryLookup[{“Hungarian”,(“b”~~__)..}] command (with double blank!).

In the second example, Panel[Grid[{#,Length[DictionaryLookup[{#,All}]]}&/@((DictionaryLookup[All])[[1;;7]])],”Size of the dictionaries”], the main piece of code is of course

{#,Length[DictionaryLookup[{#,All}]]}&/@((DictionaryLookup[All])[[1;;7]])

The Panel and Grid commands are just for formatting the output.

But we see immediately (from & /@) that here some function is applied to each element of some list.

The list is generated by the first 7 dictionaries of all known ones:

(DictionaryLookup[All])[[1;;7]]

DictionaryLookup[All]

The function we apply here elementwise is a pure function, {#, Length[DictionaryLookup[{#,All}]]}&.

It creates lists having 2 elements: when you substitute, for example, the "Arabic" string (given by DictionaryLookup[All][[1]]) into the # slot, we get

{"Arabic",Length[DictionaryLookup[{"Arabic",All}]]}

that is, the number of Arabic words in this dictionary.

Exercise.  Study and explain the following command.

DictionaryLookup[{"Hungarian",x___/;(x==StringReverse[x]&&StringLength[x]≥9)}]

The /; operator above (or equivalently, Condition) can be read as provided that. The StringReverse command has a self-explanatory name. Notice that instead of == for testing equality, you cannot use = or :=.

Exercise.  What are the longest English words with the above property?

.. WordData

The following command will download some data from the Internet, hence it will take a certain time to initialize.

Panel[
TabView[
{" " -> WordData["fish"]}~Join~Table[k->WordData["fish",k],{k,{"PartsOfSpeech","BroaderTerms","Definitions","Synonyms","InflectedForms","PhoneticForm"}}],ControlPlacement->Left
],
Hyperlink["WordData[\"fish\",\"property\"]","paclet:ref/WordData"],
Appearance->Frameless,ImageSize->600]

Explanation: details and variants

The example again creates a panel with a hyperlink to the help window of a Mathematica command.

For the TabView command, we produce a list to display as labels and contents:

{" " -> WordData["fish"]}~Join~Table[k->WordData["fish",k],{k,{"PartsOfSpeech","BroaderTerms","Definitions","Synonyms","InflectedForms","PhoneticForm"}}]

Here we have used the infix form of the Join command (see the Infix, prefix or postfix forms of commands section of the Appendix), to join two expressions (now lists):

{a,b}~Join~{c,d}

Join[{a,b},{c,d}]

The second list we use in Join is generated by Table: the 6 strings (“PartsOfSpeech”, ”BroaderTerms”, ”Definitions”, ”Synonyms”, ”InflectedForms”, ”PhoneticForm”) are substituted in place of k in the k->WordData[“fish”,k] expression.

Table[k->WordData["fish",k],{k,{"PartsOfSpeech","BroaderTerms","Definitions","Synonyms","InflectedForms","PhoneticForm"}}]

Remember, the arrows in k->WordData[“fish”,k] are needed in TabView.

So it is enough if you understand the WordData command with the specified options:

?WordData

Let us add that several other databases are accessible from within Mathematica, see the Access to huge data collections section of the Appendix for more examples.

.. Sentence scrambling

SentenceScrambler[sentence_]:=
Module[{SpecialQ,WordScrambler},
SpecialQ[character_]:=MemberQ[{",",".","\"","-","_","!","?"},character];
WordScrambler[word_]:=
Which[
StringLength[word]>4&&SpecialQ[StringTake[word,1]]&&SpecialQ[StringTake[word,-1]],
StringTake[word,2]<>RandomSample[Characters@StringTake[word,{3,StringLength[word]-2}]]<>StringTake[word,-2],
StringLength[word]>3&&SpecialQ[StringTake[word,1]],
StringTake[word,2]<>RandomSample[Characters@StringTake[word,{3,StringLength[word]-1}]]<>StringTake[word,-1],
StringLength[word]>3&&SpecialQ[StringTake[word,-1]],
StringTake[word,1]<>RandomSample[Characters@StringTake[word,{2,StringLength[word]-2}]]<>StringTake[word,-2],
StringLength[word]>2,
StringTake[word,1]<>RandomSample[Characters@StringTake[word,{2,StringLength[word]-1}]]<>StringTake[word,-1],
True,word
];
StringJoin@Riffle[WordScrambler[#]&/@StringSplit[sentence]," "]
]

DynamicModule[
{userinput="Sentence scrambling is fun."},
Column@{InputField[Dynamic@userinput,String],Dynamic@SentenceScrambler@userinput}
]

Explanation: details and variants

The first block defines a new function, SentenceScrambler.

It uses the Module command

?Module

that is similar to With we have seen earlier: both can be used to defined local variables. Module is useful when you write a longer program to avoid naming conflicts (inside and outside the program). You do not have to specify initial values in Module, but you can, if you wish to do so.

Within the module, two new functions are defined: SpecialQ and WordScrambler. But they should form one expression within the module, so you should use the symbol ; we met earlier to join them, and not the , symbol.

Mathematica commands ending in “Q” typically produce a True of False answer. So

MemberQ[{",",".","\"","-","_","!","?"},"a"]

and

MemberQ[{",",".","\"","-","_","!","?"},"!"]

are used to test membership. Hence SpecialQ decides whether its argument is a special character or not.

In the WordScrambler function, several cases are separated: this is where you can use Which.

?Which

It is assumed that the argument of the WordScrambler function is a string representing a word. The cases in Which are separated according to the length of this word.

There are 4 such cases. The last, fifth case in Which is the “otherwise” case (described by True, word): if none of the above 4 conditions applies, then WordScrambler should just return the input word itself, without any transformations.

Exercise.  Does the ordering of the cases in Which matter?

Since the cases are analogous, we will just have a closer look at the fourth case.

The fourth case in Which describes the following: if the condition StringLength[word]>2 is true,

then evaluate the expression StringTake[word,1]<>RandomSample[Characters@StringTake[word,{2,StringLength[word]-1}]]<>StringTake[word,-1].

That is, if the argument of WordScrambler is a word having length greater than 2, then it should break its argument into 3 parts.

The first and last characters are fixed; the middle part is scrambled.

The middle part of the word is described by the character positions 2 through StringLength[word]-1. We put the middle characters in a list:

StringTake["middlepart",{2,StringLength["middlepart"]-1}]

Characters@StringTake["middlepart",{2,StringLength["middlepart"]-1}]

and scramble them by

RandomSample@Characters@StringTake["middlepart",{2,StringLength["middlepart"]-1}]

Notice the difference between

StringTake["middlepart",2]

and

StringTake["middlepart",{2}]

Now we restore the first and last characters by

?StringJoin

StringJoin["h","e","l","l","o"]

%//FullForm

"h"<>"e"<>"l"<>"l"<>"o"

So

StringTake["middlepart",1]<>RandomSample[Characters@StringTake["middlepart",{2,StringLength["middlepart"]-1}]]<>StringTake["middlepart",-1]

The logical And operator (alternatively, &&) is used in the first three conditions. For example, the first condition

StringLength["word"]>4&&SpecialQ[StringTake["word",1]]&&SpecialQ[StringTake["word",-1]]

deals with words of length more than 4 and having special characters in their first and last positions.

Finally, after the definition of SpecialQ and WordScrambler in the module, we evaluate the last command StringJoin@Riffle[WordScrambler[#]&/@StringSplit[sentence],” ”]:

?StringSplit

?Riffle

StringSplit["This is a sentence."]

Riffle[StringSplit["This is a sentence."]," "]

Now we apply WordScrambler to each member of this list (that is, to each word), then assemble the sentence of scrambled words. The word order within the sentence is unchanged.

The second block in the example applies the SentenceScrambler function dynamically. DynamicModule is analogous to Module: it allows local definitions within an interactive environment.

DynamicModule[{userinput="Sentence scrambling is fun."},Column@{InputField[Dynamic@userinput,String],Dynamic@SentenceScrambler@userinput}]

The default starting sentence is “Sentence scrambling is fun.”. Due to DynamicModule however, the value of userinput cannot be seen outside the module: it has become a local variable.

userinput

A column format is used when the user input is given:

?InputField

InputField[Dynamic@userinput,String]

Enter any text below to scramble your input (if you left the above input field empty, then you will see an error message below to the right, until you enter something in the left field below):

{InputField[Dynamic@userinput,String],Dynamic@SentenceScrambler@userinput}

We remark that after entering something into the above left input field, the value of userinput is visible everywhere, because now we have not confined it into a DynamicModule environment.

userinput

So we clear it:

ClearAll@userinput

.. Synonym networks

Manipulate[
GraphPlot@Flatten@Rest@
NestList[
Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&,
{""->"sofa"},
k
],
{k,{1,2,3,4}}]

Explanation: details and variants

The Manipulate command provides the inner part,

GraphPlot@Flatten@Rest@NestList[Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&,{""->"sofa"}, 2], with a suitable k value, so it is enough to investigate the inner code piece for a particular k value, for example, for k=2.

We see that

Flatten@Rest@NestList[Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&,{""->"sofa"},2]

produces a list of rules (recall, the expression1 -> expression2 construction is called rule in Mathematica). The GraphPlot command draws an (undirected) graph: the vertices will be the words, and an edge is drawn between two words if there is an arrow between them in the list.

GraphPlot@Flatten@Rest@NestList[Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&,{""->"sofa"},2]

If you move your mouse over a vertex, its name is displayed.

We already know what Flatten and Rest do (destroy the nested structure of a list, and omit the first element, respectively):

Rest@NestList[Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&,{""->"sofa"},2]

so we can focus on only the NestList function.

We already met Nest. NestList is similar to the Nest function: they both apply the same function to an initial argument repeatedly, but, unlike Nest,  NestList keeps the intermediate results in a list:

NestList[myfunction[#]&,argument,2]

The initial argument in NestList is the list {“”->”sofa”}, and the number of repetitions is 2. The function applied repeatedly is Union@Flatten[Thread[#->WordData[#,”Synonyms”,”List”]]&/@Last/@#]&.

Let us see what happens if we apply it once:

Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&[{""->"sofa"}]

and twice:

Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@#]&[{"sofa"->"couch","sofa"->"lounge"}]

We see that Union@Flatten[Thread[#->WordData[#,”Synonyms”,”List”]]&/@Last/@#]&[{“sofa”->”couch”,”sofa”->”lounge”}] is equivalent to

Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@Last/@{"sofa"->"couch","sofa"->"lounge"}]

because they both describe the same function application to the same argument.

The last part, Last/@{“sofa”->”couch”,”sofa”->”lounge”}, is an elementwise application of Last to each list element

Last/@{"sofa"->"couch","sofa"->"lounge"}

so we have

Union@Flatten[Thread[#->WordData[#,"Synonyms","List"]]&/@{"couch","lounge"}]

But this is again an elementwise application of a function: we apply Thread[#->WordData[#,”Synonyms”,”List”]]& to each element of the list {“couch”,”lounge”}, then apply Union@Flatten to the result.

So it is enough to understand, for example,

Union@Flatten[Thread["couch"->WordData["couch","Synonyms","List"]]]

Union can be used to form the union of sets (represented in Mathematica as lists), for example.

{a,b}~Union~{c,d}

So Union is similar to Join.

{a,b}~Join~{c,d}

But Join does not sort the answer into canonical order:

{a,c}~Union~{b,d}

{a,c}~Join~{b,d}

Union also removes duplicates (which is the reason it is used in the example):

{a,c}~Union~{a,d}

Exercise.  Study the related command DeleteDuplicates.

Returning to Union@Flatten[Thread[“couch”->WordData[“couch”,”Synonyms”,”List”]]], we now omit Union

Flatten[Thread["couch"->WordData["couch","Synonyms","List"]]]

then Flatten, so we are left with

Thread["couch"->WordData["couch","Synonyms","List"]]

Thread distributes the function f among its arguments:

Thread[f[{a,b,c}]]

The function to be distributed now is Rule:

"couch"->WordData["couch","Synonyms","List"]//FullForm

What remains is

WordData["couch","Synonyms","List"]

displaying synonyms of “couch” in a list.

Exercise.  Now, as we have reverse engineered the code, describe how it works in a few sentences.

.. Where do you live?

Manipulate[
ImportString[
ExportString[
URLFetch[
"http://maps.googleapis.com/maps/api/staticmap","ContentData",
"Parameters"->
{"center"->c,"zoom"->ToString[z],"size"->"512x256","maptype"->t,"sensor"->"false","style"->"inverse_lightness:true","format"->"png"}
],
"Byte","DataFormat"->{"Bytes"}],
"PNG","DataFormat"->{"Byte"}
],
{{c,"Budapest","location"},InputField[#,String,FieldSize->35]&},
Delimiter,
{{t,"terrain","map type"},{"roadmap","terrain","satellite","hybrid"},ControlType->RadioButton},
{{z,9,"zoom"},1,20,1},
ContinuousAction->False]

Explanation: details and variants

This Manipulate command has 3 controls.

One is named location, where the user can enter their input (InputField) as a string. The default value of the field is “Budapest”.

Delimiter is responsible for the horizontal line separator.

Then the map type can be chosen from a list of 4 elements (“roadmap”,”terrain”,”satellite”,”hybrid”). Different map types can be selected by a radio button.

The zoom control can have values between 1 and 20 in discrete integer steps. Its default value is 9. ContinuousAction->False has been used to speed up Manipulate when the controls are changed.

With these control values, the

ImportString[ExportString[URLFetch["http://maps.googleapis.com/maps/api/staticmap","ContentData","Parameters"->{"center"->c,"zoom"->ToString[z],"size"->"512x256","maptype->"t,"sensor"->"false","style"->"inverse_lightness:true","format"->"png"}],"Byte","DataFormat"->{"Bytes"}],"PNG","DataFormat"->{"Byte"}]

command is evaluated.

So let us test this command with the default values:

With[{c="Budapest",t="terrain",z=9},ImportString[ExportString[URLFetch["http://maps.googleapis.com/maps/api/staticmap","ContentData","Parameters"->{"center"->c,"zoom"->ToString[z],"size"->"512x256","maptype"->t,"sensor"->"false","style"->"inverse_lightness:true","format"->"png"}],"Byte","DataFormat"->{"Bytes"}],"PNG","DataFormat"->{"Byte"}]]

The URLFetch command visits the given site “http://maps.googleapis.com/maps/api/staticmap” with the given parameters, and downloads the specified data.

Notice that ToString first converts the number z into a string

ToString[9]//FullForm

The corresponding converse command would be ToExpression:

ToExpression["9+9"]

The output of URLFetch is a huge amount of data, in the form of a large numerical list:

With[{c="Budapest",t="terrain",z=9},URLFetch["http://maps.googleapis.com/maps/api/staticmap","ContentData","Parameters"->{"center"->c,"zoom"->ToString[z],"size"->"512x256","maptype"->t,"sensor"->"false","style"->"inverse_lightness:true","format"->"png"}]]

ExportString converts this data into raw binary format, finally ImportString interprets the raw binary format as an image (of PNG type). This image is then displayed directly as a map.

.. Summary

.. Create your fractal

The following command may take some time to evaluate when you move the slider to the right.

Manipulate[
ContourPlot[
Abs@Nest[(((#)^2)+x+I y)&,0,n]==2,
{x,-2,0.5},{y,-1.2,1.2},PlotPoints->20],
{{n,2,"Number of iterations"},1,12,1}]

Exercise.  Move your mouse over the curve to see its equation displayed.

Explanation: details and variants

The Manipulate command controls the value of the iteration number, described by the n variable. So let us take a small n value for illustration, say, n=6.

ContourPlot[Abs@Nest[(((#)^2)+x+I y)&,0,6]==2,{x,-2,0.5},{y,-1.2,1.2},PlotPoints->20]

The PlotPoints->20 option in ContourPlot provides us with fine enough resolution.

The core command ContourPlot in the example generates a level curve (at level height equal to 2) of the surface given by Abs@Nest[(((#)^2)+x+I y)&,0,6]. Note that == has been used (and not = or :=).

Let us have a look at a simpler example first. If the surface is given by f(x,y)=(x^2)+(y^2) (in standard mathematical notation), then the level curves are circles:

ContourPlot[(x^2)+(y^2)==2,{x,-1.5,1.5},{y,-1.5,1.5}]

The surface itself looks like

Plot3D[(x^2)+(y^2),{x,-1.5,1.5},{y,-1.5,1.5}]

The contour plot is obtained if you slice this surface with horizontal planes.

In the example, the surface is more complicated, but the underlying rule to generate it is simple:

Abs@Nest[(((#)^2)+x+I y)&,0,6]

that is, we take 0, square it, add the complex number x + i y to it, square it again, add x + i y, and so on, several times, finally take the absolute value (to get rid of the complex numbers). We know that such recursive definitions can conveniently be described by Nest and pure functions. Notice how complex numbers are represented in Mathematica: the imaginary unit is either I or equivalently, i. Also note that you should put a space character between I and y.

The actual surface generated by Abs@Nest[(((#)^2)+x+I y)&,0,6] has the following shape:

Plot3D[Abs@Nest[(((#)^2)+x+I y)&,0,6],{x,-2,0.5},{y,-1.2,1.2},PlotRange->{0,2}]

Here we have restricted the function values to be plotted to the interval [0,2] by PlotRange->{0,2}.

Exercise.  Search the Internet for the term Mandelbrot set. Can you explain the similarities observed?

.. Cartesian and polar coordinate conversion

Manipulate[
Grid@
{{
Plot[
Null,{x,-3.5,3.5},
PlotRange->3.5,GridLines->Automatic,PlotLabel->"complex plane",Epilog->{Red,PointSize[0.03],Point[P]},AspectRatio->Automatic
],
Plot[
Null,{x,0,(Sqrt[2])3.5},
PlotRange->{{0,(Sqrt[2])3.5+1},{-π-0.2,π+0.2}},GridLines->{Range[1,1+Floor[(Sqrt[2])3.5]],Range[-π,π,(π/4)]},Ticks->{Range[1,1+Floor[Sqrt[2]3.5]],Range[-π,π,(π/4)]},PlotLabel->"polar plane",AspectRatio->Automatic,
Epilog->
{
{Red,PointSize[0.03],Point[{Abs[P.{1,I}],Arg[P.{1,I}]}]},Yellow,
Rectangle[{0,π+0.01},{(Sqrt[2])3.5+1,π+0.2}],Rectangle[{0,-π-0.2},{(Sqrt[2])3.5+1,-π}]
}
]
}},
{{P,{1,1},"Move the 2D slider to change the point in the complex plane"},{-3.5,-3.5},{3.5,3.5}},
Dynamic@(P.{1,I})]

Explanation: details and variants

The above code is a straightforward and simple realization of the sentence: manipulate a graphics arranged in a grid and consisting of two plots.

The first plot is Plot[Null,{x,-3.5,3.5},PlotRange->3.5,GridLines->Automatic,PlotLabel->”complex plane”, Epilog->{Red,PointSize[0.03], Point[P]}, AspectRatio->Automatic],

while the second one is

Plot[Null,{x,0,(Sqrt[2])3.5},PlotRange->{{0,(Sqrt[2])3.5+1},{-π-0.2,π+0.2}},
GridLines->{Range[1,1+Floor[(Sqrt[2])3.5]],Range[-π,π,(π/4)]},Ticks->{Range[1,1+Floor[Sqrt[2]3.5]],Range[-π,π,(π/4)]},
PlotLabel->"polar plane",Epilog->{{Red,PointSize[0.03],Point[{Abs[P.{1,i}],Arg[P.{1,i}]}]},Yellow,Rectangle[{0,π+0.01},{(Sqrt[2])3.5+1,π+0.2}],
Rectangle[{0,-π-0.2},{(Sqrt[2])3.5+1,-π}]},AspectRatio->Automatic]

Manipulate here controls a two-dimensional slider that updates the value of P.

The point P has two coordinates, by default {1,1}. The code piece P.{1, i} uses the Dot function (that is, the scalar product) to convert P into a complex number in algebraic form.

{1,1}.{1,I}

Exercise.  What is the definition of scalar product in general?

The Dynamic@(P.{1, i}) command displays the algebraic form of the actual complex number numerically near the slider.

To convert the algebraic form into polar form, we use

{Abs[{1,1}.{1,I}],Arg[{1,1}.{1,I}]}

Exercise.  What is the difference between Cartesian and polar coordinates?

Let us turn to the first plot. By giving P its default value, we have

With[{P={1,1}},Plot[Null,{x,-3.5,3.5},PlotRange->3.5,GridLines->Automatic,PlotLabel->"complex plane",Epilog->{Red,PointSize[0.03],Point[P]},AspectRatio->Automatic]]

We see that we do not plot any function, that is why we use the Null expression

?Null

Plot is used only to set up the grid lines with appropriate aspect ratio, the plot label and a larger red point (controlled by the 2D slider).

The second Plot is analogous, no function is plotted:

With[{P={1,1}},Plot[Null,{x,0,(Sqrt[2])3.5},PlotRange->{{0,(Sqrt[2])3.5+1},{-π-0.2,π+0.2}},GridLines->{Range[1,1+Floor[(Sqrt[2])3.5]],Range[-π,π,(π/4)]},Ticks->{Range[1,1+Floor[Sqrt[2]3.5]],Range[-π,π,(π/4)]},PlotLabel->"polar plane",Epilog->{{Red,PointSize[0.03],Point[{Abs[P.{1,I}],Arg[P.{1,I}]}]},Yellow,Rectangle[{0,π+0.01},{(Sqrt[2])3.5+1,π+0.2}],Rectangle[{0,-π-0.2},{(Sqrt[2])3.5+1,-π}]},AspectRatio->Automatic]]

Here PlotRange sets up the appropriate plot window, GridLines draws the vertical and horizontal grid lines we specify by

{Range[1,1+Floor[(Sqrt[2])3.5]],Range[-π,π,(π/4)]}

?Range

Floor is a function rounding down to the nearest integer:

{Floor[1],Floor[π],Floor[-π],Floor[-1]}

Its counterpart is Ceiling.

Ticks displays tick marks on the axes as desired. After the (empty) plot has been drawn, we also display the red point in polar coordinates, and some yellow rectangles.

Exercise.  What is the role of these yellow rectangles?

.. Square roots, cube roots and (n^th) roots

DynamicModule[{z},
Manipulate[
z=P.{1,I};
Plot[
Null,{x,-3.5,3.5},
PlotRange->3.5,GridLines->Automatic, AspectRatio-> Automatic,
Epilog->
{
Text[Style["z",Large],P+{0.15,0.15}],PointSize[0.02],Darker@Red,Point@{Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1]))))
},
PlotLabel->Style[Row@{Which[n==2,"square",n==3,"cube",True,(n^("th"))]," roots"},Bold]
],
{{n,3},2,9,1,Appearance->"Labeled"},
{{P,{3,2}},{-3.5,-3.5},{3.5,3.5},Locator},
Dynamic@z]
]

Explanation: details and variants

The example displays all the (n^th) roots of a complex number z.

Unlike the previous example, this code piece incorporates the 2D slider into the plot by the Locator expression, adding even more interactive feeling.

Just as in the previous example, the user controls the value of the list P having 2 elements. This list is then converted to a complex number, z, in algebraic form (z=P.{1, i}). Therefore, the user controls z; its current value is displayed near the controls (Dynamic@z).

Now there is a second, discrete variable, n, the degree of the root, whose value (an integer between 2 and 9) is displayed near its slider (Appearance->”Labeled”).

We have already met DynamicModule earlier: now it makes the definition z=P.{1, i} invisible from outside, by creating a local variable within an interactive environment—so that you can freely use z in your other computations without having to worry about naming collisions.

z

As for the inner Plot command, it does not plot any function (due to Null), but some grid lines (GridLines->Automatic) with proper aspect ratio (AspectRatio-> Automatic) and a sufficiently large plot window (PlotRange->3.5).

It is more interesting to have a look at the PlotLabel option within Plot: after adjusting the text style, it uses Which to make a case separation. Instead of 2th roots, we display square roots; and instead of 3th roots, we print cube roots as a plot label. Notice that in the (n^("th")) expression, the base is a variable and the exponent is a string.

But the crucial code piece in the example doing the real job is hidden inside an innocent Epilog. We already know from previous examples that Epilog displays something after the main plot has been drawn.

The command Text[Style[“z”, Large], P+{0.15,0.15}] puts a large (string character) z close to the point P (recall that P, as a list, represents z as a complex number).

For example, by using the default value of P, the above Text is evaluated as

With[{P={3,2}},Text[Style["z",Large],P+{0.15,0.15}]]

Here we observe a very important property of Mathematica that enables us to write much simpler and more efficient code pieces: Mathematica can add two lists; of course, componentwise. It behaves just as vector addition in traditional mathematics.

{3,2}+{0.15,0.15}

The essential feature is that you do not have to break the structure of the lists to perform addition: you do not have to extract their components, add them separately, then assemble the sums into a list again. This is an approach that would belong to the realm of procedural programming.

Instead, with the above functional programming approach, it is possible to perform addition by using the original data structure: the definition of Plus is extended so that it can automatically handle lists as well.

We remark that internally, in Mathematica, list addition is governed by the Listable attribute of the Plus function:

Attributes[Plus]

Exercise.  Your instructor will show you how to clear the Listable attribute of the Plus function by evaluating ClearAttributes[Plus,Listable]. Then try and execute {3,2}+{0.15,0.15}. Finally, you may want to use SetAttributes[Plus,Listable].

Exercise.  Discuss the meaning of some other attributes.

The functional approach is of course not limited to the addition of lists, as we will immediately see.

Let us return to the Epilog option. After the text is displayed (by Text[Style[“z”,Large], P+{0.15,0.15}]), some final preparations are made (by setting point sizes and colors via PointSize[0.02], Darker@Red) to evaluate the

Point@{Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (e^((i/n) (Arg[z]+2π Range[0,n-1]))))

expression, responsible for displaying all the (n^th) roots of z.

Exercise.  Recalling de Moivre’s formula for determining the (n^th) roots of a complex number may be useful at this point.

Let us test the code with n=3 and z=1 for simplicity: we see that

With[{n=3,z=1},(((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1])))]

is a list consisting of the 3 cube roots of 1. The list structure is inherited from Range: the Range[0, n-1] command generates a list of length n (with elements 0, 1, 2, ..., n-1). But multiplication, addition and the exponential function are all Listable

Attributes/@{Times,Plus,Exp}

so instead of writing loops or working with separate components, we can use a fairly compact code without breaking the list structure, thanks to the functional programming approach made possible by the language:

With[{n=3,z=1},Range[0,n-1]]

With[{n=3,z=1},2π Range[0,n-1]]

With[{n=3,z=1},(I/n) (Arg[z]+2π Range[0,n-1])]

With[{n=3,z=1},(E^((I/n) (Arg[z]+2π Range[0,n-1])))]

With[{n=3,z=1},(((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1])))]

What remains is to display all these roots as Point objects in Epilog.

The useful {Re[#],Im[#]}& function separates real and imaginary parts of a complex number

{Re[#],Im[#]}&[3+2I]

so we can apply it elementwise to the list of  (n^th) roots:

With[{n=3,z=1},{Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1]))))]

Finally, we apply Point as well

With[{n=3,z=1},Point@{Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1]))))]

Concerning the precedence of the operations, notice that

Point@{Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (e^((i/n) (Arg[z]+2π Range[0,n-1])))) is equivalent to

With[{n=3,z=1},(Point@{Re[#],Im[#]}&)/@((((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1]))))]

but not to

With[{n=3,z=1},Point@({Re[#],Im[#]}&/@((((Abs[z]))^(1/n)) (E^((I/n) (Arg[z]+2π Range[0,n-1])))))]

.. Can we solve a quintic?

Some of you might have learned earlier that “equations of degree 5 or above cannot be solved”. Well, the truth of the previous statement in quotation marks depends on the precise definition of solving.

Module[{x},
Manipulate[
ListPlot[
Tooltip[{Re[#],Im[#]}&/@NSolve[(x^5)+a  x+1==0,x][[All,1,2]]],
PlotRange->{{-3.5,3.5},{-3.5,3.5}},PlotStyle->PointSize@Large,AxesLabel->{"Re","Im"}
],
{a,-4,4,0.1}]
]

Explanation: details and variants

The outer Module[{x}, ...] part ensures (by localizing x) that the code still works even if the variable x already had some predefined value.

The core command in the example is NSolve, capable of solving polynomial equations of higher degree (and much more) numerically.

The Manipulate command is used to change the value of the a parameter. Hence we can observe how the zeros of a polynomial depend on that particular coefficient.

Let us fix a=-2, for example. Then it is enough to understand

ListPlot[Tooltip[{Re[#],Im[#]}&/@NSolve[(x^5)-2  x+1==0,x][[All,1,2]]],PlotRange->{{-3.5,3.5},{-3.5,3.5}},PlotStyle->PointSize@Large,AxesLabel->{"Re","Im"}]

We see that

NSolve[(x^5)-2  x+1==0,x]

solves the quintic equation (x^5)-2  x+1==0 numerically but gives the solutions in a nested list containing Rule objects:

NSolve[(x^5)-2  x+1==0,x]//FullForm

We would like to keep only the complex numbers in this list. By repeatedly using the Part operator (that is, [[ ]]) we could write

NSolve[(x^5)-2  x+1==0,x][[1]]

then

NSolve[(x^5)-2  x+1==0,x][[1]][[1]]

and

NSolve[(x^5)-2  x+1==0,x][[1]][[1]][[2]]

to get the first complex number. To get the second one, we can write

NSolve[(x^5)-2  x+1==0,x][[2]][[1]][[2]]

and so on. But there are too many brackets to write. Fortunately we can rewrite the last expression, for example, as

NSolve[(x^5)-2  x+1==0,x][[2,1,2]]

So to extract all the complex numbers, we could write

Table[NSolve[(x^5)-2  x+1==0,x][[k,1,2]],{k,1,5}]

But there is an even more elegant way: we can get them all at once by All as

NSolve[(x^5)-2  x+1==0,x][[All,1,2]]

This is again a functional approach: no need to write loops or use a Table command.

We are already familiar with the next building block (separating real and imaginary parts componentwise)

{Re[#],Im[#]}&/@NSolve[(x^5)-2  x+1==0,x][[All,1,2]]

At this point we can use ListPlot to display these points on the plane:

ListPlot[{Re[#],Im[#]}&/@NSolve[(x^5)-2  x+1==0,x][[All,1,2]]]

But it is nicer if we enlarge the points drawn, add some labels to the axes and create a larger plot window by

ListPlot[{Re[#],Im[#]}&/@NSolve[(x^5)-2  x+1==0,x][[All,1,2]],PlotRange->{{-3.5,3.5},{-3.5,3.5}},PlotStyle->PointSize@Large,AxesLabel->{"Re","Im"}]

Finally, if we add Tooltip, then, in the present case,  Mathematica displays the coordinates of the points when you place your mouse pointer over a data point.

.. Solve, NSolve, Reduce and FindRoot

polynomial=(x^5)-2x+17

solutionlist=NSolve[polynomial==0][[All,1,2]]

Module[{command},
Manipulate[
command[polynomial==0],
{{command,Solve,"Choose a solution method:"},{Solve,NSolve,Reduce,FindRoot[#,{x,-1}]&,FindRoot[#,{x,-1+I}]&}},
Row@
{
Plot[polynomial,{x,-3,3},Epilog->{PointSize@Large,Tooltip[Point@#,#]&@{solutionlist[[1]],0}},ImageSize->200],
Spacer[50],
ListPlot[
Tooltip[{Re[#],Im[#]}&/@solutionlist],
PlotRange->{{-3,3},{-3,3}},PlotStyle->{PointSize@Medium,Red},GridLines->Automatic,AxesLabel->{"Re","Im"},ImageSize->200
]
}
]
]

Explanation: details and variants

We are going to study the roots of the given quintic equation (x^5)-2x+17 = 0 with the help of Solve, NSolve, Reduce and FindRoot.

In general, Solve can solve many polynomial equations or inequalities exactly; NSolve gives a numerical approximation to the zeros of polynomials to any requested precision; Reduce is similar to Solve, but always tries to give an equivalent reformulation; finally, FindRoot can numerically approximate the zeros of much general classes of functions than polynomials, provided that a good enough initial guess is available.

The solutionlist variable contains an approximation of the zeros of polynomial. This list is used to plot the roots in the two figures.

The Module command first localizes the variable command.

With Manipulate, we can choose from the 5 commands to use as a solution method and display their output graphically as well as algebraically.

The Solve command yields its output in the form of a nested list with Rule objects (you can think of the ... -> ... constructions as substitution rules), this time containing some Root objects as well. These Root[... , k] objects represent the (k^th) zero of the given polynomial in pure function form (17-2 #1+((#1)^5)&); k runs from 1 to 5, the degree of the polynomial. In some simpler cases (for example, when the polynomial degree is at most 4), the Root objects can be converted into square roots, cube roots, and so on,

{Root[((#)^2)-4&,1],Root[((#)^2)-4&,2],Root[((#)^2)-#-4&,2]}

but we know that in general no such conversion is possible, so Mathematica just maintains the zeros in these symbolic Root forms. We remark that you can perform several operations on the Root objects (but we are not going into these details now).

Exercise.  Search the Internet for the mathematicians Ruffini, Abel and Galois.

We have already illustrated the output of NSolve in the previous example.

The output of Reduce is a logical combination of the possible values of the variable(s) satisfying the equation. The logical operator here is the Or operation, also denoted by || in Mathematica:

Or[True,False]

True||False

The FindRoot[#,{x,-1}]& Mathematica command gives a numerical approximation to the zero of a function (in variable x). The function is substituted into the slot #, with a starting approximation x = -1. The FindRoot[#,{x,-1+i}]& command is analogous, but uses x = -1+i as an initial guess. FindRoot always gives you only one zero, but the zero found by FindRoot can depend on the initial approximation as we see from the example.

The two graphs are displayed in one row (Row[ ... ]).

The first graph is given by Plot[polynomial,{x,-3,3},Epilog->{PointSize@Large,Tooltip[Point@#,#]&@{solutionlist[[1]],0}},ImageSize->200]. The polynomial is plotted first, then, within the Epilog option, we mark its intersection with the real axis: the point size is set to larger and a Tooltip displaying the coordinates of this real zero is used. So it is enough to study Tooltip[Point@#,#]&@{solutionlist[[1]],0} in some more detail.

Clearly, {solutionlist[[1]],0} is just the first element of the solution list, being the only real solution of the equation, hence it has imaginary part 0. So, as a coordinate pair, it will be represented by {-1.83251,0}:

{solutionlist[[1]],0}

Due to the definition of the “at” operator (@) and the pure function (#&), the command

Tooltip[Point@#,#]&@{solutionlist[[1]],0}

is equivalent to

Tooltip[Point[{solutionlist[[1]],0}],{solutionlist[[1]],0}]

If you move your mouse over the output of the above command, you can see that it displays {solutionlist[[1]],0} as a label to the user, but the actual output is still a Point object used in Epilog.

Exercise.  What is the difference between the above and Tooltip[Point@#]&@{solutionlist[[1]],0}, being equivalent to Tooltip@Point@{solutionlist[[1]],0}?

The second graph is generated by ListPlot[Tooltip[{Re[#],Im[#]}&/@solutionlist],PlotRange->{{-3,3},{-3,3}},PlotStyle->{PointSize@Medium,Red},GridLines->Automatic,AxesLabel->{“Re”,”Im”},ImageSize->200]. We are already familiar how this works, thanks to the previous examples.

Finally, we put some space between the two graphs by Spacer[50].

ClearAll[polynomial,solutionlist]

.. Logical operations and set operations: Venn diagrams

Module[{logicalOperation,x,y},
TabView@Table[
logicalOperation->
Row@ 
{
RegionPlot[logicalOperation[(((-(1/2)+x))^2)+(y^2)<1,((((1/2)+x))^2)+(y^2)<1],{x,-2,2},{y,-2,2},ImageSize->200],
Spacer[20],
Panel[Grid[Outer[logicalOperation,{True,False},{True,False}],Frame->All],"  Truth table",FrameMargins->False]
},
{logicalOperation,{And,Or,Xor,Implies,Nand,Nor}}
]
]

Explanation: details and variants

We already know how Module, TabView, Table and Spacer work, so let us focus only on RegionPlot and Panel[...].

RegionPlot is suitable for displaying planar sets that are described by (logical combination of) inequalities. For example,

RegionPlot[{(((-(1/2)+x))^2)+(y^2)<1,((((1/2)+x))^2)+(y^2)<1},{x,-2,2},{y,-2,2}]

displays the two shifted disks in the example simultaneously.

We know that there is a close connection between set operations (e.g., intersection, union) and logical operations (“and”, “or”). The present example is designed to illustrate this connection.

With TabView, we substitute the 6 logical operations into the logicalOperation variable. If the And operation is chosen, for example, then the set And[(((-(1/2)+x))^2)+(y^2)<1,((((1/2)+x))^2)+(y^2)<1] consists of all those planar points (x,y) (more precisely, points in the prescribed plot window [-2,2]×[-2,2]) which are elements of both the left and the right disks simultaneously—in other words, which are in the intersection.

Exercise.  Discuss the remaining 5 logical operations and their meaning. Which operation is not symmetric?

The Panel[Grid[Outer[logicalOperation,{True,False},{True,False}],Frame->All],”  Truth table”,FrameMargins->False] command represents the actual logical operation with its truth table instead of a Venn diagram. Just keeping the essential part, we have

Panel[Grid[Outer[And,{True,False},{True,False}]]]

A new command here is Outer.

It forms all the possible pairs of elements with the first element coming from the first set, and the second element of the pair taken from the second set (in mathematics, this operation is the well-know Cartesian product), then it applies the specified function f to create a nested list:

Outer[f,{a,b},{c,d}]

The sets can have a different number of elements, and f can be any two-variable function:

Outer[List,{1,2,3},{a,b,c,d}]

Outer[Plus,{1,2,3},{a,b,c,d}]

Outer[Times,{1,2,3},{a,b,c,d}]

Therefore,

Outer[And,{True,False},{True,False}]

just creates the entries of the truth table of the And operation. Panel and Grid finally align the entries into a nicer table.

Exercise.  How many binary logical operations can be defined?

.. Pythagorean triples

Module[{x,y},
Manipulate[
Grid@Partition[
Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize->100]/.
(ToRules/@Table[Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers],{z,max}]),7,7,{1,1},Spacer[100]],
{max,6,50,1}]
]

Explanation: details and variants

We first localize the two auxiliary variables (Module[{x,y}, ...]) so that our code will run even if x and y have predefined values from earlier.

The Manipulate command controls the variable max within the interval [6, 50] in discrete steps, so let us consider only a singe value, say, max=13. We also omit the known Grid command.

With[{max=13},Partition[Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize->100]/.(ToRules/@Table[Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers],{z,max}]),7,7,{1,1},Spacer[100]]]

The core command is Reduce, embedded in a Table: Table evaluates Reduce with several z values from z=1 to z=max=13. Let us see what we get for z=5, for example:

With[{z=5},Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers]]

We see that Reduce finds all integer solutions to the equation (x^2)+(y^2)=(5^2) under the restriction  0<x≤y. Here the ∧ operator (pronounced as “wedge”) is just the logical “and” operator (as often used in mathematics):

With[{z=5},Reduce[And[(x^2)+(y^2)==(z^2),y≥x>0],{x,y},Integers]]

With[{z=5},Reduce[(x^2)+(y^2)==(z^2)&&y≥x>0,{x,y},Integers]]

Reduce claims that the above equation with the given constrains has a unique solution: in this case the triple (x,y,z)=(3,4,5) is called a Pythagorean triple.

But, for example, as we see,

With[{max=13},Table[Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers],{z,max}]]

the equations (x^2)+(y^2)=(1^2), (x^2)+(y^2)=(2^2), (x^2)+(y^2)=(3^2) or (x^2)+(y^2)=(4^2) have no integer solutions.

We know from our elementary studies that the above triples define precisely the right-angled triangles with integer side lengths (whenever they exist): finding these triples without Mathematica would be non-trivial.

The second goal of the present example is to graphically illustrate the above geometric fact. So we are going to construct these integer-sided, right-angled triangles.

For this we need the individual (x,y,z) triples. ToRules applied elementwise (/@) converts the logical combinations (given by Reduce) to replacement rules:

With[{max=13},ToRules/@Table[Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers],{z,max}]]

With the ReplaceAll operator (/.)

?ReplaceAll

we are going to substitute these x and y values into the

Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize-> 100]

expression. The substitution of a particular (x,y) pair (that is, one element of the nested list {{x->3,y->4}, {x->6,y->8}, {x->5,y->12}}) will have the following effect:

With[{max=13},Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize->100]/.{x->3,y->4}]

that is,

Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{3,0},{0,4}}],Text[{3,4,(Sqrt[(3^2)+(4^2)])},{(2/3) 13,(2/3)13}]},Axes->True,ImageSize->100]

So the Polygon command draws a polygon with 3 vertices, as specified by the Pythagorean triple. The triangle will have black edges, and will not be filled. A text label (with appropriate size) will be attached to the figure with the numerical values, and the axes will be drawn. Let us try the following variant, for example:

Graphics[{EdgeForm[Red],FaceForm[Darker@Green],Polygon[{{0,0},{3,0},{0,4}}],Text[{3,4,(Sqrt[(3^2)+(4^2)])},{(2/3)13,(2/3)13}]},Axes->None,ImageSize->75]

Now substituting the whole nested list {{x->3,y->4},{x->6,y->8},{x->5,y->12}} into the original version gives

With[{max=13},Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize->100]/.{{x->3,y->4},{x->6,y->8},{x->5,y->12}}]

several figures in a list.

The last command, Partition breaks the list into smaller sublist. When there are many solutions to the defining equation (that is, when max is large), we would get the following output without partitioning:

With[{max=50},Grid@{Graphics[{EdgeForm[Black],FaceForm[None],Polygon[{{0,0},{x,0},{0,y}}],Text[{x,y,(Sqrt[(x^2)+(y^2)])},{(2/3)max,(2/3)max}]},Axes->True,ImageSize->100]/.(ToRules/@Table[Reduce[(x^2)+(y^2)==(z^2)∧y≥x>0,{x,y},Integers],{z,max}])}]

We see that the grid in some cases can extend too far to the right, and you have to scroll with the mouse to see all of them.

Let us consider first the following simple example, partitioning a list of length 30 into non-overlapping sublists of length 7:

Partition[Table[k,{k,1,30}],7]

Notice that the last 2 elements are lost. One possibility to overcome this is to use the following form:

Partition[Table[k,{k,1,30}],7,7,{1,1},{}]

But we need a rectangular grid at the end, that is, we need sublists of equal length. We can fill the missing entries with a specified element:

Partition[Table[k,{k,1,30}],7,7,{1,1},x]

or, as in the example, with some empty space for the sake of the Graphics command.

Partition[Table[k,{k,1,30}],7,7,{1,1},Spacer[100]]

.. Summary

.. Sequence explorer: arithmetic, geometric and harmonic sequences

arithmetic[n_,a_,d_,q_]:=a+n  d

geometric[n_,a_,d_,q_]:=a (q^n)

harmonic[n_,a_,d_,q_]:=If[1+n d≠0,(a/(1+n d)),∞]

Manipulate[
DiscretePlot[sequence[n,a,d,q],{n,1,𝒩},PlotRange->{-window,window}],
{{𝒩,5,"Number of terms"},5,20,1},
{{window,10,"Plot window size"},1,20},
{{a,1},-5,5},
{{d,1},-5,5},
{{q,0.5},-1.3,1.3},
{
{sequence,arithmetic, "Sequence type"},
{arithmetic->"arithmetic:  n ↦ a + n d",geometric->"geometric:  n ↦ a (q^n)",harmonic->"harmonic: n ↦ \!\(\*FractionBox[\(a\), \(1\\  + \\ n\\ d\)]\)"},
ControlType->PopupMenu
} 
]

Explanation: details and variants

With the above example you can interactively explore certain properties (e.g., monotonicity, boundedness or limit) of some basic sequence types: the arithmetic, geometric and harmonic sequences.

First, we define these parametric families as Mathematica functions: n is considered to be a variable, and a, d and q as parameters.

Notice that, for example, the right-hand side of arithmetic does not depend on q. The reason we still included q as a dummy variable on the left-hand side of the definition is that this way all the 3 sequence types can be handled in a uniform way: Manipulate replaces sequence by arithmetic, geometric or harmonic, according to the user’s choice (with arithmetic being the default choice); all 3 functions formally depend on all 3 parameters.

In the definition of harmonic, a case separation is made by using If: if the denominator is non-zero, we define it to be (a/(1+n d)), otherwise its value is defined to be ∞. In this way we avoid an error message that would appear when the sliders are set in a position to cause division by 0.

Exercise.  How can one enter the ≠ and ∞ characters easily?

The realization with Manipulate is straightforward: 𝒩, window, a, d and q are controlled as discrete or continuous parameters with some default values specified. If 𝒩 is increased, then the plot window extends to the right by displaying more sequence terms, whereas controlling the value of window makes it possible to zoom in the vertical direction. We have used a new control type in the example (ControlType->PopupMenu).

The sequences are actually displayed by DiscretePlot. Its structure is analogous to Plot, so we only give one separate illustration:

DiscretePlot[Sin[(n/2)]+Sin[(n/23)],{n,1,120},FillingStyle->Red]

Exercise.  Incorporate your favorite sequence (also depending on some parameters) into the original example by adding the necessary code pieces.

ClearAll[arithmetic,geometric,harmonic]

.. Recursive sequences: the Fibonacci numbers

Manipulate[
Magnify[
Text@Column@
{
Row@
{
"The Fibonacci sequence (Subscript[F, n]):\n\n",
Row@Most@Flatten@Table[{Fibonacci[n],", "},{n,1,terms+1}],
"\n\nThe ratio of the last two terms is  ",
((Subscript[F, terms+1])/(Subscript[F, terms])),
" = ",
((Fibonacci[terms+1])/(Fibonacci[terms])),
" ≈ ",
N[((Fibonacci[terms+1])/(Fibonacci[terms])),6],
"\n"
},
Graphics@
{
ColorData["Legacy","Gold"],
Rectangle[{0,0},{GoldenRatio,1}],
White,Opacity@0,EdgeForm@{Thin,Black},
Rectangle[{0,0},{((Fibonacci[terms+1])/(Fibonacci[terms])),1}]
}
},
1.2],
{{terms,1,"Number of terms"},1,20,1,Appearance->"Labeled"},
ContentSize->600]

Explanation: details and variants

This exercise illustrates the Fibonacci sequence and its relation to the golden ratio. The Fibonacci sequence in Mathematica is Fibonacci.

Exercise.  Give the definition of the Fibonacci sequence as a recursive sequence, that is, give a definition when the (n^th) term of the sequence depends on some previous terms.

Manipulate controls the number of terms of the sequence displayed via the terms variable. The Magnify command can magnify any Mathematica object by a specified factor:

Magnify[DiscretePlot[Sin[(n/2)]+Sin[(n/23)],{n,1,120},FillingStyle->Red],0.1]

Text@Column@{...} arranges the two inner objects, Row@{...} and Graphics@{...}, into a column form, and modifies the text style.

Let us consider Row@{...} first. It displays some strings (in quotation marks), the first few terms of the Fibonacci sequence (Row@Most@Flatten@Table[{Fibonacci[n], “, ”}, {n,1,terms+1}]), and the ratio of the last two terms, together with its numerical value to 6 digits precision (N[... , 6]). Recall that “\n” denotes a new line character.

If the value of terms is 10, for example, then

With[{terms=10},Table[{Fibonacci[n],", "},{n,1,terms+1}]]

constructs the first 11 elements with some separators (,). Flatten then simplifies the nested structure, and Most omits the last comma

With[{terms=10},Most@Flatten@Table[{Fibonacci[n],", "},{n,1,terms+1}]]//FullForm

finally, Row does some formatting:

With[{terms=10},Row@Most@Flatten@Table[{Fibonacci[n],", "},{n,1,terms+1}]]//FullForm

With[{terms=10},Row@Most@Flatten@Table[{Fibonacci[n],", "},{n,1,terms+1}]]

The Graphics@{...} code piece draws two overlapping rectangles (that is why Opacity is used); one is white, the other has golden color:

With[{terms=2},Graphics@{ColorData["Legacy","Gold"],Rectangle[{0,0},{GoldenRatio,1}],White,Opacity@0,EdgeForm@{Thin,Black},Rectangle[{0,0},{((Fibonacci[terms+1])/(Fibonacci[terms])),1}]}]

We conclude from the example that the ratio ((Subscript[F, n+1])/(Subscript[F, n])) gets closer and closer to GoldenRatio, as n increases.

Exercise.  Give the exact value of the golden ratio constant. Discuss the properties of the golden rectangle.

By using the notion of the limit, we can make the above statement (“gets closer and closer to”) precise:

Limit[((Fibonacci[n+1])/(Fibonacci[n])),n->∞]

Let us add finally that the useful FunctionExpand command can be used to transform some expressions into a “simpler” form (by using some more elementary functions):

GoldenRatio//FunctionExpand

Fibonacci[n]//FunctionExpand

.. The Tower of Hanoi puzzle

sums[s_,i_]:={}/;s<i||i==0;
sums[s_,s_]:={Table[1,{s}]};
sums[s_,1]:={{s}};
sums[s_,i_]:=Module[{d},Flatten[Table[(Join[{d},#1]&)/@sums[s-d,i-1],{d,s-i+1}],1]];
hanoiP[n_,p_]:=Join[Table[1,{n-1}],Table[0,{p-n-1}],{2 n-1}]/;n<p-1;
hanoiP[n_,p_]:=hanoiP[n,p]=Module[{v,t},t=sums[n-1,p-2];v=(Join[#1,{2 Plus@@Table[Last[hanoiP[#1[[i]],p-i+1]],{i,p-2}]+1}]&)/@t;First[Sort[v,Last[#2]>Last[#1]&]]];
superHanoi[{{d_},{a_,___,b_}}]:={d,a,b};
superHanoi[{tower_,pegs_}]:=Module[{a,pat,lp=Length[pegs],n,ans={},i,p,spread,back},a=Drop[hanoiP[Length[tower],lp],-1];pat=Table[Take[tower,{1+(∑_(i=1)^(n-1))a[[i]],(∑_(i=1)^n)a[[i]]}],{n,lp-2}];spread=Table[p=Drop[pegs,{2,n}];i=Last[p];p[[-1]]=p[[2]];p[[2]]=i;{pat[[n]],p},{n,lp-2}];spread=Cases[spread,{{__},_}];back=({First[#1],Join[{Last[Last[#1]]},Complement[Last[#1],{Last[Last[#1]],Last[pegs]}],{Last[pegs]}]}&)/@Reverse[spread];(AppendTo[ans,superHanoi[#1]]&)/@spread;AppendTo[ans,{Last[tower],First[pegs],Last[pegs]}];(AppendTo[ans,superHanoi[#1]]&)/@back;Partition[Flatten[ans],3]];
towers[numDisks_,numPegs_]:=Module[{t,sH=superHanoi[{Range[numDisks],Range[numPegs]}]},FoldList[(t=#1;t[[#2[[2]]]]=Rest[t[[#2[[2]]]]];t[[Last[#2]]]=Prepend[t[[Last[#2]]],First[#2]];t)&,Join[{Range[numDisks]},Table[{},{numPegs-1}]],sH]];
colors={RGBColor[0.53,0.2,0.18],RGBColor[0.95,0.57,0.38],RGBColor[0.23,0.46,0.52],RGBColor[0.71,0.86,0.5],RGBColor[0.5,0.78,0.78],RGBColor[0.8,0.78,0.68],RGBColor[0.33,0.38,0.48],RGBColor[0.85,0.87,0.32]};
graphtower[n_,li_]:=Module[{y=-2},Graphics[{{RGBColor[0.2,0.4,0.4],Rectangle[{-.4,0},{.4,2 n+1}]},Map[(y=y+2;{EdgeForm[{Black,Thickness[.025]}],colors[[#]],Rectangle[{-2 #+.6,y+.05},{2 #-.6,y+2}]})&,Reverse[li]]},PlotRange->{{-2 n,2 n},{0,2 n+1}},AspectRatio->2]];
showtowers[li_List]:=GraphicsRow[(graphtower[Length[Flatten[li]],#]&)/@li,ImageSize->{250,200}];
HanoiDiagram[NumberOfDisks_,NumberOfPegs_,PositionInmoveList_]:=showtowers[towers[NumberOfDisks,NumberOfPegs][[PositionInmoveList]]]

Manipulate[If[PositionInmoveList>Length@towers[NumberOfDisks,NumberOfPegs],PositionInmoveList=Length@towers[NumberOfDisks,NumberOfPegs]];HanoiDiagram[NumberOfDisks,NumberOfPegs,PositionInmoveList],{{PositionInmoveList,1,"position"},1,{{8,16,32,64,128,256},{6,10,14,18,26,34},{6,8,12,16,20,24}}[[NumberOfPegs-2,NumberOfDisks-2]],1},{{NumberOfPegs,3,"number of pegs"},{3,4,5}},{{NumberOfDisks,4,"number of disks"},Range[3,8]},SaveDefinitions->True]

Explanation: details and variants

This advanced code piece solves the Tower of Hanoi puzzle, related to recursive programming and recursive sequences.

Exercise.  Make an Internet search to figure out how this puzzle works.

We are not going to analyze the above example in detail: the code is included here for fun—and to illustrate that even a short Mathematica code can solve a non-trivial task.

We are going to discuss only those commands that have not been covered in this material so far.

1.)  We already met the /; (Condition) operator: in sums[s_, i_] := {} /; s < i || i == 0 it is used to define the sums function to have the {} value if s<i or i==0.

2.)  The hanoiP[n_,p_]:=hanoiP[n,p]=Module[...] piece is a special function definition, often used in recursive programming. Let us give a simpler example.

Suppose you want to define the Fibonacci sequence by yourself. Then you could write

myfibonacci[1]=1;myfibonacci[2]=1;

and for integer arguments greater than 2:

myfibonacci[n_/;(n∈Integers&&n≥3)]:=myfibonacci[n-1]+myfibonacci[n-2]

However, computing the (30^th) term, say, takes too much time

AbsoluteTiming@myfibonacci[30]

due to fact that previous values of the myfibonacci sequence are not stored in the memory, so Mathematica has to recompute each term from the n=1 starting value recursively, requiring a huge amount of function evaluations and time. A possible workaround is to use functions that remember their previous values. This can be done in Mathematica as follows, by taking advantage of the := (delayed evaluation) and = (immediate evaluation) operators.

myfasterfibonacci[1]=1;myfasterfibonacci[2]=1;

myfasterfibonacci[n_/;(n∈Integers&&n≥3)]:=myfasterfibonacci[n]=myfasterfibonacci[n-1]+myfasterfibonacci[n-2]

The speedup is considerable:

AbsoluteTiming@myfasterfibonacci[30]

3.)  The Plus@@Table[...] piece is equivalent to Apply[Plus, Table[...]]. Let us give a simple example. The command

Apply[Plus,{a,b,c}]

just adds the elements of the list.  We already know that Total does the same:

Total@{a,b,c}

But Apply can be used not only with Plus:

Apply[Times,{a,b,c}]

We know that {a,b,c} is internally stored as

{a,b,c}//FullForm

Here, List is the head of the expression

{a,b,c}//Head

Notice that the (0^th) part of an expression is also its head:

{a,b,c}[[0]]

So Apply replaces the original head by the given one:

Plus@@{a,b,c}//FullForm

4.) Let us illustrate the command Sort[v, Last[#2]>Last[#1]&]. Suppose v is a nested list of the following form:

v={{1,2},{1,0},{-2,1},{4,5}}

Then

Sort[v,Last[#2]>Last[#1]&]

sorts the sublists according to their last component: Last[#2]>Last[#1]& is a two-variable Boolean function (that is, a “true or false” function), so you have to specify 2 arguments (#1 stands for the first, while #2 for the second argument), and both arguments should have a last element:

(Last[#2]>Last[#1])&[{1,2},{1,0}]

(Last[#2]>Last[#1])&[{1,2},{4,5}]

Otherwise (that is, if the arguments are atomic) an error message is issued:

(Last[#2]>Last[#1])&[1,2]

Since Last is equivalent to the [[-1]] operator (i.e., the first element counted from the end), we could also write

Sort[v,#2[[-1]]>#1[[-1]]&]

The SortBy command (together with Last) is equivalent to the above: the sorting order is determined by an elementwise application of Last:

SortBy[v,Last]

5.) Let us present some more list manipulation commands from the code. Drop drops some elements

Drop[{a,b,c,d,e},2]

Drop[{a,b,c,d,e},-2]

whereas Take keeps some

Take[{a,b,c,d,e},2]

Take[{a,b,c,d,e},-2]

Exercise.  Study the related commands Insert and Delete.

Reverse reverses a list

Reverse[{a,b,c,d,e}]

Complement deletes the elements of the second list from the first list

Complement[{a,b,c,d,e,f,g,h},{a,b,c}]

AppendTo appends the expression defined by the second argument to the list specified by the first argument, and assigns this new value to the variable in the first argument

AppendTo[v,d]

Prepend is analogous; it appends the new element to the beginning of the list

Prepend[{a,b},c]

Exercise.  Is there a difference between Append and AppendTo? Or between Prepend and PrependTo?

FoldList is analogous to NestList, but in each iteration step, a different argument can be supplied:

FoldList[command,first,{(Subscript[argument, 1]),(Subscript[argument, 2]),(Subscript[argument, 3])}]

Finally, Cases is analogous to Select we saw earlier. Both are used to pick out some elements of the given list. Select uses a Boolean function as a selector:

Select[{1,2,3,4,5},#>2&]

that is, an element is selected, if the test function (here the “Greater than 2?” question) yields True. Cases however, makes a selection based on the structure of the expressions:

Cases[{(n^2),(n^2013),Log[n],(m^2),(m^2013),Log[m]},(n^(_))]

that is, all elements are selected which have the form “n raised to any power” (recall the Blank (_) pattern means “any expression”).

Exercise.  Study the related commands DeleteCases, Pick, Position and Count.

ClearAll[sums, hanoiP,superHanoi,towers,colors, graphtower, showtowers, HanoiDiagram, myfibonacci,myfasterfibonacci,v]

.. Sequence limit explorer

sequence[k_]:=((k-1+Sin[2 k])/(k+1))

If[
Limit[sequence[k],k->∞]∈Reals,
"The sequence has a finite real limit. You can start the interactive application below.","Please choose another sequence. The given one does not have a finite real limit.","Please choose another sequence. Mathematica currently cannot determine the limit of this sequence."]

Manipulate[
Module[{limit,k,M,sequenceGraphPoints,inside,outside},
   sequenceGraphPoints=Table[{k,sequence[k]},{k,1,n}];
   limit=Limit[sequence[k],k->∞];
   inside=Select[sequenceGraphPoints,Abs[#[[2]]-limit]≤ϵ&];
   outside=Complement[sequenceGraphPoints,inside];
   If[Length@outside>0,M=First@Last@outside,M=1];
ListPlot[
If[Length@inside>0,{sequenceGraphPoints,inside},sequenceGraphPoints],
AxesOrigin->{0,limit},
If[joinQ==0,Joined->False,Joined->{True,False}],If[Length@inside>0,PlotStyle->{RGBColor[0.41,0.35,0.80],RGBColor[0.79,0.71,0.26]},PlotStyle->RGBColor[0.41,0.35,0.80]],PlotRange->{limit-zoom,limit+zoom},
AxesLabel->"(Subscript[a, k])",
Epilog->
{
{
{RGBColor[1,0.47,0],Thick,Line[{{0,limit},{n,limit}}]},{Dashed,RGBColor[0.6,0.73,0.36],Thick,Line[{{0,limit+ϵ},{n,limit+ϵ}}]},{Dashed,RGBColor[0.6,0.73,0.36],Thick,Line[{{0,limit-ϵ},{n,limit-ϵ}}]}
},
If[Length@inside>0&& M<n,{RGBColor[1,0,0],Thick,Line[{{M+1,limit-ϵ},{M+1,limit+ϵ}}]},Null]
},
PlotLabel->Row@{"(lim_(k->∞)) (Subscript[a, k ])= ",limit}
]
],
{{n,45,"Number of terms shown"},45,245,1},
{{ϵ,0.1,Magnify[ϵ,1.5]},0.01,0.2},
{{zoom,0.2,"Zoom"},0.005,1},
{{joinQ,0,"Join points?"},{0,1},ControlType->Checkbox}]

Explanation: details and variants

Some people may find the notion of the limit of a sequence hard to grasp for the first time. Indeed, this is one of the non-trivial concepts students may encounter soon after their elementary-level mathematics courses. This interactive application may be helpful for them illustrating sequence limits graphically.

For simplicity, we consider here only the case when the sequence converges to a finite real number.

Recall that a sequence (Subscript[a, k]) (k = 1, 2, ...) converges to a finite real number L, if, for each ϵ > 0 there is an index M ∈ ℕ such that for all k≥M we have |(Subscript[a, k])-L|≤ϵ. In this case, the number L  is denoted by (lim_(k->∞))(Subscript[a, k]).

In everyday language, (Subscript[a, k]) converges to L, if the (Subscript[a, k]) terms of the sequence get arbitrarily close to L provided that k is sufficiently large. (Of course, this sentence is not entirely precise, because it does not specify what “arbitrarily close” and “sufficiently large” mean.)

In some simpler cases,  Mathematica’s Reduce can directly verify (lim_(k-> ∞))(Subscript[a, k]) = L from the definition.

Let us consider the sequence (Subscript[a, k])=((k-((k^2)/2))/(2013-(k^2)+k)), for example. Then the definition with L=(1/2) is

(Subscript[∀, ϵ,ϵ>0])(Subscript[∃, M])(Subscript[∀, k,k≥M])Abs[((k-((k^2)/2))/(2013+k-(k^2)))-(1/2)]≤ϵ

and so

Reduce[ForAll[ϵ,ϵ>0,Exists[M,ForAll[k,k≥M,Abs[((k-((k^2)/2))/(2013-(k^2)+k))-1/2]≤ϵ]]]]

Since the limit is unique when it exists, the above does not hold for L≠(1/2):

Reduce[ForAll[ϵ,ϵ>0,Exists[M,ForAll[k,k≥M,Abs[((k-((k^2)/2))/(2013-(k^2)+k))-1/3]≤ϵ]]]]

In general, it is more effective to use Limit:

Limit[((k-((k^2)/2))/(2013-(k^2)+k)),k->∞]

The role of the If[Limit[sequence[k], k->∞]∈Reals, ... ] case separation in the example is to warn the user if the given sequence does not converge to a finite real number. We are using the

If[condition, true, false, otherwise] construction. The otherwise case is chosen, if Mathematica cannot determine whether condition is True or False. Two examples follow.

sequence1[k_]:=(((1+(1/k)))^(k^2))

If[Limit[sequence1[k],k->∞]∈Reals,"The sequence has a finite real limit. You can start the interactive application below.","Please choose another sequence. The given one does not have a finite real limit.","Please choose another sequence. Mathematica currently cannot determine the limit of this sequence."]

If the sequence is more complicated, even Limit cannot handle it. Prime[k] in Mathematica denotes the (k^th) prime number.

sequence2[k_]:=((Prime[k])^(1/k))

If[Limit[sequence2[k],k->∞]∈Reals,"The sequence has a finite real limit. You can start the interactive application below.","Please choose another sequence. The given one does not have a finite real limit.","Please choose another sequence. Mathematica currently cannot determine the limit of this sequence."]

From now on let us consider the particular sequence in the original example.

The structure of the given code piece is clear: we localize some variables, and control some sliders. With Magnify[ϵ,1.5], the ϵ character is made more visible.

In order to analyze the code within Module, let us freeze interactivity and choose some values for n, ϵ, zoom and joinQ.

With[{n=71,ϵ=0.1,zoom=0.2,joinQ=0},Module[{limit,k,M,sequenceGraphPoints,inside,outside},
	sequenceGraphPoints=Table[{k,((k-1+Sin[2 k])/(k+1))},{k,1,n}];
	limit=Limit[((k-1+Sin[2 k])/(k+1)),k->∞];
	inside=Select[sequenceGraphPoints,Abs[#[[2]]-limit]≤ϵ&];
	outside=Complement[sequenceGraphPoints,inside];
	 If[Length@outside>0,M=First@Last@outside,M=1];
          ListPlot[If[Length@inside>0,{sequenceGraphPoints,inside},sequenceGraphPoints],AxesOrigin->{0,limit},If[joinQ==0,Joined->False,Joined->{True,False}],If[Length@inside>0,PlotStyle->{RGBColor[0.41,0.35,0.80],RGBColor[0.79,0.71,0.26]},PlotStyle->RGBColor[0.41,0.35,0.80]],PlotRange->{limit-zoom,limit+zoom},AxesLabel->"(Subscript[a, k])",
Epilog->{{{RGBColor[1,0.47,0],Thick,Line[{{0,limit},{n,limit}}]},{Dashed,RGBColor[0.6,0.73,0.36],Thick,  Line[{{0,limit+ϵ},{n,limit+ϵ}}]},{Dashed,RGBColor[0.6,0.73,0.36],Thick,Line[{{0,limit-ϵ},{n,limit-ϵ}}]}},
If[Length@inside>0&& M<n,{RGBColor[1,0,0],Thick,Line[{{M+1,limit-ϵ},{M+1,limit+ϵ}}]},Null]},PlotLabel->Row@{"(lim_(k -> ∞)) \!\(\*SubscriptBox[\(a\), \(\(k\)\(\\ \)\)]\)= ",limit}]
]]

First, the sequenceGraphPoints variable is defined to contain the first n points of the sequence as a nested list—with indices as first coordinates and function values as second coordinates:

With[{n=71,ϵ=0.1,zoom=0.2,joinQ=0},Module[{limit,k,M,sequenceGraphPoints,inside,outside},
	sequenceGraphPoints=Table[{k,((k-1+Sin[2 k])/(k+1))},{k,1,n}]
]]

Then the (finite and real) limit of the sequence is determined, and stored in the limit variable:

With[{n=71,ϵ=0.1,zoom=0.2,joinQ=0},Module[{limit,k,M,sequenceGraphPoints,inside,outside},
	sequenceGraphPoints=Table[{k,((k-1+Sin[2 k])/(k+1))},{k,1,n}];
	limit=Limit[((k-1+Sin[2 k])/(k+1)),k->∞]
]]

Next, we select (and store in the inside variable) those sequenceGraphPoints for which the second coordinate is closer to limit than ϵ. The inside list therefore corresponds to sequence terms inside the green strip.

With[{n=71,ϵ=0.1,zoom=0.2,joinQ=0},Module[{limit,k,M,sequenceGraphPoints,inside,outside},
	sequenceGraphPoints=Table[{k,((k-1+Sin[2 k])/(k+1))},{k,1,n}];
	limit=Limit[((k-1+Sin[2 k])/(k+1)),k->∞];
	inside=Select[sequenceGraphPoints,Abs[#[[2]]-limit]≤ϵ&]
]]

The outside=Complement[sequenceGraphPoints, inside] definition collects the outliers into the outside variable:

With[{n=71,ϵ=0.1,zoom=0.2,joinQ=0},Module[{limit,k,M,sequenceGraphPoints,inside,outside},
	sequenceGraphPoints=Table[{k,((k-1+Sin[2 k])/(k+1))},{k,1,n}];
	limit=Limit[((k-1+Sin[2 k])/(k+1)),k->∞];
	inside=Select[sequenceGraphPoints,Abs[#[[2]]-limit]≤ϵ&];
	outside=Complement[sequenceGraphPoints,inside]
]]

If there are no terms outside (Length@outside==0), then the index M is set to 1. Otherwise (i.e., if Length@outside>0), the value of M is the largest first component:

First@Last@{{1,((Sin[2])/2)},{2,(1/3) (1+Sin[4])},{3,(1/4) (2+Sin[6])},{4,(1/5) (3+Sin[8])},{5,(1/6) (4+Sin[10])},{6,(1/7) (5+Sin[12])},{7,(1/8) (6+Sin[14])},{8,(1/9) (7+Sin[16])},{9,(1/10) (8+Sin[18])},{11,(1/12) (10+Sin[22])},{12,(1/13) (11+Sin[24])},{14,(1/15) (13+Sin[28])},{15,(1/16) (14+Sin[30])},{18,(1/19) (17+Sin[36])},{21,(1/22) (20+Sin[42])},{24,(1/25) (23+Sin[48])}}

Hence, in any case, if k≥M (and of course, k≤n, the number of terms considered altogether), then all (Subscript[a, k]) lie in the strip:|(Subscript[a, k])-L|≤ϵ.

What remains is to display all these objects in different colors by ListPlot.

First, it is clear that the (vertical) plot range is set to be an interval around the limit value with window width zoom (PlotRange->{limit-zoom, limit+zoom}). We also label the vertical axis (AxesLabel) and the complete plot (PlotLabel). With the AxesOrigin option, the two axes will have their intersection point at {0,limit}.

The Epilog piece draws the two dashed horizontal lines in this color:

ColorSetter[RGBColor[0.6,0.73,0.36]]

The limit value is represented by a thick, continuous horizontal line in this color:

ColorSetter[RGBColor[1,0.47,0]]

The If[Length@inside>0&& M<n,{RGBColor[1,0,0],Thick,Line[{{M+1,limit-ϵ},{M+1,limit+ϵ}}]},Null] part draws the thick vertical segment (of height 2ϵ), representing the position of the M index in the limit definition, in

ColorSetter[RGBColor[1,0,0]]

color, provided that there are terms in the strip and M is still less than the total number of terms considered (Length@inside>0 && M<n). Otherwise, no vertical segment is drawn: Null.

Finally, we see that there are multiple case separations in the main part of ListPlot.

ListPlot[If[Length@inside>0,{sequenceGraphPoints,inside},sequenceGraphPoints],...,If[joinQ==0,Joined->False,Joined->{True,False}],If[Length@inside>0,PlotStyle->{RGBColor[0.41,0.35,0.80],RGBColor[0.79,0.71,0.26]},PlotStyle->RGBColor[0.41,0.35,0.80]],...]

Namely, if there are points in the strip (if Length@inside>0), then two sets of points are superimposed on each other: sequenceGraphPoints in

ColorSetter[RGBColor[0.41,0.35,0.80]]

color, and inside in

ColorSetter[RGBColor[0.79,0.71,0.26]]

color. If there are no points in the strip (if Length@inside==0), then only sequenceGraphPoints are displayed in

ColorSetter[RGBColor[0.41,0.35,0.80]]

color.

The joinQ variable can have 0 or 1 value (controlled by Manipulate). We illustrate its effect in a simple example.

ListPlot[{{0,1},{2,5},{3,1},{5,5},{6,1}},Joined->True]

ListPlot[{{0,1},{2,5},{3,1},{5,5},{6,1}},Joined->False]

We remark that ListLinePlot could also be used:

ListLinePlot[{{0,1},{2,5},{3,1},{5,5},{6,1}}]

Exercise.  What happens in the original code, if If[joinQ==0, Joined->False, Joined->{True, False}] is replaced by If[joinQ==0, Joined->False, Joined->True]?

Exercise.  Choose and define your convergent sequence function, then explore its properties.

ClearAll[sequence,sequence1,sequence2]

.. Infinite series explorer

Definition

An infinite series (∑_(k=1)^∞)(Subscript[a, k]) is the sum of the terms of a given sequence {(Subscript[a, 1, ])(Subscript[a, 2]), (Subscript[a, 3]),... }.

More precisely, given a sequence {(Subscript[a, 1, ])(Subscript[a, 2]), (Subscript[a, 3]),...},  its (n^th) partial sum, (Subscript[s, n]), is the sum of the first n terms:  (Subscript[s, n])=(∑_(k=1)^n)(Subscript[a, k]). The infinite series (∑_(k=1)^∞)(Subscript[a, k]) converges and has value L, if the sequence of its partial sums {(Subscript[s, 1]),(Subscript[s, 2]),(Subscript[s, 3,])...} converges to a finite number L.  In other words, (∑_(k=1)^∞)(Subscript[a, k])=L, if ∃ L ∈ℂ  ∀ϵ>0  ∃N∈ℕ  ∀n≥N: |(Subscript[s, n])-L|<ϵ.  A series is said to be divergent if it is not convergent.

ClearAll[k];showPartialSums[sequence_]:=
Manipulate[
Column@
{
Pane@Row@{Text@"The first few terms of the (Subscript[a, k]) sequence: ",Text@Table[N[sequence,3],{k,1,𝒩}]},Row@{Text@"(lim_(k-> ∞)) (Subscript[a, k]) = ",Limit[sequence,k->∞]},
Magnify[DiscretePlot[sequence,{k,1,𝒩},AxesLabel->{"k","(Subscript[a, k])"}],1.2],
Spacer[{50,50}],
Pane@Row@{Text@"The corresponding (Subscript[s, n]) partial sums: ",Text@Table[N[Sum[sequence,{k,1,n}],3],{n,1,𝒩}]},Row@{"(Underoverscript[ ∑, (    k=1), (  ∞)])(Subscript[a, k]) = \!\(\*UnderscriptBox[\(lim\), \(n -> \\ ∞\)]\)(Underoverscript[ ∑, (    k=1), (  n)])(Subscript[a, k]) = (lim_(n-> ∞)) (Subscript[s, n ]) = ",Quiet@Check[Sum[sequence,{k,1,∞}],∞]},Magnify[DiscretePlot[Sum[sequence,{k,1,n}],{n,1,𝒩},AxesLabel->{"n","(Subscript[s, n])"}],1.2]
},
{{𝒩,5,"Number of terms of the sequence"},5,30,1},
ContentSize->{750,550}]

TabView[
#->showPartialSums[#]&/@
{(1/k),((((-1))^k)/k),((((-1))^(k-1))/(2k-1)),(1/(k^2)),(1/(2^k)),(2^k),(k/(((-E))^k)),(1/(k!)),(1/(Prime[k]))},
ControlPlacement->Left]

Convergence tests

Ratio test

Suppose that the limit (Subscript[L,  ratio]):=(lim_(k-> ∞)) |((Subscript[a, k+1])/(Subscript[a, k]))| exists. Then (Subscript[L,  ratio]) < 1 implies that  (∑_(k=1)^∞)(Subscript[a, k]) converges, and (Subscript[L,  ratio]) > 1 implies that  (∑_(k=1)^∞)(Subscript[a, k]) diverges. If (Subscript[L,  ratio])=1, then the ratio test can not be applied.

ratioTest[sequence_]:=Limit[Abs[((sequence/.{k->k+1})/sequence)],k->∞]

Root test

Suppose that the limit (Subscript[L,  root]):=(lim_(k-> ∞)) ((|(Subscript[a, k])|)^(1/k)) exists. Then (Subscript[L,  root]) < 1 implies that  (∑_(k=1)^∞)(Subscript[a, k]) converges, and (Subscript[L , root]) > 1 implies that  (∑_(k=1)^∞)(Subscript[a, k]) diverges. If (Subscript[L,  root])=1, then the root test can not be applied.

rootTest[sequence_]:=Limit[((Abs[sequence])^(1/k)),k-> ∞]

Manipulate[
Which[
TrueQ[0≤test@sequence<1],"(∑_(k=1)^∞)(Subscript[a, k]) converges",
TrueQ[test@sequence>1],"(∑_(k=1)^∞)(Subscript[a, k]) diverges",
TrueQ[test@sequence==1]&&test===ratioTest,"The ratio test is too weak to determine whether (∑_(k=1)^∞)(Subscript[a, k]) converges or diverges, because (lim_(k-> ∞)) |(Subscript[a, k+1])/(Subscript[a, k])| = 1.",TrueQ[test@sequence==1]&&test===rootTest,"The root test is too weak to determine whether (∑_(k=1)^∞)(Subscript[a, k]) converges or diverges, because  (lim_(k-> ∞)) ((|(Subscript[a, k])|)^(1/k)) = 1.",TrueQ[test@sequence∈Reals]==False&&test===ratioTest,"Mathematica cannot decide whether (∑_(k=1)^∞)(Subscript[a, k]) converges or diverges, because either (lim_(k-> ∞)) |(Subscript[a, k+1])/(Subscript[a, k])| does not exist (so the ratio test cannot be applied), or the limit exists but the current version of Mathematica cannot compute it.",TrueQ[test@sequence∈Reals]==False&&test===rootTest,"Mathematica cannot decide whether (∑_(k=1)^∞)(Subscript[a, k]) converges or diverges, because either (lim_(k-> ∞)) ((|(Subscript[a, k])|)^(1/k)) does not exist (so the root test cannot be applied), or the limit exists but the current version of Mathematica cannot compute it."
],
{{test,ratioTest,"Test type:"},{ratioTest,rootTest}},
{{sequence,(2^k),"The given sequence (Subscript[a, k]) = "},{(2^k),(k/(((-E))^k)),(1/k),(1/(Prime[k]))}}
]

Explanation: details and variants

This interactive application makes it possible to investigate the convergence or divergence of infinite sums, and study some convergence tests. We make a clear distinction between the original sequence and the sequence of the corresponding partial sums—understanding different properties of these two sequences is often confusing for beginners.

The TabView command applies the function showPartialSums to the given 9 sequences {(1/k),((((-1))^k)/k),((((-1))^(k-1))/(2k-1)),(1/(k^2)),(1/(2^k)),(2^k),(k/(((-e))^k)),(1/(k!)),(1/(Prime[k]))} one by one to display them and their partial sums.

The showPartialSums function uses Manipulate to control how many terms of the actual sequence (𝒩) should be taken into account for the computations. Some known display elements and formatting (Column, Row, Text, Magnify) are used to enhance the appearance; the Pane command restricts its content to a rectangular window of fixed maximal size by applying line breaks when necessary (shrinking or scroll bars can also be specified).

In the upper half of the Manipulate window, the sequence selected by TabView on the left is shown: the first 𝒩 elements numerically (Table[N[sequence, 3],{k,1,𝒩}]), the limit of the sequence (whenever it exists, or Mathematica can determine it), and a plot (DiscretePlot[sequence,{k,1,𝒩},...]).

Exercise.  Is there a sequence among the examples for which Mathematica cannot determine its limit?

In the lower half of the Manipulate window, the partial sums of (Subscript[a, k]) are displayed in an analogous way (Table[N[Sum[sequence,{k,1,n}], 3],{n,1,𝒩}] and DiscretePlot[Sum[sequence,{k,1,n}],{n,1,𝒩},...]).

We perform a convergence check by Quiet@Check[Sum[sequence,{k,1,∞}], ∞].  Let us give an example. The command

Sum[(1/k),{k,1,∞}]

produces a warning (more precisely, a message), but we do not want this to appear in the Manipulate window. So we check for messages by

Check[Sum[(1/k),{k,1,∞}],"The command produced a message."]

and suppose that the message was generated because the sum diverges to ∞ (this last assumption is true in the 3 divergent cases in the original example, but not true in general). To suppress the message itself, Quiet is applied:

Quiet@Check[Sum[(1/k),{k,1,∞}],∞]

The ratioTest and rootTest functions are straightforward Mathematica implementations of the corresponding mathematical definitions. A Manipulate is set up at the end to illustrate the convergence tests on a set of predefined examples. The test variable is either ratioTest or rootTest.

Let us analyze the decision process in detail when test is chosen to be the ratioTest: there are 4 further cases separated by Which.

The (Subscript[L,  ratio]) < 1 case corresponds to the TrueQ[0≤test@sequence<1] part; when (Subscript[L,  ratio]) > 1, we use TrueQ[test@sequence>1]; the (Subscript[L,  ratio])=1 case is described by TrueQ[test@sequence==1]&&test===ratioTest; finally, we apply the TrueQ[test@sequence∈Reals]==False&&test===ratioTest Boolean function to see if none of the previous conditions are satisfied.

The TrueQ[condition] function always produces a True of False answer (similarly to the If[condition, true, false, otherwise] construction): if condition is true, then it gives True; if condition is false, then it gives False; while if the truth value of condition cannot be determined, then it also produces False. The third case can also happen:

Limit[(1/(Prime[k])),k->∞]

0≤Limit[(1/(Prime[k])),k->∞]<1

Since the limit in this case remains unevaluated, Mathematica cannot decide whether the limit is less than one or not, for example. In this situation we use TrueQ to force a False answer:

TrueQ[0≤Limit[(1/(Prime[k])),k->∞]<1]

As for the === (SameQ) command, we have already met the =, := and == operators: === is a Boolean function related to ==. It can be easily explained by some examples.

1+1==2

1+1===2

ClearAll[a,b];a==b

ClearAll[a,b];a===b

That is, when the two sides are evaluated and they are “mathematically” equal, both == and === give the same result.

However, the “Is it true that a equals b?” question does not have a true or false answer, because its truth value would depend on the actual values of the a and b variables. So == just leaves the a == b expression unevaluated. But in the Which construction we need a definite True or False answer, therefore the more strict === is used here: in other words, === tests for structural equality as well; in order for expression1===expression2 to be true, expression1 and expression2 should have the same values when evaluated, and they should “look” the same.

Exercise.  Can you construct an example when ratioTest yields a definite answer (that is, (Subscript[L,  ratio]) < 1 or (Subscript[L,  ratio]) > 1), but rootTest fails (i.e.,  (Subscript[L,  root])=1)? What about the other way round? Search the web.

Exercise.  Modify the code in the original example such that === is replaced by TrueQ.

Finally, it is natural at this point to remark that Mathematica makes a distinction between integers and numerical expressions containing a decimal point (.). Let us study the following examples.

N[1]

1==1.

1===1.

(Sqrt[2])

(Sqrt[2.])

1∈Integers

Element[1.,Integers]

We see that Mathematica treats 1 and 1. differently. The number 1, for example, without decimal point represents the exact integer 1, whereas 1. stands for a floating point approximate real number. Moreover, any expression containing a floating point approximate number is converted to such form. In some situations this distinction between the two number types can be very important.

.. Trigonometric function explorer

Manipulate[
Plot[
amplitude function[frequency(x+horizontal)]+vertical,{x,-2π,2π},
Ticks->{{-2π,-((3π)/2),-π,-(π/2),(π/2),π,((3π)/2),2π},True},
PlotStyle->{Thickness[0.008],Hue[0.6]},
PlotRange->{-6,6},
PlotLabel->
If[amplitude≥0,amplitude function[TraditionalForm[frequency("x"+horizontal)]]+vertical,Which[vertical>0,ToString@TraditionalForm[amplitude function[TraditionalForm[frequency("x"+horizontal)]]]<>"+"<>ToString@vertical,vertical<0,ToString@TraditionalForm[amplitude function[TraditionalForm[frequency("x"+horizontal)]]]<>"-"<>ToString@Abs@vertical,vertical==0,ToString@TraditionalForm[amplitude function[TraditionalForm[frequency("x"+horizontal)]]]]],
GridLines->Automatic,LabelStyle->Directive[FontFamily->"Helvetica",FontSize->12],ImageSize->{300,200}
],
{{frequency,1,"frequency"},-10,10,Appearance->"Labeled",ControlPlacement->Left},
{{amplitude,1,"amplitude"},-5,5,Appearance->"Labeled",ControlPlacement->Left},
{{horizontal,0,"horizontal shift"},-3.14,3.14,Appearance->"Labeled",ControlPlacement->Left},
{{vertical,0,"vertical shift"},-2,2,Appearance->"Labeled",ControlPlacement->Left},
{function,{Sin,Cos,Tan,Cot,Sec,Csc},ControlPlacement->Left}]

Explanation: details and variants

This application helps you develop some intuition and provides you with a thorough understanding about the effect of applying some (affine) linear transformations one after another on certain function graphs.

It is often hard for some students to understand the connection between the formula and the geometric transformation: which sign of which parameter controls the horizontal and vertical translation to the left of right, or the horizontal or vertical scaling (shrinking or magnification).

Exercise.  What is the definition of the sec (secant) and csc (cosecant) functions?

Exercise.  We see that the graphs are shifted upwards if the vertical shift parameter is increased. Can you explain why the graphs move to the left (and not to the right) when the horizontal shift parameter is increased?

Exercise.  We see that the graph of sin(x+π) is shifted by π unit to the left relative to the graph of sin(x). By how many units should we shift the graph of sin(2x) to the left to get the graph of sin(2x+π)? (Be careful, many people answer this question wrong!)

By now you are already familiar with the complete code that is a standard application of Manipulate with some added graphical elements.

There is only one subtlety we would like to highlight concerning PlotLabel. Mathematica evaluates x-3 as

ClearAll[x];x-3

but in the application we would like to see the more conventional x-3 form rather than the –3 + x form, that is why TraditionalForm is applied here:

TraditionalForm[x-3]

However, if we put TraditionalForm outside the expression (in PlotLabel->...), then we could get

With[{amplitude=1,function=Sin,frequency=1,horizontal=-1,vertical=1},Plot[amplitude function[frequency(x+horizontal)]+vertical,{x,-2π,2π},Ticks->{{-2π,-((3π)/2),-π,-(π/2),(π/2),π,((3π)/2),2π},True},PlotStyle->{Thickness[0.008],Hue[0.6]},PlotRange->{-6,6},
PlotLabel->TraditionalForm[amplitude function[frequency("x"+horizontal)]+vertical],
GridLines->Automatic,LabelStyle->Directive[FontFamily->"Helvetica",FontSize->12],
ImageSize->{300,200}]]

which is still not satisfactory. So let us try and apply TraditionalForm only in the function argument inside:

With[{amplitude=1,function=Sin,frequency=1,horizontal=-1,vertical=1},Plot[amplitude function[frequency(x+horizontal)]+vertical,{x,-2π,2π},Ticks->{{-2π,-((3π)/2),-π,-(π/2),(π/2),π,((3π)/2),2π},True},PlotStyle->{Thickness[0.008],Hue[0.6]},PlotRange->{-6,6},
PlotLabel->amplitude function[TraditionalForm[frequency("x"+horizontal)]]+vertical,
GridLines->Automatic,LabelStyle->Directive[FontFamily->"Helvetica",FontSize->12],
ImageSize->{300,200}]]

It seems to be working. But consider the following choice of parameters:

With[{amplitude=-1,function=Sin,frequency=1,horizontal=-1,vertical=1},Plot[amplitude function[frequency(x+horizontal)]+vertical,{x,-2π,2π},Ticks->{{-2π,-((3π)/2),-π,-(π/2),(π/2),π,((3π)/2),2π},True},PlotStyle->{Thickness[0.008],Hue[0.6]},PlotRange->{-6,6},
PlotLabel->amplitude function[TraditionalForm[frequency("x"+horizontal)]]+vertical,
GridLines->Automatic,LabelStyle->Directive[FontFamily->"Helvetica",FontSize->12],
ImageSize->{300,200}]]

The problem reoccurs, this time due to a different reason:

-Sin[TraditionalForm[x-1]]+1

is again not what we want to see, because Mathematica again does some (unexpected) transformations. A possible solution to override Mathematica’s built-in transformation rules in this situation is offered by the following case separations with If and Which, for example:

PlotLabel->If[amplitude≥0, ..., Which[vertical>0, ..., vertical<0, ..., vertical==0, ...]]

That is, in the problematic amplitude < 0 case, we manually adjust the three plot labels according to the sign of the vertical shift parameter. Within Which, we convert the formulae to strings (ToString) and concatenate (with <>) the appropriate plus or minus signs and the vertical shift parameter as we wish.

The above code piece again illustrates the flexibility of Mathematica: conditional constructions can easily be used also in plot labels.

We remark that PlotLabel automatically applies some traditional formatting (e.g., it would convert Sin to sin). Finally, also note the quotation marks around x: without quotation marks and with x having a predefined value, the plot label would not look as expected:

With[{x=2013,amplitude=1,function=Sin,frequency=1,horizontal=-1,vertical=1},PlotLabel->amplitude function[TraditionalForm[frequency(x+horizontal)]]+vertical]

.. Differential equations

ClearAll[x,m,g,t,v];
Column@{
Text@Row@
{
"The initial value problem ",TraditionalForm[x''[t]==-m·g],", ",TraditionalForm[x[0]==(Subscript[x, 0])],", ",TraditionalForm[x'[0]==(Subscript[v, 0])]," has general solution ",
TraditionalForm@(DSolve[x''[t]==-m g,x[t],t][[1,1]]/.{C[1]->"(Subscript[x, 0])",C[2]->"(Subscript[v, 0])",Rule->Equal}),
"."
},
Text@Row@
{
"With initial position ",TraditionalForm[(Subscript[x, 0])==9], " and initial speed ",TraditionalForm[(Subscript[v, 0])==0], ", the object in free fall covers the distance of ",TraditionalForm[9-5(t^2)]," units, and follows the trajectory below:"
},
Animate[
Graphics@
{
Arrow@{{0,0},{0,9.5}},
Line@{{-0.15,9},{0.15,9}},
Red,PointSize@Large,Point@{1,9-5(t^2)},
Black,Text[Style["(Subscript[x, 0])",13],{-0.5,9}],
PlotRange->{{-2,2},{-1,9.5}}
},
{t,0,(Sqrt[(9/5)])},
AnimationRepetitions->3,AnimationRunning->False]
}

ClearAll[x,k,t,ω];Manipulate[
Column[
{
Animate[
Graphics@{Arrow@{{-10,0},{10,0}},Line@{{0,-0.15},{0,0.15}},Red,PointSize@Large,Point[Flatten[{x[t]/.#,1}]],Black,Thick,Text[Style[(Subscript[x, 0]),13],{-10,2}],PlotRange->{{-11,11},{-1,3}}},
{t,0,10},AnimationRepetitions->3,AnimationRunning->False],Text@Row@{"The differential equation ",TraditionalForm[x''[t]-k x'[t]+(ω^2)x[t]==0],", ",TraditionalForm[x[0]==(Subscript[x, 0])],", ",TraditionalForm[x'[0]==(Subscript[v, 0])],", "},
Text@Row@{"representing this configuration",,","},Text@Row@{" has the following solution: ",TraditionalForm[#[[1,1]]/.Rule->Equal],"."}
}
]&@
DSolve[{x''[t]-k x'[t]+(ω^2)x[t]==0,x[0]==(Subscript[x, 0]),x'[0]== (Subscript[v, 0])},x[t],t], 
{k,-3,1/2,1/10},{ω,0,6,3/10},{(Subscript[x, 0]),-10,10,1},{(Subscript[v, 0]),0,15,1/10},ContentSize->600]

Explanation: details and variants

The first code simulates the trajectory of an object in free fall. The motion is governed by a second order linear ordinary differential equation as described by Newton’s law: x(t) represents the position after t seconds, (Subscript[x, 0 ])is the initial position at t=0, and (Subscript[v, 0]) is the initial velocity.

Exercise.  What is the physical meaning of the first and second derivatives of the function x?

The only new graphical element (Arrow) has a self-explanatory name, so it is enough to illustrate the core command DSolve[ ... , x[t], t], capable of solving wide classes of differential equations by formulae.

DSolve[x''[t]==-m g,x[t],t]

The C[1] and C[2] constants will have concrete values if we specify some initial values:

DSolve[{x''[t]==-m g,x[0]==9,x'[0]==0},x[t],t]

The highlighted solution in the example is recovered after expanding out the previous expression and using the approximate value g=10. For simplicity, we suppose that the object has mass m=1.

Exercise.  What is a more accurate value of g? Is it an absolute constant?

Expand@DSolve[{x''[t]==-m g,x[0]==9,x'[0]==0},x[t],t]

Expand@DSolve[{x''[t]==-m g,x[0]==9,x'[0]==0},x[t],t]/.{g->10, m->1}

Exercise.  What is the physical meaning of the time interval {t,0,(Sqrt[(9/5)])} given in Animate?

We know that in

DSolve[x''[t]==-m g,x[t],t][[1,1]]/.{C[1]->"(Subscript[x, 0])",C[2]->"(Subscript[v, 0])",Rule->Equal}

the [[1,1]] operator picks out the actual solution having the form of a Rule (->). This -> is replaced by ==, and the generic constants by some strings ("(Subscript[x, 0])" and "(Subscript[v, 0])"):

DSolve[x''[t]==-m g,x[t],t][[1,1]]

DSolve[x''[t]==-m g,x[t],t][[1,1]]/.{C[1]->"(Subscript[x, 0])",C[2]->"(Subscript[v, 0])"}

DSolve[x''[t]==-m g,x[t],t][[1,1]]/.{C[1]->"(Subscript[x, 0])",C[2]->"(Subscript[v, 0])",Rule->Equal}

The second code piece shows the motion of an object attached to a spring, in the presence of friction (= damping); hence this ordinary differential equation (ODE) is often referred to as the ODE for the damped harmonic oscillator.

Technically, an Animate command is manipulated here: the user selects some parameter values (k, ω, (Subscript[x, 0]), (Subscript[v, 0])) with Manipulate, then the corresponding ODE is solved by DSolve, finally, the solution is used to Animate the Large Red Point.

Exercise.  Use the web to figure out the physical meaning of the parameters k and ω. What is the usual sign assumption on k? Is this assumption always satisfied in our example? For which k values do you see some strange behavior?

Exercise.  Is there any difference in the behavior of the application if the {k,-3,1/2,1/10} piece in Manipulate is replaced by {k,-3,1/2,1/10.}? Can you explain why?

Let us focus only on the non-graphical elements.

First notice that the Column[...]& command is a pure function, whose argument is

DSolve[{x''[t]-k x'[t]+(ω^2)x[t]==0,x[0]=="(Subscript[x, 0])",x'[0]==(Subscript[v, 0])},x[t],t]

or, after some simplification

DSolve[{x''[t]-k x'[t]+(ω^2)x[t]==0,x[0]=="(Subscript[x, 0])",x'[0]==(Subscript[v, 0])},x[t],t]//Simplify

Exercise.  Why did we use "(Subscript[x, 0])" instead of (Subscript[x, 0]) in the initial value? Hint: evaluate FullForm[(Subscript[x, 0])].

The slot (#) appears twice in the Column[...]& pure function. We know that its argument (DSolve) is substituted into the slots, so, by using some numerical values for simplicity, TraditionalForm[#[[1,1]]/.Rule->Equal] evaluates to

TraditionalForm[DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t][[1,1]]/.Rule->Equal]

a construction we have seen in the first code example; here it is also responsible for displaying the exact solution in the plot. On the other hand, the expression containing the other slot (Point[Flatten[{x[t] /. #, 1}]]) becomes

Point[Flatten[{x[t]/.DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t],1}]]

that is, this  x[t]/.DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t] construction just gets the solution itself:

x[t]/.DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t]

is the same as

x[t]/.{{x[t]->-(1/3) (E^(-3 t)) (1+29 (E^(3 t)))}}

We remark that instead of

Point[Flatten[{x[t]/.DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t],1}]]

we could have used

Point[Flatten[{DSolve[{x''[t]-(-3) x'[t]+(0^2)x[t]==0,x[0]==-10,x'[0]==1},x[t],t][[1,1,2]],1}]]

The DSolve[...][[1,1,2]] construction can be advantageous over x[t] /. DSolve[...], if, for example, you do not know the name of the solution function (here being x[t]).

Exercise.  Could you use the command ParametricNDSolve in this example as an alternative?

.. Statistical means explorer

Manipulate[
Manipulate[
Graphics[{
If[mean,{Red,Tooltip[Disk[Mean@r,.02],Row@{"arithmetic mean = ",Mean@r}]},{}],If[median,{Blue,Tooltip[Disk[Median@r,.02],Row@{"median = ",Median@r}]},{}],If[rms,{Green,Tooltip[Disk[RootMeanSquare@r,.02],Row@{"root mean square = ",RootMeanSquare@r}]},{}],If[gmean,{Magenta,Tooltip[Disk[GeometricMean@r,.02],Row@{"geometric mean = ",GeometricMean@r}]},{}],If[hmean,{Purple,Tooltip[Disk[HarmonicMean@r,.02],Row@{"harmonic mean = ",HarmonicMean@r}]},{}]},PlotRange->{{-.1,2.1},{-.1,2.1}},ImageSize->400],
{{r,RandomReal[{0,2},{number,2}]},{0.01,0.01},{1.99,1.99},Locator,LocatorAutoCreate->{1,∞}},{{mean,True,Row[{Graphics[{Red,Disk[]},ImageSize->6,BaselinePosition->(Center->Center)],"  arithmetic mean"}]},{True,False},ControlPlacement->Left},{{median,True,Row[{Graphics[{Blue,Disk[]},ImageSize->6,BaselinePosition->(Center->Center)],"  median"}]},{True,False}},{{rms,False,Row[{Graphics[{Green,Disk[]},ImageSize->6,BaselinePosition->(Center->Center)],"  root mean square"}]},{True,False}},{{gmean,False,Row[{Graphics[{Magenta,Disk[]},ImageSize->6,BaselinePosition->(Center->Center)],"  geometric mean"}]},{True,False}},{{hmean,False,Row[{Graphics[{Purple,Disk[]},ImageSize->6,BaselinePosition->(Center->Center)],"  harmonic mean"}]},{True,False}},ControlPlacement->{Top,Left,Left,Left,Left,Left,Left}],
{{number,2,"Number of random data points"},2,12,1}]

Explanation: details and variants

This interactive application helps you familiarize yourself with five statistical means.

The outer Manipulate is used to set up the appropriate number of random data points on which the inner Manipulate performs some analysis.

Therefore it is enough to focus on the inner Manipulate only. Let us suppose that number=5, for example. Then

RandomReal[{0,2},{5,2}]

yields 5 random points on the plane, and stores this initial choice in the r variable.

Exercise.  Which “2” in RandomReal[{0,2},{5,2}] is responsible for the planar configuration (i.e., for dimension 2), and which is for the right endpoint of the range [0,2]?

A Locator is used in Manipulate so that we can change r within the central window interactively.

Suppose in the following that the mean Boolean variable is active (that is, it has True value).

Then, within Graphics, the If[mean,{Red,Tooltip[Disk[Mean@r,.02],Row@{“arithmetic mean = “, Mean@r}]},{}] code piece is evaluated as

{Red,Tooltip[Disk[Mean@RandomReal[{0,2},{5,2}],.02],Row@{"arithmetic mean = ",Mean@RandomReal[{0,2},{5,2}]}]}

By hovering your mouse over the Disk[...] object, the (known) ToolTip command displays a Row object with the numerical value of the actual mean.

The core commands here are of statistical nature:

Information/@{Mean,Median,RootMeanSquare,GeometricMean,HarmonicMean};

.. Statistical distribution explorer

Let us generate some (10^4) random reals first, by sampling a Gaussian distribution (with mean = 1 and standard deviation = 3).

data=RandomVariate[NormalDistribution[1,3],(10^4)]

We can study some statistical properties of the above data by using the following tools, for example.

ListPlot[data]

Row@
{
Show[
Histogram[data,20,"ProbabilityDensity"],
Plot[PDF[NormalDistribution[1,3],x],{x,-9,9},PlotStyle->Thick],ImageSize->250],TabView[#-> #[data]&/@{Mean,Median,Variance,StandardDeviation},ControlPlacement->Left]
}

BoxWhiskerChart[data,"Outliers"]

DistributionChart@data

Explanation: details and variants

The Show command can superimpose two or more (2D or 3D) graphics. In the present example, we place a Histogram on top of a Plot. PDF of course stands for

?PDF

Notice that you can get further information in a pop-up window if you place your mouse in the central area in the output of BoxWhiskerChart or DistributionChart.

We also remark that Mathematica now supports several other (discrete or continuous) distributions.

?*Distribution

ClearAll[data]

.. Summary

The two examples in this chapter have been taken from workshop lectures held by Wolfram Research at the Wolfram Technology Conference 2012 in Champaign (Illinois), United States.

The code pieces in the first section may require Internet connection.

.. Life Expectancy vs. Literacy Rate vs. Population: a bubble chart study

In this section, we will develop, step by step, an application showing a bubble chart with various country data displayed.

Essential code pieces are shown with the usual background. Optional code pieces for further illustration use this background. Our explanations are interspersed in the text, therefore there will be no separate Explanation: details and variants section now.

Let us fetch some country data from the Wolfram servers first.

data=
Table[
{
country,100CountryData[country,"LiteracyFraction"],CountryData[country,"LifeExpectancy"],  CountryData[country,"Population"],CountryData[country,"Continent"]
},
{country,CountryData[]}];

Recall that the 100CountryData[country,”LiteracyFraction”] command multiplies each element of the list CountryData[country,”LiteracyFraction”] by 100.

The data variable now contains data ("LiteracyFraction", ..., "Continent") on 240 countries in a nested list:

data//Short

We have used Short above to see only the structure of data; the number of omitted elements is 238.

We can display the data in a table. For simplicity, we take only the first 5 pieces now.

SmallGrid[data_]:=Grid[Take[data,5],Frame->All,FrameStyle->Lighter@Gray]

SmallGrid[data]

Or we can display it as a bubble chart:

BubbleChart[data[[All,{2,3,4}]]]

Clearly, the data[[All,{2,3,4}]] construction here keeps only the (2^nd), (3^rd) and (4^th) components of the sublists for each country, so the country name and its continent is not visible on the chart:

data[[All,{2,3,4}]]//Short

Exercise.  Which piece of the country data influences the bubble sizes?

Let us add now a plot label, and labels for the axes. With ChartLabels->Placed[...,Tooltip] we create a label for each bubble. The label displays the corresponding element of data[[All,1]], that is, the country name.

BubbleChart[
data[[All,{2,3,4}]],
ChartLabels->Placed[data[[All,1]],Tooltip],
FrameLabel->{"Literacy fraction","Life expectancy"},
PlotLabel->"Life Expectancy vs. Literacy Rate vs. Population"]

Now let us group the country data by continents.

continentData=SplitBy[SortBy[data,Last],Last];

As for the command above, we already know that SortBy[..., Last] puts the sublists of the nested list data into the canonical order defined by the last components of the sublists:

Short[SortBy[data,Last],3]

SplitBy[..., Last] is analogous: elements of the above nested list are put into groups according to their last elements, i.e., according to the continents. Note that data is a nested list having 2 levels, while the list representing continentdata has 3 levels:

Short[continentData,3]

Indeed, the (1^st) level of continentData is the group of continents; we use TreeForm to display this (1^st) level:

TreeForm[continentData,1]

The (2^nd) level represents the group of countries within each continent. Let us only display, say, the South American countries (so the tree is not overcrowded):

Magnify[TreeForm[continentData[[6]],1],2.2]

Notice that the first level of continentData[[6]] is found on the second level of continentData.

Finally, on the (3^rd) level of continentData there are the individual countries, say, Argentina (again, a leaf on the (3^rd) level of continentData corresponds to the first level of continentData[[6,1]]):

TreeForm[continentData[[6,1]],1]

As we have just observed, countries are located on 6 continents:

Length[continentData]

which are

continents=Last@First@#&/@continentData

That is, the Last@First@#& function is applied to each of the 6 elements of continentData. For example, application of this function on the first element of continentData yields

continentData[[1]]

First@continentData[[1]]

Last@First@continentData[[1]]

Now an auxiliary function is defined, capable of creating tooltips:

label[{country_,x_,y_,z_,continent_}]:=Tooltip[{x,y,z},country]

This label function is applied to each element on the (2^nd) level of the continentData list:

splitdata=Map[label,continentData,{2}];

Short[InputForm[splitdata],5]

Each country is represented by a list of length 5 (e.g., {"Algeria",69.9`,74.02`,3.5423`*^7,"Africa"}), so x, y and z in label are the middle 3 numbers.

Now we can return to the bubble chart and group the bubbles according to the continents:

BubbleChart[
splitdata,
FrameLabel->{"Literacy fraction","Life expectancy"},
PlotLabel->"Life Expectancy vs. Literacy Rate vs. Population",
ChartLegends->continents]

The first phase of our little project is completed, we have created a neat visualization only in a few steps: recall that we need only the definition of data, continentData, continents, label and splitdata to produce the above bubble chart.

In the second phase we extend the number of categories displayed. Let us fetch some more data.

richData=
Table[
{
country,
100CountryData[country,"LiteracyFraction"],100CountryData[country,"MaleLiteracyFraction"],100CountryData[country,"FemaleLiteracyFraction"],CountryData[country,"LifeExpectancy"],
CountryData[country,"MaleLifeExpectancy"],CountryData[country,"FemaleLifeExpectancy"],CountryData[country,"Population"],
CountryData[country,"MalePopulation"],
CountryData[country,"FemalePopulation"],
CountryData[country,"Continent"]
},
{country,CountryData[]}];

And group it again according to continents:

splitRichData=SplitBy[SortBy[richData,Last],Last];

The splitRichData variable has the following structure:

SmallGrid[First[splitRichData]]

Instead of label, a more clever metalabel function is defined:

metalabel[{country_,lit_,mlit_,flit_,exp_,mexp_,fexp_,pop_,mpop_,fpop_,continent_}]:=Tooltip[{lit,exp,pop},country]->{country,{mlit,flit},{mexp,fexp},{mpop,fpop}}

The role of splitdata is taken over by metadata (recall that “metadata” means “data about data”):

metadata=Map[metalabel,splitRichData,{2}];

Short[InputForm[metadata],5]

The following function will produce a tooltip with extended capabilities: instead of a single data piece, it will display a little table, corresponding to each bubble. The Block command is analogous to Module, while Mouseover is similar to Tooltip.

renderBubble[{{xmin_,xmax_},{ymin_,ymax_}},{lit_,exp_,pop_},meta_]:=
Block[{country,mlit,flit,mexp,fexp,mpop,fpop},
{country,{mlit,flit},{mexp,fexp},{mpop,fpop}}=First[meta];
Mouseover[
Disk[{xmin+xmax,ymin+ymax}/2,{xmax-xmin,ymax-ymin}/2],
{
Disk[{xmin+xmax,ymin+ymax}/2,{xmax-xmin,ymax-ymin}/2],
{
Black,
Inset[Grid[{{"","Lit.","L. Exp.","Pop"},{"M",mlit,mexp,mpop},{"F",flit,fexp,fpop}},Dividers->All,Background->White],Scaled[{0.02,0.98}],{Left,Top}]
}
}
]
]

Finally, we arrange metadata into a bubble chart and use the renderBubble function to provide the user with some additional data on female and male literacy, life expectancy and population, for each country.

BubbleChart[metadata,
ChartElementFunction->renderBubble,
FrameLabel->{"Literacy fraction","Life expectancy"},
PlotLabel->"Life Expectancy vs. Literacy Rate vs. Population",
ChartLegends->continents]

.. Optical analysis of music sheets

The following example has the flavor of a real-life application. Here we will make no attempt to understand every piece of the code: the purpose of the example is to illustrate the solution of a non-trivial task with only a few lines of Mathematica code (similarly to the Tower of Hanoi puzzle). We only give a brief explanation on the main building blocks: it is our hope that—at this point of the course and given enough time—the interested reader could figure out the missing details. Similarly to the previous section, we use this background for the essential code pieces, whereas this background for remarks and explanations.

Let us consider the following music sheet (being a simplified version of the corresponding, original music), encoded as a normal 2D image:

sheet=;

Exercise.  Before proceeding, can you recognize the music from the sheet?

The goal is to develop a Mathematica application that “imports the image of the music sheet, extracts the individual image portions corresponding to each staff, finds the vertical and horizontal positions of the different types of notes, converts the vertical positions with respect to the staff into notes, converts the horizontal positions into a temporal positions according to the notes’ types, finally plays the sequence of notes according to pitch and  duration”.

Although the task carried out by the program is remarkable, this version of the code is, of course, by no means perfect: some more fine-tuning would be necessary, for example, to recognize the natural sign   at the very end. Moreover, as you will hear, the recognition of some parts of the sheet is incomplete (sometimes “ghost” notes are also detected), as it is often the case with, say, optical character recognition.

Let us see one possible solution.

First, we detect the line features of the image (lines) and keep only the horizontal lines (lh):

lines=ImageLines[ColorNegate@sheet,Automatic,.005];
lh=Select[lines,#[[1,2]]==#[[2,2]]&];

lines//Short

lh//Short

We sort the horizontal lines by their vertical location, and make groups of five:

staves=Partition[SortBy[lh,-#[[1,2]]&],5,5];

The staves variable is formally a nested list:

{staves//Length,staves//Short}

But it already encapsulates the requested information:

Show[sheet,Graphics@Table[{ColorData[24][i],Thick,Line/@staves[[i]]},{i,Length@staves}]]

The next step is to estimate the vertical distance (denoted by δ) between a pair of the 5 regular lines. This step is necessary because we want to recognize also the notes that are printed below or above the 5 regular lines.

δ=Module[{a,b,x},Abs@Mean@Table[With[{ylines=l[[All,1,2]]},a/.FindFit[ylines,a x+b,{a,b},x]],{l,staves}]]

Here the l variable runs through the 4 sublists of staves. So, for example, when l=staves[[1]], then

staves[[1]][[All,1,2]]

and we seek a linear (interpolating) polynomial (a x+b) that gives a best fit to the given data:

ClearAll[a,b,x];FindFit[staves[[1]][[All,1,2]],a x+b,{a,b},x]

Show[ListPlot[{387.272,379.26,371.248,363.236,355.224},PlotStyle->{Red,PointSize@Large}],Plot[a x+b/.{a->-8.01202,b->395.284},{x,1,5}]]

We repeat the above process with the remaining 3 sublists of staves, and average the four a values by

Mean@Table[With[{ylines=l[[All,1,2]]},a/.FindFit[ylines,a x+b,{a,b},x]],{l,staves}]

Let us proceed. Since 3 non-printed lines under or above will be sufficient, we set

n=3;

Now we would like to extract the shape of a note.

staff=staves[[1]];
img=ColorNegate@ImageTrim[sheet,Flatten[staff,1],n δ,Padding->1]

qn=Opening[img,DiskMatrix[δ/3]]

comp=ComponentMeasurements[qn,{"Area","BoundingBox"}]

We seek the most normal note:

bbox=Select[comp[[All,2]],Abs[#[[1]]-Median[comp[[All,2,1]]]]<5&,1][[1,2]];
quartertemplate=Image[ImageTrim[img,bbox],ImageSize->100]

fulltemplate=Image[MorphologicalPerimeter@quartertemplate,ImageSize->100]

Then we find the locations of the notes:

notesimg=ImageAdd[
Binarize[ImageCorrelate[img,quartertemplate,NormalizedSquaredEuclideanDistance],{0,.18}],
Binarize[ImageCorrelate[img,fulltemplate,NormalizedSquaredEuclideanDistance],{0,.18}]]

notespos=SortBy[ComponentMeasurements[Closing[notesimg,1],"Centroid"][[All,2]],First]

The pitch of the notes is found from their vertical positions:

notesindex=Round[Rescale[notespos[[All,2]],{0,Last@ImageDimensions@img},{-2(n-1),10+2n}]]

rules=Flatten@MapThread[Thread[#1+Range[0,6]->Map[Function[s,s<>ToString@#2],{"C","D","E","F","G","A","B"}]]&,{{-7,0,7},{3,4,5}}]

notes=notesindex/.rules

But we should also take into account the possible alterations. As a simplifying assumption, we use the information that there are exactly 3 alterations in the very beginning of sheet just after the G-clef, lowering the pitches of B, E and A.

alterations[note_]:=If[MatchQ[StringTake[note,1],"B"|"E"|"A"],StringTake[note,1]<>"b"<>StringTake[note,2;;],note];
notes=alterations/@notes

From the above first line, you can already recognize the music.

Now we find the duration from the horizontal positions:

data=Transpose[{notes,notespos[[All,1]]}];
data[[All,2]]=data[[All,2]]-data[[1,2]];
data=Split[data,Abs[Last@#1-Last@#2]<δ&];data=Table[z=g;z[[All,2]]=ConstantArray[Mean[z[[All,2]]],Length@z];z,{g,data}]

A note ends when the next note starts:

ends=ArrayPad[Mean/@data[[2;;,All,2]],{0,1},"Extrapolated"]

Notice (again) the use of the list[[2;;]] operator, collecting all elements from the second position to the end of the list.

The final sequence of notes:

Flatten@MapThread[Table[SoundNote[i[[1]],{i[[2]],#2}],{i,#1}]&,{data,ends}]

So far we have dealt only with the first line of the music sheet.

Let us incorporate the above algorithm into a single function by copying the previous commands into a Module—so we could have started the current section essentially from here without presenting the above details.

soundFromStaff[staff_,offset_:0,instrument_:"Piano"]:=Module[
{img,notesimg,comp,quartertemplate,fulltemplate,notespos,notesindex,rules,notes,alterations,data,g,tmp,ends},
img=ColorNegate@ImageTrim[sheet,Flatten[staff,1],n δ,Padding->1];
comp=ComponentMeasurements[Opening[img,DiskMatrix[δ/3]],{"Area","BoundingBox"}];
quartertemplate=ImageTrim[img,Select[comp[[All,2]],Abs[#[[1]]-Median[comp[[All,2,1]]]]<5&,1][[1,2]]];
fulltemplate=MorphologicalPerimeter@quartertemplate;
notesimg=ImageAdd[
Binarize[ImageCorrelate[img,quartertemplate,NormalizedSquaredEuclideanDistance],{0,.18}],
Binarize[ImageCorrelate[img,fulltemplate,NormalizedSquaredEuclideanDistance],{0,.18}]
];
notespos=SortBy[ComponentMeasurements[Closing[notesimg,1],"Centroid"][[All,2]],First];
notesindex=Round[Rescale[notespos[[All,2]],{0,Last@ImageDimensions@img},{-2(n-1),10+2n}]];
rules=Flatten@MapThread[Thread[#1+Range[0,6]->Map[Function[s,s<>ToString@#2],{"C","D","E","F","G","A","B"}]]&,{{-7,0,7},{3,4,5}}];
notes=notesindex/.rules;
alterations[note_]:=If[MatchQ[StringTake[note,1],"B"|"E"|"A"],StringTake[note,1]<>"b"<>StringTake[note,2;;],note];
notes=alterations/@notes;
data=Transpose[{notes,notespos[[All,1]]}];
data[[All,2]]=data[[All,2]]-data[[1,2]];
data=Split[data,Abs[Last@#1-Last@#2]<δ&];
data=Table[tmp=g;tmp[[All,2]]=ConstantArray[Mean[tmp[[All,2]]],Length@tmp];tmp,{g,data}];
ends=ArrayPad[Mean/@data[[2;;,All,2]],{0,1},"Extrapolated"];
Flatten@MapThread[Table[SoundNote[i[[1]],offset+{i[[2]],#2},instrument],{i,#1}]&,{data,ends}]
]

Notice in the above definition of soundFromStaff the optional arguments offset and instrument, with default values 0 and “Piano”, respectively.

We process all the 4 sublists of staves (the Do command below evaluates the given expression several times):

score={{{0,{0,0},"Instr"}}};
Do[AppendTo[score,soundFromStaff[staff,score[[-1,-1,2,-1]],"Piano"]],{staff,staves}];
score=Flatten[Rest@score]

Exercise.  How many times does Do evaluate its argument?

Finally, we can listen to the result by pressing the play button.

Sound[score,16]

.. Summary

.. The structure of Mathematica: the Kernel and Front End. Different forms of input. Some basic Mathematica syntax

In this section we list some useful notion and tips that can make your work with Mathematica easier. We also highlight some typical questions or errors that first-time Mathematica users often make. Different topics will be  separated by this background color.

Kernel and Front End

The kernel of Mathematica is the heart of the software. It is a huge collection of clever algorithms developed over the past 25 years. The kernel is the part of the software which performs the actual computations.

The front end can be thought as an interface to the user. It handles and interprets the user inputs, and communicates with the kernel. It also allows us to use the sophisticated 2D typesetting features of Mathematica.

It is possible to run many kernels simultaneously within one front end, or do computations in parallel. And vice versa, one instance of a kernel running on a powerful computer can serve several front ends with different users.

Evaluation

A main concept in Mathematica is evaluation. When you type in an expression and press Shift-Enter (or the Enter key on the numeric keypad), you ask Mathematica to evaluate your input. Notice that the Enter key alone produces only a new line.

Exercise.  Perform some basic arithmetic operations.

Menus and palettes

Palettes, for example, make it easier to enter special characters or textbook-style mathematical input, such as ψ, ☺, ✓, \[MathematicaIcon], €, (2013^2013),   (∑_(k=1)^(+∞))(1/(k^2)),   (∫_0^(+∞))(e^(-(x^2)))dx   or  (({{2, 3, 5}, {7, 11, 13}, {17, 19, 23}})).

Exercise. Try and enter some similar expressions.

Exercise. Ask your instructor to tell you about the “escape sequences”, that is, how to enter, e.g., Greek letters by the Esc + ... + Esc combination.

Also choose some colors from the Format menu.

Exercise. You may wish to spend a few minutes with your instructor on exploring the most important menus and palettes available in Mathematica.

Can you figure out how to enter the Chinese character 茶 (meaning “tea”)? Hint: you can cook Chinese tea by using the Unicode character "8336" in hexadecimal format. Use the form "\:xxxx" where "xxxx" is a hexadecimal number to enter Unicode characters.

Now predict what will happen if you drag the slider below:

Manipulate[Magnify[茶,n],{n,0.5,5}]

The In[ ] and Out[ ] symbols

In[ ] and Out[ ] pairs are automatically created each time you enter your input, or when Mathematica gives back the corresponding output. You can refer to the previous output by the % symbol:

1+1+1

5 %

Exercise. What is the meaning of the %% symbol? What does %1 mean? And what about Out[1]?

Help

By using the ?Command syntax, we obtain a quick reminder on the usage of “Command”:

?Manipulate

The form ?Comm* can be used to list all command beginning with “Comm”:

?Man*

Then, if necessary, by clicking on the “>>” link above, a pop-up Help window appears containing a detailed description of the command with many usage examples.

Exercise. With help from your instructor, explore the Help window. Practice how to find information efficiently. Observe how the different help topics are interrelated and linked together.

Why are the Mathematica commands not abbreviated?

This is among the earliest design principles: spelling out names fully makes it unnecessary for you to memorize a large number of abbreviations. You will also notice that when you begin typing a command, a pop-up menu appears, and by using the keyboard or the mouse, you can quickly choose the desired command to enter (see also the Predictive command completion paragraph below).

Cells

As you may have already noticed, there is a hierarchy of cells on the right of the Mathematica notebooks:

These cells help us group information: successive computations appear in different cells. Cells also make the copy-and-paste process easy. Notice the differences between various cell types; there are cells which cannot be evaluated (this very cell is an example, with cell type ), because, for example, they contain textual data. If a cell type is, then it can be evaluated:

1+1

When a cell is being evaluated, its border is marked with the symbol. In this case you cannot do other computations until Mathematica finishes the previous one.

If a computation takes too long, you can abort it: look for the Abort Evaluation command in the Evaluation menu. In this case the memory content with your previous computations is preserved.

If the above abort command does not help, you can also use the Quit Kernel / Local command (from the same menu). In this case however all your previous unsaved work will be lost.

Exercise. With help from your instructor, explore the cell structure of a Mathematica notebook. Use the current notebook as an example and see the Cell menu also. Practice grouping, ungrouping, closing or opening cells. (Think of these features when you make your presentation.) Delete some cells by first selecting them (then possibly undo the operation).

Different forms of input

If you run Mathematica on a computer with Internet connection, you can take advantage of the free-form input or the Wolfram Alpha input.

Try and begin your input with an = (a single equality sign): the free-form input makes it possible to use less rigorous syntax, similar to everyday speech.

If you begin your input with == (a double equality sign), your query is processed by Wolfram Alpha:

Exercise. Make several queries by using the free-form input or the Wolfram Alpha input. Use your imagination.

The predictive interface, predictive command completion, syntax coloring, selecting subexpressions by repeated clicking

These enhancements and features have been added to Mathematica to ease user inputs or the Mathematica workflow in general. You will find some of them very useful in your work.

The following screenshot (taken as a command were being typed) simultaneously shows the coloring of different variables (cyan and blue), the coloring of the commas and the caret character (pink and red; indicating that something is missing) and the coloring of the brackets (light green; indicating the beginning and the end of a command):

The next screenshot illustrates what happens when one begins typing the letters, e.g.,  Fact. Mathematica immediately opens a pop-up menu from which you can choose the desired function.

The following screenshot image shows subexpression selection (light blue rectangle) by repeatedly clicking with the mouse on a fixed part of the complete expression. More and more clicks will result in a selection of a larger and larger part. This selection feature is very useful when you want to copy and paste a syntactically correct part of a large output.

Exercise. Create a large, compound output (e.g., ∫(1/(1+(x^5)))dx as in the above example) and practice clicking repeatedly to select the desired part.

Finally, a major new feature, the predictive interface is shown in the bottom line of the next screenshot (since the screenshot here is only an image, feel free to magnify it as necessary by dragging, e.g., the lower right corner of the image):

Depending on the type of your input, Mathematica offers various menus in the bottom line. With the help of these menus (and even without knowing much Mathematica syntax), one can easily build up fairly complex computations with just a few simple clicks.

Exercise. Study the behavior of the predictive interface with your instructor. Use different types of functions as an input and see what Mathematica offers as a next step. Practice how to disable and enable again the predictive interface.

Infix, prefix or postfix forms of commands

Mathematica supports the above three types of ordering of operators and operands. Let us consider the following examples.

Infix forms (i.e., the command is placed between the arguments):

1+1

1~Plus~1

Prefix forms (i.e., the command precedes the arguments):

Plus[1,1]

N[π]

N@π

Notice that in the shorter command@argument prefix form, no brackets are needed.

Postfix form (i.e., the argument is given first):

π//N

Different types of parentheses

As we have already observed several times, square brackets [ ] should be used for the function arguments:

Cos[0]

Round parentheses ( ) signify the precedence of operators:

5 (((1+2))^2)

Braces { } are typical in list/vector/matrix operations:

Eigenvalues[{{1,2},{2,1}}]

Double brackets [[ ]] will appear when you refer to certain elements of lists:

{a,b,c,d}[[2]]

Undo

Always be prepared that the Undo command in Mathematica (see the Edit menu)  has unfortunately only very limited capabilities: it can undo only the last step at best. (There is a hope that this will change in future versions of Mathematica.) So it is wise to save your work periodically.

Exercise. Together with your instructor, familiarize yourself with the File menu and practice how to open and save your work.

Warnings

Sometimes Mathematica will issue the warning This file contains potentially unsafe dynamic content. Generally, it is safe to ignore this message (if your file comes from a trusted source), and you can simply click on the Enable Dynamics button.

Magnifying notebooks

If you feel that the actual font size in your current notebook is too small, you can always magnify the whole document by selecting the appropriate magnification factor from the lower right corner of each individual notebook.

Why has Mathematica just echoed my input?

In some cases you will experience that Mathematica just repeats your input (seemingly) without doing much/anything to it. This is the expected behavior, for example, if you define a new variable:

myvariable=5

Mathematica will also repeat your input, if its built-in rules cannot transform, simplify or compute the input expression:

∫(x^x)\[DifferentialD]x

How do I suppress long outputs?

One possibility is to use a semicolon “;” at the end of your input:

Expand[(((a+b))^16)]

myvariable2=Expand[(((a+b))^16)];

Notice that myvariable2 still contains the expanded form of (((a+b))^16):

myvariable2

As an alternative, you can use the command Short:

Short[myvariable2]

How do I clear the value of a variable?

Mathematica behaves unexpectedly in the following example:

Solve[myvariable2==1]

The reason is that the value of myvariable2 is still maintained in the system (recall that we assigned a value to myvariable2 in the above How do I suppress long outputs? paragraph). To clear its value, you can use the myvariable2=. form, or the more effective command

ClearAll[myvariable2]

Its value is now reset:

myvariable2

Why do I get an error message when Mathematica solves this simple equation?

Solve[a (x^2)+b x+c=0,x]

You should be aware that Mathematica has several different “equality signs”. The single “=” is used to define a variable. The double “==” should be used when solving an equation:

Solve[a (x^2)+b x+c==0,x]

I have used the double ==, still I do not get the expected answer.

Solve[(ax^2)+bx+c==0,x]

Here we have used two different variable names ax and bx, i.e., without the space character. You should take into account that, for example, ax and a x are different symbols. In other words, multiplication is denoted by a(n invisible) space character.

Why am I unable to compute the numerical value of sin(π) ?

sin(π)

You should note that Mathematica capitalizes its built-in commands. So sin and Sin are different symbols. In general, Mathematica makes a distinction between lowercase and uppercase letters.

Sin(π)

As already mentioned above, square brackets should be used to denote function evaluation. So the proper form is:

Sin[π]

What is .1 ?

In Mathematica, .1 is the same as 0.1. Recall that the decimal mark is the “.” period.

.. Some basic building blocks of Mathematica

In this section we give a selection of the most important Mathematica commands encountered in the previous chapters, and group these commands into several categories according to their role within Mathematica. It should be noted that a particular command often would fit into more than one category. We also give basic examples illustrating a possible application of each command.

Numerical computation

({{Command, Example}, {N, N[(Sqrt[2]),12] }, {π, N[π]}, {I, (I^2)}, {E, N[E]}, {GoldenRatio, FunctionExpand[GoldenRatio]}, {Re, Re[2+3I]}, {Im, Im[2+3I]}, {Abs, Abs[-1]}, {Sin, Cos, Tan, Sin[0]}, {Mod, Mod[2013,10]}, {Min, Min[2012,2013]}, {Max, Max[2012,2013]}, {Floor, Floor[-2013.5]}, {Ceiling, Ceiling[-2013.5]}, {Dot, Dot[{a,b},{c,d}]}, {Total, Total[{a,b,c,d}]}, {RandomReal, RandomReal[]}, {RandomSample, RandomSample[{a,b,c,d},2]}, {RandomChoice, RandomChoice[{a,b,c,d},5]}, {Integers, π∈Integers}, {Prime, Prime[3]}})

Solving equations and inequalities

({{Command, Example}, {Solve, Solve[a (x^2)+b x+c==0,x] }, {NSolve, NSolve[3 (x^2)-4 x-5==0,x]}, {Reduce, Reduce[a (x^2)+b x+c>0,x]}, {FindRoot, FindRoot[3 (x^2)-4 x-5==0,{x,1}]}})

Calculus

({{Command, Example}, {Limit, Limit[((Cos[x])/x),x->0] }, {Sum, Sum[(1/(k^2)),{k,1,∞}]}, {DSolve, DSolve[x'[t]==x[t] ,x[t],t]}})

Statistics

({{Command, Example}, {Mean , Mean[{3,2,1,2,3}] }, {Median , Median[{3,2,1,2,3}]}, {RootMeanSquare , RootMeanSquare[{3,2,1,2,3}]}, {Variance, Variance[{3,2,1,2,3}]}, {StandardDeviation, StandardDeviation[{3,2,1,2,3}]}, {PDF, PDF[NormalDistribution[0,1],x]}, {NormalDistribution, Plot[PDF[NormalDistribution[0,1],x],{x,-5,5}]}})

Logical operations

({{Command, Example}, {==, 1==1. }, {===, 1===1.}, {And, True&&False}, {Or, True||False}, {Implies, Implies[True,False]}, {ForAll, ForAll[x,a x^2+b x+c>0]}, {Exists, Exists[x,a x^2+b x+c==0 && x>0]}, {Element, 5∈Primes}})

Formula manipulation

({{Command, Example}, {Expand, Expand[(((a+b))^5)]}, {Factor, Factor[(a^5)+5 (a^4) b+10 (a^3) (b^2)+10 (a^2) (b^3)+5 a (b^4)+(b^5)]}, {Simplify, Simplify[((Cos[x])^2)+((Sin[x])^2)]}, {FullForm, FullForm[(a^b) c+d]}, {FunctionExpand, FunctionExpand[Sin[3Degree]]}})

List manipulation

({{Command, Example}, {Table ,   Table[(π^k),{k,0,7}]}, {Range , Range[5,9]}, {Tuples , Tuples[{a,b,c},2]}, {Select , Select[{1,2,3,4,5,6,7,8,9},EvenQ]}, {Partition , Partition[{1,2,3,4,5,6,7,8,9},2]}, { Flatten, Flatten[{{c},{{c}},{a,{b}}}]}, {Length, Length[{a,b,c,d}]}, {Part , {a,b,c,d}[[2]]}, {Part, {a,b,c,d}[[-1]]}, {Part, {a,b,c,d}[[0]]}, {Part, {a,b,c,d}[[2;;4]]}, {Part, {a,b,c,d}[[2;;]] }, {Part, {{a,a},{a,b},{a,c},{a,d}}[[All,2]]}, {First, First[{a,b,c,d}]}, {Last, Last[{a,b,c,d}]}, {Most, Most[{a,b,c,d}]}, {Rest, Rest[{a,b,c,d}]}, {Union, Union[{c,b,a,a},{d,c,b,a}]}, {Join, Join[{c,b,a,a},{d,c,b,a}]}, {Thread, Thread[{a,b,c}=={1,2,3}]}, {MemberQ, MemberQ[{1,2,3,π,4},π]}, {Sort , Sort[{"This","is","a", "big", "apple."}]}, {SortBy, SortBy[{{1,2},{2,3},{3,1}, {2,2}}, Last]}, {Take, Take[{a,b,c,d},3]}, {Drop, Drop[{a,b,c,d},3]}, {Complement, Complement[{1,2,3,4,5,6,7,8,9},{1},{2},{4},{8}]}, {Prepend, Prepend[{a,b,c,d},x]}, {AppendTo, list={a,b,c};AppendTo[list,x];list}, {Reverse, Reverse[{1,b,3,d}]}, {Tally, Tally[{a,a,π,2013,b,a,c,π,a}]}, {SplitBy, SplitBy[{3,π,-4,3,3,-2,-1.9,0,0.9,0.5},Floor]}, {Outer, Outer[Plus,{E,π},{1,2,3}]}})

String manipulation

({{Command, Example}, {StringTake ,  StringTake["The orbit of every planet is an ellipse.",25]}, {StringJoin , "The orbit of" <> " every planet "<> "is an ellipse."}, {StringSplit , StringSplit["The orbit of every planet is an ellipse."]}, {StringLength , StringLength["The orbit of every planet is an ellipse."]}, {ToString , ToString[a+1+1]}, {ToExpression , ToExpression["1+1"]}, {StringReverse , StringReverse["E két répát, na vedd agárdi, drága, de van tápértéke."]}})

Rules, patterns, pattern matching and attributes

({{Command, Example}, { Rule,  x->3}, {/., (x^2)/.x->3}, {_, StringReplace["CCACCTCCATCCTCCATTCCT","CCA"~~_~~"CCT"~~_->"GG"]}, {__ , StringReplace["CCACCTCCATCCTCCATTCCT","CCA"~~__~~"CCT"~~_->"GG"]}, {___ , StringReplace["CCACCTCCATCCTCCATTCCT","CCA"~~_~~"CCT"~~___->"GG"]}, {Cases , Cases[{a,b,a+b,a+b+c,a b},x_+y_]}, {Attributes, Attributes[Plus]}})

Defining variables and functions

({{Command, Example}, { =, a=RandomReal[] }, {=., a=.}, {ClearAll, ClearAll[a]}, { :=, a:=RandomReal[]}, { f[x_]:=..., myfunction[a_]:=(a^2)}, {/;, mysqrt[x_/;x≥0]:=(Sqrt[x])}, {f[x_,y_:defaultvalue]:=... , f[x_,y_:0]:=Cos[x y]}, {f[n_]:=f[n]= ... , f[0]=1;f[1]=1;f[n_]:=f[n]= f[n-1]+f[n-2]  }, {With, x=5;With[{x=8},Print[(x^2)]];x}, {Module, fib[n_]:=Module[{f},f[0]=f[1]=1;f[i_]:=f[i]=f[i-1]+f[i-2];f[n]];fib[5]}})

Procedural programming

({{Command, Example}, {;, a=2+3;b=2 a}, {If , If[a>2013,Print[a," > 2013"],Print[a," ≤ 2013"],Print["The comparison ",a, " > 2013 cannot be made."]]}, { Which, a=12;Which[a>2013,"a is big",0≤a≤2013,"a is small",a<0,"a is negative",True, "none of the above"]}, {Quiet, Quiet[(1/0)]}, {Check, Check[I>1,"the comparison failed"]}, {Do, x=.;temp=x;Do[temp=(Sqrt[temp+1]),{8}];temp}})

Functional programming

({{Command, Example}, { Function,  (#+((Sin[#])/(#)))&[2013]}, {Nest , Nest[(Sqrt[1+#])&,x,8]}, {NestList , NestList[(Sqrt[1+#])&,x,8]}, {FoldList, FoldList[Plus,0,{a,b,c,d}]}, {Map , Reverse/@{{a,b},{3,2},{2013,c,d}}}, {Apply, Apply[Times,{a,b,c,d}]}})

Graphics, visualization and graphics primitives

({{Command, Example}, {Plot, Plot[Cos[x],{x,-π,π}]}, {Plot3D, Plot3D[Sin[(x^2)+(y^2)],{x,-3,3},{y,-2,2}]}, {ParametricPlot3D, ParametricPlot3D[{(2+Cos[v])Cos[u],(2+Cos[v])Sin[u],Sin[v]},{u,0,π},{v,0,2π}]}, {ListPlot, ListPlot[{1,2,3,5,8,13,21}]}, {ListLinePlot, ListLinePlot[{1,2,3,5,8,13,21}]}, {DiscretePlot, DiscretePlot[Prime[n],{n,1,20}]}, {ContourPlot, ContourPlot[Sin[(x^2)+(y^2)],{x,-3,3},{y,-2,2}]}, {RegionPlot, RegionPlot[(1/9)≤(x^2)+(y^2)≤1,{x,-1,1},{y,-1,1}]}, {GraphPlot, GraphPlot[{1->2,2->1,1->3,3->1,1->4,4->1,4->4,2->2}]}, {Histogram, Histogram[{1,12,3,2,4,6,7,8,6,4,2}]}, {BubbleChart, BubbleChart[RandomReal[1,{5,4,3}]]}, {Show, Show[Plot[(x^2),{x,0,3}],ListPlot[{1,4,9}]]}, {TabView, TabView[{x->a,y->b,z->c}]}, {Grid, Grid[{{1,α},{,∞}}]}, {Row, Row[{first,second,third}]}, {Column, Column[{first,second,third}]}, {Rectangle, Graphics[Rectangle[{0,0},{3,1}]]}, {Circle, Graphics[Circle[{0,0},{3,4}]]}, {Disk, Graphics[Disk[]]}, {Polygon, Graphics3D[Polygon[{{1,0,0},{1,1,1},{0,0,1}}]]}, {Line, Graphics[Line[{{1,0},{2,1},{3,0},{4,1}}]]}, {Cuboid, Graphics3D[Cuboid[]]}, {Sphere, Graphics3D[Sphere[{0,0,0}]]}, {Cone, Graphics3D[Cone[]]}})

Image processing

({{Command, Example}, {ImageTake,  ImageTake[,54]}, {ImageDimensions, ImageDimensions[]}, {ImagePartition, ImagePartition[,20]}, {ImageAssemble, ImageAssemble[{{,,},{,,},{,,}}]}, {Rotate , Rotate["Am I rotated?",π/2]}, {Magnify , Magnify[1+,5]}, {ColorNegate, ColorNegate[]}})

Dynamic interactivity

({{Command, Example}, {Slider, Slider[(1/2)]}, {Dynamic, x=(1/2);{Slider[Dynamic[x]],Dynamic[x]}}, {Manipulate, Manipulate[Plot[Sin[a x],{x,0,2π}],{a,1,3}]}, {Animate, Animate[Plot[Sin[a x],{x,0,2π}],{a,1,3}]}})

.. Why to use Mathematica in your studies or research? Who else uses this software?

In this section we briefly survey how Mathematica evolved during the past 25 years and mention some of its potential application areas.

Stephen Wolfram    founded his company    (WRI) in 1987 and created their flagship product Mathematica in 1988. The official Mathematica logo is the spikey , whose appearance has been changing slightly from time to time.

As Wolfram himself put it, Mathematica is a “a system for doing mathematics by computer”.

Earlier, Mathematica was primarily known as a computer algebra system (CAS) with an emphasis on symbolic formula manipulation.

Today it is better described as one of the general computational software products that is used by millions of people in the industry, engineering, technical computing, science or education. The significance of how Mathematica changed the way we think about computations cannot be ignored. Nowadays many other software products (directly or indirectly) rely on Mathematica or its technology, therefore we will also mention some important web sites or initiatives that are closely related to this product.

Mathematica is built on the same, few number of carefully chosen design principles, hence the software is (in almost all cases) backward compatible. Moreover, it is often very easy to integrate new functionality into the system by building on existing pieces of code.

Exercise.  Can you spot the hyperlink behind the WRI logo above? This already illustrates the flexibility of the system: Mathematica uses different “data types”—text, graphics, formulae or sound—in a uniform manner. In this example, a hyperlink can be not only some text, but also an arbitrary image.

In order to be able to give an overview of the capabilities of Mathematica, let us list a few areas in which Mathematica excels. The following, continuously expanding list highlighting the versatility of Mathematica illustrates why it is a good choice to familiarize yourself with Mathematica and to use it in your studies.

Mathematica is an advanced calculator

Mathematica is capable of handling arbitrary large inputs (limited, in principle, only by the computer's memory) or evaluating numerical expressions to an arbitrary precision. In our first example, a huge power is computed. Notice the line breaks at the end of each line.

(2013^2013)

The time spent on the above computation is only

First@AbsoluteTiming[(2013^2013)]

seconds. So Mathematica in this example was fairly fast, although the output has

Total@DigitCount[(2013^2013)]

digits. Mathematica is flexible, because one can arrive at the same result (here, determining the number of digits in the output) by using slightly different tools:

Length@IntegerDigits[(2013^2013)]

In the second example, the constant π is instantly computed to 2013 digits of precision:

N[π,2013]

Mathematica is a technical language and a programming environment

The following diagram shows the number of built-in functions (or commands) in Mathematica (vertical axis) over the time (dates on the horizontal axis). The digits from 1 to 9 on the top of the graph refer to the successive Mathematica versions.

As the diagram suggests, Mathematica is now a huge software with vast capabilities and many ramifications spanning diverse areas. As an immediate consequence, it is almost impossible for one to comprehend all aspects of the current and future versions of Mathematica. Therefore, in these notes we can only focus on some narrowly selected slices of the software.

Mathematica supports many traditional programming paradigms. These include procedural programming, list-based programming, functional programming, rule-based programming, object-oriented programming, or string-based programming. With these programming styles at hand, it is often enough to assemble a few lines of Mathematica code to easily solve fairly complex practical problems.

Mathematica can create high quality 2D or 3D images and dynamic visualizations

As we have seen in the Images in 2D and 3D chapter, after getting some experience, it is not difficult to produce appealing 2D or 3D plots, graphs, tables or animations with a single Mathematica command.

Mathematica has also become a great tool for (scientific) presentations: see the Slide Show command in the Palettes menu.

Exercise.  Your instructor will help you show how to edit the 2D plots, or to rotate and zoom the 3D plots.

Exercise.  Create a presentation with Mathematica. Use the Slide Show command.

Mathematica is an image editor

Exercise.  Try (right-)clicking on any of the embedded images in this document: a complete image editor becomes instantly available. As one of the simplest steps, for example, try to invert the colors of an image.

Mathematica can create professional technical documents

Mathematica is an environment for easily creating high-quality documents.  In fact, this whole course material was created entirely within Mathematica.

Your work can be saved into a Mathematica notebook. Alternatively, you can easily convert them into PDF files.

With the introduction of the computable document format (CDF), see also in the File Menu, you can save your work as an interactive document similar to a Mathematica notebook, but in order to manipulate a CDF, it is sufficient to have the much simpler CDF Player and not a complete Mathematica installation.

Exercise. With the help of your instructor, try and explore the default stylesheets available in the Format/Stylesheet menu. Choose one stylesheet in which you are going to submit your future homework or exam solutions.

Wolfram Alpha

With the introduction of Wolfram Alpha in 2009, it is possible to have more and more computational capabilities of Mathematica just by using a browser.

At the core of Wolfram Alpha, there are several Mathematica kernels running on servers. The kernels process user inputs, compute answers to their questions and give the answers in forms of graphs or tables. Wolfram Alpha can also be though of as a search engine (searching in databases maintained and regularly updated by several dozens of people). Wolfram Alpha can now be easily connected to the major social networking sites to do some social network analysis.

The Wolfram Demonstrations site

By opening the page http://demonstrations.wolfram.com, you will have access to 9027 interactive Mathematica demonstrations (at the time of writing, but growing) created by volunteers. You also can be an author. The topics of these professional demonstrations include mathematics, physical and life sciences (also cognitive science), social systems, modeling, creative arts or even puzzles. The Mathematica source code is freely available for all the demonstrations. This is an excellent site to learn about new and interesting ideas.

Exercise.  Your instructor will suggest you study this site on your own and select some of your favorite demonstrations so that you will be able to do a small presentation of them in front of your class during the semester.

The MathWorld site

The http://mathworld.wolfram.com site contains a very interesting concise on-line encyclopedia of (recreational as well as more advanced university-level) mathematics.

The Functions site

The site http://functions.wolfram.com is a huge collection of (classical and advanced) mathematical functions and tables, containing approximately 300 000 mathematical formulae (more than any single book can contain).

Access to huge data collections

Since every object in the system is represented as a Mathematica expression, this makes it possible to handle different data types in a uniform and simple manner. If Mathematica is connected to the Internet, it is easy to have access to several (regularly updated) data sets.

?SocialMediaData

Exercise.  Study also the ParticleData, AstronomicalData, ExampleData, FinancialData, PolyhedronData, ProteinData, CalendarData, GenomeData, ChemicalData, GraphData, CityData, ColorData,  KnotData, WeatherData, CountryData, WordData or ElementData data sets and commands.

Mathematica on mobile devices

Various applications have been created and are available on mobile devices and tablets. These applications are using different segments of the main Mathematica engine or the Wolfram Alpha databases, hence anyone familiar with these products will easily be able to take advantage of their mobile capabilities.

Mathematica-enhanced versions of classical graphing calculators (e.g., on IPad) are becoming available these days.

Mathematica on the web

With the introduction of webMathematica about a decade ago, one can access specific Mathematica applications through a web browser. webMathematica is intended for developers.

Mathematica in the cloud

In the recent months, a new initiative, Mathematica Online has been started. The aim of Mathematica Online is to provide us with a complete Mathematica version in a normal browser window with full functionality. Apart from our Mathematica skills, no other expertise is required. There will be no need to install anything on our local computer, because Mathematica engines will be running on high-performance remote servers in the background somewhere on the web (“in the cloud”). After ordering the appropriate package, one will be able to use their computational resources depending on the type of the package purchased.

A New Kind of Science

Besides being a theoretical physicist and heavily involved in studying the behavior of cellular automata, Stephen Wolfram also authored the book A New Kind of Science (NKS) in 2002. Based on the NKS ideas, Wolfram Research organizes a summer school in each year since then.

Mathematica in education

Mathematica versions with limited functionality focusing on specific topics in education are also available on mobile devices and tablets. For example, different applications have been created for linear algebra and for multivariable calculus.

Mathematica is now a mature tool to be used in education. The initiative at http://computerbasedmath.org/ aims at rethinking how mathematics is taught: “a project to build a completely new math curriculum with computer-based computation at its heart—alongside a campaign to refocus math education away from historical hand-calculating techniques and toward relevant and conceptually interesting topics”. Estonia seems to be a pioneering country in this respect.