## Lab Manual - Computer and Mathematical Sciences - University of ...

The computers in the Mathematics Computer Lab run an operating system called ... interested in running programs, storing data, and accessing devices ...

SCARBOROUGH COLLEGE MATHEMATICS COMPUTER LAB STUDENT GUIDE

c Copyright 1991, 1992, 1993 by Mary Horrigan and Paul Selick

TABLE OF CONTENTS Part One: I II III IV V VI VII VIII Part Two: Lab I Lab II Lab III Lab IV Lab V Part Three:

User’s Guide ............................................................................................. Introduction to UNIX ............................................................................ Introduction to X Windows .................................................................. Essential UNIX Commands .................................................................. Introduction to vi .................................................................................... Introduction to emacs ............................................................................ Introduction to Mathematica ............................................................... More Advanced Uses of Mathematica ................................................ Other Information ................................................................................... Orientation Sessions................................................................................ Introduction to X Windows .................................................................. Essential UNIX Commands .................................................................. Introduction to emacs ............................................................................ Introduction to Mathematica ............................................................... Using Mathematica with Emacs .......................................................... Courseware ............................................................................................... Introduction to the Courseware ........................................................... 2D Isometries ........................................................................................... Platonic Solids.......................................................................................... Cube Symmetries .................................................................................... TicTacToe.................................................................................................. Da Vinci Game ........................................................................................ Frieze Game.............................................................................................. Wallpaper Groups ................................................................................... Geometry Tutorial 1 ............................................................................... Geometry Tutorial 2 ............................................................................... Geometry Tutorial 3 ............................................................................... Geometry Tutorial 4 ............................................................................... Geometry Tutorial 5 ............................................................................... Permutation Groups ............................................................................... Normal Subgroups................................................................................... Quotient Groups ...................................................................................... Sylow subgroups ...................................................................................... Linear Groups .......................................................................................... Group Actions.......................................................................................... Jordan Normal Form .............................................................................. Sequences .................................................................................................. Conditionally Convergent Sequences .................................................. Congruences ............................................................................................. Sieves.......................................................................................................... Powers........................................................................................................ Orbits .........................................................................................................

1 8 12 24 29 33 44 50 53 56 60 62 68 71 73 76 81 83 84 85 88 91 93 95 98 101 103 109 111 113 114 117 121 131 134 138 143 145 147

Egyptian Fractions .................................................................................. Carmichael Numbers .............................................................................. Graph Theory........................................................................................... Shortest Paths.......................................................................................... Depth First Search.................................................................................. Branchings ................................................................................................ Spanning Trees......................................................................................... Planarity.................................................................................................... Networks ................................................................................................... Matching ................................................................................................... Tours .......................................................................................................... Extension Fields....................................................................................... Finite Fields.............................................................................................. Symmetric Polynomials.......................................................................... Solvable Groups ....................................................................................... Conics......................................................................................................... Quartics ..................................................................................................... Ruler and Compass ................................................................................. Galois Groups........................................................................................... Curves ........................................................................................................ Surfaces...................................................................................................... Phase Portraits ........................................................................................ Complex Functions.................................................................................. Complex Mappings ................................................................................. Convex Hulls ............................................................................................ Part Four: Reference Materials ................................................................................ UNIX Commands Quick Reference..................................................... VI Reference Card .................................................................................. Keybindings for Emacs Math Mode Commands .............................. GNU Emacs Reference Card ................................................................

148 149 150 156 159 164 167 169 172 176 181 183 184 186 188 190 193 195 198 203 207 209 211 212 214 215 216 219 220

PART ONE: USER’S GUIDE

I. Introduction to UNIX 1. Introductory Concepts The most obvious component of a computer system is its hardware, i.e., the physical equipment. Hardware includes: • the central processing unit (CPU), which does the work of computation. • data storage devices such as random access memory (RAM), and hard disks. printer, diskette drive, and tape drive. Computer systems also include software, which consists of programs that run on the hardware. A program is usually stored on the hard disk; when it is executing, an image of the program resides in RAM. A computer system is a very complex entity, but the task it the information via programs, and produces new information for the users (output). It also allows users to store information for later use. Every computer, whether it is a small laptop, or a large mainframe, needs a program called an operating system, which supervises and controls its operation. When the computer is turned on, it begins a process called BOOTing, which involves finding and starting the operating system program. The computers in the Mathematics Computer Lab run an operating system called AIX, which is a version of UNIX. This chapter introduces the basic features of UNIX, in preparation for learning how to use the lab machines. An operating system is a complex program that manages all the hardware and software resources of the computer on which it is running. Novice users of a computer are primarily interested in running programs, storing data, and accessing devices attached to the computer; they regard the operating system as the means by which they may accomplish these tasks. UNIX is an operating system that permits many users to access its computer simultaneously. Therefore, UNIX is designed to ensure that all users receive a fair share of the resources, and that users do not interfere with each other. Understanding this is an important key to understanding UNIX. The work of managing the computer system is done by the UNIX kernel, which is a program that is executing all the time while the computer is turned on. Users cannot interact with the kernel directly; instead, UNIX provides programs called shells, which accept commands from users. This chapter deals with the features of UNIX that are most directly relevant to the needs of the beginning user. In order to run programs and access devices, the user must understand UNIX commands; in order to store data, the user must understand the UNIX file system. In addition, every user must understand the security features provided by UNIX, in order to protect his/her work. The rest of this chapter deals with these fundamental concepts.

1

2. The UNIX File System File Names There are two kinds of memory in a computer system; high-speed RAM, and lowerspeed secondary storage. RAM is volatile, which means that anything stored there is lost when the computer is turned off. Secondary storage is not volatile, which means that anything stored there is preserved when the computer is turned off. RAM is used to store data and code for a program that is actually executing; secondary storage is used to store user data for extended periods of time. In order to place data into secondary storage, it is usually necessary to explicity save the data; user data is saved in units called files. On the math lab servers, secondary storage is provided by hard disks. The amount of storage taken up on a hard disk by a file is reported in units called bytes. In the math lab, each user can store up to two megabytes (i.e. 2000 bytes) of personal data on the hard disks. Each file has a name, which is used to refer to it. Under UNIX, file names may contain as many as 256 characters, although short, meaningful file names are recommended. UNIX considers upper-case alphabetic characters to be different from the corresponding lowercase characters, so that, for example, a file named “myfile” is not the same as a file named “myFile”. Characters other than alphabetic or numeric are permitted within filenames. However, there are some characters which have special meaning to UNIX shells (called metacharacters), and so produce unexpected results if embedded in filenames. These characters are: • • • • • • • • • • • • • • • • • • • •

backslash (\), foreslash (/), asterisk (∗), question mark (?), quote (0 ), back quote (‘), double quote (”), semicolon (;), ampersand (&), left parenthesis ((), right parenthesis ()), left bracket ([), right bracket (]), left brace ({), right brace (}), sharp (#), pipe (|), greater-than (>), less-than ( symbol is used, as in the following: command > filename This will cause the command to send its output to the named file. If the named file existed prior to the output redirection, it will be overwritten. It is easy to destroy the contents of a file by mistake in this way – be careful. A more sophisticated use of I/O redirection involves redirecting the standard output of one command and way that the commands are connected. The output from To accomplish this, the | symbol is used, as in the following: command1 | command2 Such a sequence of commands is called a pipeline. Pipelines can be extended to include many commands. 6

7

course instructors will sometimes use this facility to communicate with their students (for example, to give notice that an assignment is changed). After you have read the contents of the xmessage window, move the mouse point to the small window inside the xmessage window that is labelled okay. Click the leftmost mouse button to indicate that you are finished with xmessage. The xmessage window will disappear, and a new window will appear at the upper left corner of the screen. This window will be titled with the name of the math lab server that you are connected to, either titania.scar-math-ether, or oberon.scar-math-ether. You should avoid closing this window, since that will end your session. At this point, you have successfully logged into a math lab machine, and are ready to begin working. The Root Window The screen of your X station now looks mostly gray, with a white window at the upper left corner. The gray area of the screen is also a window, called the root window. The root window provides a menu which allows you to create new windows, among other things. To activate this menu, move the mouse point into the gray area, press and hold button1. The root menu will pop up. Move the mouse point down the menu without releasing the button, until your selection is highlighted. Then release the button. If you have selected New Window, an outline of the new window will appear on the screen. Move the mouse to position the new window where you want, then click button1. Manipulating Windows X Windows (or, to be precise, the Motif Window Manager, which is an X windows program), gives you the ability to move, resize, and close the windows on the screen, except for the root window. Moving a window means altering its position on the screen; resizing a window means altering its shape and/or size. There are two special resizing operations, called maximizing and minimizing. Maximizing a window means enlarging it to cover the entire screen (thus obscuring any other window on the screen). Minimizing a window means making it an icon, which is a tiny, symbolic window located in the lower right corner of the screen. Closing a window means destroying it. All operations, except close, do not affect the contents of the window, and can be undone. Many windows can exist on the screen at the same time, but you can only interact with one at any given moment. You select the window you want to interact with, by moving the mouse point inside that window, and clicking button1. This is called giving the window focus. You will notice that the symbol for the mouse point changes as it crosses window boundaries. When the mouse point is on the gray area of the screen, it is symbolized by an X. When it is inside a window, it is symbolized by a small arrow. (The shape and colour of the mouse point indicator can be customized, but this is for advanced users.) Each window on the screen has a gray bar across the top, called the title bar. On this bar is some text, which is the title of the window. Also on this bar are three small squares. There is a square at the left, marked with a horizontal bar. There are two squares at the right; one marked with a dot, the other with a square. 9

The easiest way to log off, is to give focus to the first window that appeared (the one that is titled with the name of the math lab machine you are connected to), and then type exit in response to the shell prompt. All your windows will be closed, your session will be terminated, and a new welcome window will appear on the screen.

11

III. Essential UNIX Commands 1. Introductory Concepts As a user, your work in the math lab is accomplished by interacting with a UNIX shell. You type commands; the shell parses and then executes these commands. Each new window that you bring up under X windows provides you with a separate shell. When the new window appears, you will see the shell prompt, \$. This section of the lab manual provides a brief introduction to UNIX commands, sufficient for you to accomplish most of the tasks you will be interested in.

12

3. File and Directory Commands pwd: Print Working Directory In order to determine your current location in the UNIX filesystem, type pwd. This will print the absolute pathname of the directory where you are currently located. For example, immediately after logging in, you will be placed in your home directory, and the pwd command will produce results like the following: \$ pwd /home/smith \$ ls: List Contents of Directory The command ls lists the names of all the files in the current working directory: \$ ls current \$

data

script

The output from ls will include directory and special files, as well as ordinary files. However, ls will not list any files whose names begin with “.”. In order to see these files, you have to add the -a option to ls (for a discussion of UNIX commands and options, see the earlier section of this manual, “Introduction to UNIX”). \$ ls -a . ..

.kshrc

.profile

.Xdefaults

current

data

script

Here you can see the two special files “.” and “..”, as well as the system files “.kshrc”, “.profile”, and “.Xdefaults”. Another useful option for ls is -l. ls with this option provides a “long listing” of the files, which includes a lot of information about them: \$ ls -l total 24 drwxr-xr-x -rw-r--r--rw-r--r--

2 smith staff 1 smith staff 1 smith staff

512 May 10 15:26 current 12 Apr 08 16:36 data 69 Apr 08 16:36 script

The first field in the long listing describes the type of the file, and its access permissions. The first character in this field gives the file type: “d” for directories; “-” for ordinary files; and other characters for various kinds of special files. The next nine characters indicate whether permission is granted for read (r), write (w), execute (x) for owner, group, and others. A “-” in one of these fields indicates that permission is not granted. For example, the string “drwxr-xr-x” above indicates that “current” is a directory file, for which the owner has read, write, and execute permission, the group has read and execute, but not write, permission, and other users have read and execute, but not write, permission. The third field in the long listing gives the user name of the owner of the file, 13

in this case, smith. The fourth field gives the group name of the file, in this case, staff. The fifth field gives the size of the file, i.e. how many bytes of the hard disk it takes up. The sixth, seventh, and eighth fields give the time of last modification of the file. The last field gives the filename. ls can also be used with an argument, which can be a file name or a file name pattern. If the argument refers to a directory, ls will list the contents of that directory. \$ ls Graphics \$ ls -l total 96 -rw-r--r--rw-r--r-drwxr-xr-x \$ ls demos bessel.m

Mathematica.1

1 smith 1 smith 2 smith

demos

students students students

6505 May 04 08:37 Graphics 32225 Feb 15 13:17 Mathematica.1 512 Jan 28 14:18 demos

Creating Text Files One kind of ordinary file on the UNIX system is the ASCII text file. An ASCII text file can contain, for example, a letter, or program source code. Such a file consists of a series of lines, which are separated by the newline character. (Newline characters are only visible by their effect; they cause a carriage return, then a line feed to occur on your screen.) UNIX provides two full-screen text editors which allow you to create and modify ASCII text files. These are vi and emacs. Neither vi nor emacs is a word processor; neither does any text formatting. In order to have the facilities provided by a word processor, for example, margin justification, pagination, or font selection, you must use other programs, such as Tex. vi and emacs are discussed further in later sections of this manual. cat: Catenate (Print) File cat takes an argument, which must be the name of an existing file. cat will print the contents of this file on standard output: \$ 1 2 3

cat data a b c

cat works best on ordinary text files; it will not complain if given a directory or binary file as an argument, but the resulting output will not be intelligible. cat can be given multiple filename arguments as well; the listings of the files will follow each other sequentially, with no line break in between. As with all UNIX commands, the output of cat can be redirected: \$ cat script > new If the file “new” did not already exist, this will create “new” as a copy of “script”: 14

\$ ls current

data

new

script

If the file “new” existed prior to the use of cat, its contents will be replaced with a copy of the file “script”. cat is not a very convenient way of viewing long files, since the output will scroll off the screen too quickly for you to read. more: Print Files a Page at a Time more is like cat, in that it takes filename arguments and prints the contents of the files on standard output. Unlike cat, more produces output one screenful at a time, pausing for you to indicate when you want the next screenful printed. This makes it a more convenient file browser than cat. When more pauses, it will place a message in reverse video at the bottom of the screen, indicating the percentage of the file that has been viewed already. If you press “Enter”, one more line of the file will be added to the screen. If you press the space bar, the next screenful of output will be displayed, and more will pause again. If you want to terminate the more command, type “q” when more pauses. cp: Copy Files We saw above how you could use cat to make a copy of an existing file. UNIX provides the cp command, which does the same thing. cp takes two arguments, the name of the existing file, and the name of a new file to be created as a copy of the existing one: \$ cp data longdata \$ ls current data longdata

new

script

If the second argument indicates an already existing file, its contents will be overwritten. mv: Move Files mv renames files. It takes two arguments, the name of an already existing file, and a new name for that file: \$ mv longdata shortdata \$ ls current data new script

shortdata

The original file disappears, and the new file appears. If the second argument specifies an already existing file, it is replaced by the first file.

15

rm: Remove Files rm with a filename argument removes the specified file: \$ rm shortdata \$ ls current data

new

script

A file that has been removed cannot be retrieved; therefore, be careful when using this command. chmod: Change Permissions on a File chmod is used to change the access permissions on files, including directory files. chmod takes two arguments, a string which describes the change in permissions, and the filename. Change in permissions is expressed in the general form users change permissions where: • users represents one or more of owner, group, others using the letter codes u for owner, g for group, and o for others. • change indicates whether permission is added, deleted, or assigned, using the letter codes + for added, - for deleted, and = for assigned. • permissions indicates the permissions that are affected, using the letter codes r for read, w for write, and x for execute. Thus, the string ug+rw means to add read and write permissions for owner and group. Following is an example of the use of chmod: \$ ls -l total 32 drwxr-xr-x 2 smith -rw-r--r-1 smith -rw-r--r-1 smith -rw-r--r-1 smith \$ chmod o+x script \$ ls -l total 32 drwxr-xr-x 2 smith -rw-r--r-1 smith -rw-r--r-1 smith -rw-r--r-x 1 smith

students students students students

512 12 69 69

May Apr May Apr

10 08 10 08

15:26 16:36 15:50 16:36

current data new script

students students students students

512 12 69 69

May Apr May Apr

10 08 10 08

15:26 16:36 15:50 16:36

current data new script

On creation, the permissions of an ordinary file are automatically set to rw-r--r-; when a directory or a program executable file is created, its permissions are set to rwxr-xr-x.

16

cd: Change Current Working Directory In order to change your current working directory, use the command cd. cd takes one argument, which is the name of the new current working directory. \$ pwd /home/smith \$ cd awkstuff \$ pwd /home/smith/awkstuff The above shows user “smith” changing his current working directory from his home directory to a subdirectory named “awkstuff”. The directory argument to cd can be specified using absolute or relative pathnames, which can include the special names “.” and “..”. You can use cd with no argument, in which case you are placed in your home directory. mkdir: Create a New Directory Ordinary files are usually created by invoking a text editor, such as vi or emacs. These text editors will be discussed in detail later. New directories are created using mkdir, which takes one argument, the name of the new directory. The new directory is created as a subdirectory of the current working directory. \$ ls -l total 32 drwxr-xr-x 2 smith students -rw-r--r-1 smith students -rw-r--r-1 smith students -rw-r--r-x 1 smith students \$ mkdir newdir total 40 drwxr-xr-x 2 smith students -rw-r--r-1 smith students -rw-r--r-1 smith students drwxr-xr-x 2 smith students -rw-r--r-x 1 smith students \$ cd newdir \$ pwd /home/smith/awkstuff/newdir

512 12 69 69

May Apr May Apr

10 08 10 08

15:26 16:36 15:50 16:36

current data new script

512 12 69 512 69

May Apr May May Apr

10 08 10 11 08

15:26 16:36 15:50 10:27 16:36

current data new newdir script

rmdir: Remove a Directory You can remove a directory using rmdir, providing the directory is empty of all files. rmdir takes one argument, which is the name of the directory to be removed. \$ ls current

data

new

newdir

script 17

\$ rmdir newdir \$ ls current data

new

script

cp -r: Copy a Directory With All Its Files Since a directory may contain files, including other directories, copying a directory is more complicated than copying an ordinary file. The entire directory structure that depends from this directory must be copied. To accomplish this, use a -r option on the cp command. \$ ls -l total 96 -rw-r--r-1 smith students -rw-r--r-1 smith students drwxr-xr-x 2 smith students \$ ls demos bessel.m \$ cp -r demos demos.orig \$ ls -l total 104 -rw-r--r-1 smith students -rw-r--r-1 smith students drwxr-xr-x 2 smith students drwxr-xr-x 2 smith students \$ ls demos.orig bessel.m

6505 May 04 08:37 Graphics 32225 Feb 15 13:17 Mathematica.1 512 Jan 28 14:18 demos

6505 32225 512 512

May Feb Jan Jun

04 15 28 25

08:37 13:17 14:18 11:34

Graphics Mathematica.1 demos demos.orig

4. Environment Commands echo: Print Value of Variable In order to see the current value of a shell environment variable, use the echo command with the name of that variable as an argument: \$ echo \$PATH /bin:/usr/local/bin:/usr/bin:/etc:/usr/ucb:/usr/bin/X11 Note that the name of the variable, in this case PATH, is prefixed by a \$ symbol. The value stored in PATH is a list of directories, where the names of directories are separated by the “:” symbol. Two other important environment variables are TERM and DISPLAY: \$ echo \$TERM aixterm \$ echo \$DISPLAY flute:0 18

=: Set Value of a Variable To change the value of a variable, type the name of the variable, followed immediately by “=” (no blanks), followed immediately by the new value. \$ TERM=vt100 \$ echo \$TERM vt100 export: Make Value of Variable Available for Later Commands Setting the value of a variable will change its value for the shell in which it is set, but commands that you subsequently run in that shell will not know about the new setting unless you use the export command to make the new setting available. export takes one argument, which is the name of the variable to be made available. \$ export TERM You can combine the operations of setting and exporting the value of a variable: \$ export DISPLAY=snail:0 An important example of this procedure is modifying the value of the PATH environment variable. PATH is used by the shell to find the commands that you type. When you type a command, UNIX will search in order the sequence of directories specified in \$PATH. UNIX will execute the first file whose name is the same as the command you typed. If no such file is found in the directories specified in \$PATH, UNIX gives the error message “ksh: commandname: not found”, where commandname is the command you typed. For the math lab servers, the default value of PATH does not include the current working directory. This means that UNIX will not find any commands in your current directory, unless you either refer to the commands by an absolute pathname, as in “./commandname”, or modify your PATH. Type export PATH=\$PATH:. to modify your PATH to include your current working directory. hostname: Print the Name of the Login Machine In some situations, it will be important for you to know the name of the machine that you are currently using. This can be determined by typing hostname with no arguments. \$ hostname titania.scar-math-ether The math lab servers are named “titania.scar-math-ether” (“titania” for short), and “oberon.scar-math-ether” (“oberon” for short).

19

5. Process Control Commands ps: List Processes ps gives information about running processes. When used with no arguments, it gives a report of the processes running under the current shell: \$ ps PID 8453 10193 • • • •

TTY pts/1 pts/1

TIME CMD 0:00 -ksh 0:00 ps

There are four columns in this report: PID, which gives the unique process id. TTY, which is the terminal device controlling the process (in most cases, this is equivalent to the name of the terminal from which the process was started). TIME, which is the amount of CPU time used by the process since it was started. CMD, which is the name of the command that caused the process to be launched.

In the above example, ps reported the shell and the process started by ps itself. To get a report on all processes associated with a specific user, add the -u option to ps: \$ ps UID 200 200 200 200 200 200 200 200 200 200 200 200 200 200 200

-u smith PID TTY 7152 7170 8187 8203 pts/0 8453 pts/1 8708 9167 pts/3 9403 10195 pts/1 10446 10940 pts/2 11216 pts/3 12284 12812 pts/0 13066 -

TIME 0:00 0:05 0:00 0:01 0:00 0:13 0:02 0:00 0:00 0:15 0:00 0:02 0:00 0:05 0:42

Here we see a new field in the report, UID, which gives the user id of the owner of the process. kill: Terminate a Process The owner of a process has the ability to terminate it, using the command kill. kill takes one argument, which is the process id of the process to be terminated. This process id can be obtained via ps, as above. 20

\$ kill 12812 Occasionally, a process will survive the kill command. In that case, it is necessary to use the -9 option with kill: \$ kill -9 12812

6. Printing Commands lpstat: Report Status of Printer The printer in the math lab is capable of printing both ordinary text files (ASCII) and graphics (PostScript). In order to accomplish this, several queues are set up on the printer; different kinds of files are sent to different queues for printing. The queues of immediate interest to you are asc, for text files, and ps for graphics. You can ask for a report on the status of the queues using lpstat: \$ lpstat Queue Dev ------- ----wasc lp0 bsh bshde ps lp0 asc lp0 blp dblp blp lp

The above example shows the output of lpstat when typed on oberon. Oberon has the printer directly attached, so that the print queues ps and asc are local queues. Titania sends print requests to oberon for processing. Therefore, lpstat on titania reports twice for each of these queues – once for the queue which is local to titania, and once for the queue on oberon. \$ lpstat Queue Dev ------- ----bsh bshde asc dasc asc asc ps dps ps ps wasc dwasc wasc wasc blp dblp blp lp

If all is well with the printing system, the queues should show a status of READY, or perhaps show print jobs RUNNING or QUEUED. If there is a problem with the printer, one or more of the queues will show a status of DOWN. In such a case, intervention by the system administrator is required to fix the printing system. If you have sent a file to the printer, you can check on the status of your print job by using lpstat: \$ lpstat Queue Dev ------- ----wasc lp0 bsh bshde ps lp0 asc lp0 blp dblp blp lp

The above example shows a print job RUNNING on the ps queue, for user horrigan. The print job number is 154. This job number can be used to cancel the print job, as detailed below in the section on the cancel command. lpr: Print a File The command to print a text file is lpr -h -Pasc filename where filename is the name of the file you want to print. The -P option to lpr, followed by the name of a queue, specifies that you want the file sent to that queue. The -h option suppresses the printing of a header page. The printing of PostScript files is usually done through packages such as Mathematica and MATLAB, which produce graphics. If you want to print a PostScript graphics file directly, the command is: lpr -h -Pps filename where filename is the name of the file you want to print. cancel: Cancel Printer Jobs You can cancel a printing request that you made via lpr by using cancel. cancel takes one argument, which is either a print job number, or a printer queue name. Print job numbers are obtained via lpstat, as above. If cancel is used with a print job number argument, that print job is cancelled. If cancel is used with a printer queue name, all your jobs on the specified queue are cancelled. You can only cancel your own print jobs.

7. Remote Login You may have a user account on more than one UNIX system at the University of Toronto. Once you have logged on to one UNIX system, you can log on to any other 22

8. man: More Information About UNIX Commands UNIX provides on-line documentation of all of its commands. To access the information about a command, type man commandname The output of man is automatically displayed using more, so that you can read it a page at a time.

23

IV. Introduction to vi Introductory Concepts vi (visual editor) is a full-screen text editor which allows you to create and modify ASCII text files. The rest of this section provides a very brief introduction to vi. Not all the facilities of vi are covered; for more details, see the “VI Reference Guide” provided as an appendix to this manual, or consult an introductory UNIX text. When you invoke vi, you are provided with a temporary storage area called an edit buffer. Any characters you insert or modify, change this buffer. The changes are displayed on the screen immediately, so that you can always see what you have done. The edit buffer is not saved automatically; you must save it explicitly using a vi write command. vi displays a window into the edit buffer you are working on, which contains as many lines as will fit into the window or screen you are using. In order to determine the size of the window, vi uses the current setting of the TERM environment variable. Thus, it is important that TERM be set correctly, and exported, in order for vi to work properly. This will not be an issue when you are working inside the math lab, but will become important if you access the math lab servers from a remote location. If there are not enough lines in the edit buffer to fill the window, vi indicates the presence of empty lines with the tilde character, “ ˜ ”. Your current position within the edit buffer, the point at which all insertions, deletions, and modifications take place, is marked by the cursor. When you are using vi on the math lab servers, the cursor is marked by a solid coloured rectangle. Other computer systems may indicate the cursor differently; for example, by a coloured or blinking underscore. The cursor is positioned exactly at the character underneath it. Starting vi To start an editing session with vi, type vi filename where filename is the name of the file you want to edit. If filename exists, a copy of the file will be loaded into the edit buffer, and vi will give you a window positioned at the beginning of the buffer. If filename does not exist, vi will give you a window into an empty edit buffer; the window will be full of tildes, to indicate that all the lines are empty. vi will also place a message at the bottom of the window that filename is a new file. In either case, you have now started vi, and are ready to begin working. vi Modes There are three distinct modes of interaction with vi: command mode, edit mode, and ex mode. (ex is the name of an older UNIX editor, on which vi is based.) Command mode is the default mode; vi starts up in this mode. When in command mode, vi is expecting you to type simple commands, typically involving one or two keystrokes. These commands do things like move the cursor, move the window, delete characters, or enter edit mode. The keystrokes that make up the command are not displayed 24

anywhere on the screen; only the effect of the command is visible. If the keystrokes you type while in command mode make no sense, vi will beep to indicate that it is confused. Pressing the “Esc” key will clear up the confusion. Edit mode is entered from command mode, by typing a command that causes the insertion of text. Once vi is in edit mode, every character that you type is placed in the edit buffer, and so is displayed on the screen. There are some exceptions to this rule: “Esc” “Backspace” “Ctrl-w”

- exits edit mode and places vi back in command mode. - causes the character just before the cursor to be erased. - causes the word just before the cursor to be erased.

ex mode is entered from command mode by typing “:”, “/”, “?”, or “!!”. When vi is in this mode, the command you type is displayed on the bottom line of the window. ex mode commands include commands for reading another file, saving the edit buffer as a file, and quitting vi. When you have finished entering the command, press “Enter” to get vi to process the command. If there is an error, vi will display a message in the bottom line of the window. Otherwise, vi processes the command, and then returns to command mode. Leaving vi To leave vi, you must enter ex mode. The usual ways of leaving vi are: :wq

- write the edit buffer as a UNIX file, then quit.

:q

- quit without writing the edit buffer. If you have made changes to the edit buffer, vi will display a warning message, and give you a chance to write the buffer out.

:q!

- quit without writing the edit buffer, even if the edit buffer has been changed. vi will not give you a chance to change your mind; all the changes to the edit buffer will be lost.

Positioning the Cursor vi is a full-screen editor, which means that you have the ability to move the cursor to any position within the current window. Cursor movement is accomplished via keystrokes while in command mode. The keys that move the cursor are: “h” “l” “j” “k”

-

move move move move

the the the the

cursor cursor cursor cursor

one one one one

position to the left. position to the right. line down. line up.

On most terminals, the arrow keys in the lower right corner of the keyboard can be used as well as the letter keys. There are many other commands for cursor movement. Among the more useful are: “w” “b”

- move the cursor to the first character of the next word (i.e., right). - move the cursor to the first character of the current or previous word 25

“\$” “ˆ”

(i.e., left). - move the cursor to the last character of the current line. - move the cursor to the first character of the current line.

Positioning the Window You can move the window up and down within the edit buffer, to work with different sections of your document. The most common window movement commands are: “Ctrl-d” “Ctrl-u”

- move the window forward (i.e., toward the end of the buffer) by one half the lines in the window. - move the window backward (i.e., toward the beginning of the buffer) by one half the lines in the window.

Appending and Inserting Text The most common commands for adding text to the edit buffer are: “a” “i” “o” “O”

- vi goes into edit mode; all characters typed until the next “Esc” are placed in the edit buffer after the cursor. - vi goes into edit mode; all characters typed until the next “Esc” are placed in the edit buffer before the cursor. - vi goes into edit mode; a new line is opened after the current line; all characters typed until the next “Esc” are placed in this new line. - vi goes into edit mode; a new line is opened before the current line; all characters typed until the next “Esc” are placed in this new line.

Arguments to vi Commands Many of the vi commands that work with text, require that an area of text, such as a word or a line, be specified. Specifying a text object is done by using an argument with the command. Some arguments are: w b e 0 orˆ \$

-

word backward word end of word beginning of line end of line

Line Numbers Sometimes, you need to see line numbers on your text. To see line numbers, type :set number. Line numbers will appear to the left of the lines in the window. To get rid of the line numbers, type :set nonumber. Line numbers are used in some vi commands; for example, you can move the cursor to a specific line using the command “nG”, where n is the line number. In such situations, you can use the symbol “\$” to refer to the last line in the file, and the symbol “.” to refer to the current line. 26

Deleting Text Deleting text is done in vi command mode. The command “x” deletes the character directly under the cursor. The command “d” followed by a symbol for an area of text (see above), deletes that area of text. The command “dd” deletes the current line. If you want to delete a range of lines, and know the line numbers of the start and end of that range, you can use the command “start line number,end line numberd. For example, the command “.,\$d” deletes all lines from the current line to the end of the file. Deleted text is placed in a special buffer area, and can be recovered with the “p” command (see below). Yanking Text The command “y” followed by a symbol for an object, places a copy of that object into the same buffer that is used for deleted text. The command “yy” places a copy of the current line into the buffer. Pasting Text The command “p” inserts the most recently yanked or deleted text after the cursor. Changing Text The command “r” replaces the character under the cursor with the next character entered by the user. The command “c” followed by a symbol for a text area, causes vi to go into edit mode; all characters typed until the next “Esc” are inserted into the edit buffer in place of the specified text area, which is deleted. Repeat The command “.” will repeat the last command that changed the edit buffer. Many vi commands can be prefixed by a number, which causes the command to be done that number of times. For example, “dd” causes the current line of text to be deleted; “10dd” causes the next 10 lines of text to be deleted. Undo You can undo the last command that changed the edit buffer by typing “u” while in command mode. There is no facility for changing any command except the immediately previous one. The undo command can itself be undone. Word Searching You can ask vi to position the cursor at the next occurrence of a certain string. The window will automatically be adjusted so that the cursor (and therefore, the string of interest) is in the centre of the screen. In order to do this, you must enter ex mode by typing either “/” or “?”, then type the string of interest, then press “Enter”. If you entered ex mode with “/”, vi will search forward in the file for the next occurrence of the string. 27

If vi does not find the string by the time it reaches the end of the file, it will continue the search starting at the beginning of the file, so that the entire file is searched. This is called wrapping around. If you used “?”, vi will search backward in the file for the next occurrence of the string, again wrapping around so that the entire file is searched. If vi does not find the string, a message to that effect will appear in the bottom line of the window. If you successfully locate a string using a word search command, typing “n” while in command mode will go to the next occurrence of that string. You can use UNIX pattern matching facilities, similar to those provided by the shell for filename expansion, to specify classes of strings to search for. For more details, consult a UNIX text. Saving the Buffer In order to save your edit buffer as a file, without quitting vi, enter ex mode by typing “:”, then type w. vi will save the file under the name you gave it when you started up. If you want to save the file under a different name, type “:w filename”. You will sometimes want to extract a portion of text from a file. There are a couple of ways of accomplishing this: - You can vi the file, delete all the lines except the ones you want, then write the modified edit buffer under a new filename, using the w command as above. - You can write a specific range of lines under a new filename, by typing :start line number, end line numberw filename. Reading Another File If you want to include the contents of another ASCII file in the current edit buffer, you can do this by entering ex mode, then typing r filename. If the file is found, its contents will be placed after the current line. Recovery From Crash You are strongly encouraged to save the contents of your edit buffer frequently; if a disaster, such as a power failure or system crash, occurs during your vi editing session, you could lose all the changes you have made. However, under some circumstances, it is possible to recover the edit buffer as it was at the time of the crash. When you are able to log on to the computer again, type vi -r to get a report of any editing sessions that were saved. If the system managed to save a copy of your edit buffer, the command vi -r filename will place you back in the editing session in almost the same state as at the time of the crash.

28

V. Introduction to emacs Introductory Concepts emacs is a full-screen text editor which allows you to create and modify ASCII text files. The rest of this section provides a very brief introduction to emacs. Not all the facilities of emacs are covered; for more details, see the “Emacs Reference Guide” provided as an appendix to this manual, or consult the GNU Emacs Manual. When you invoke emacs, you are provided with a temporary storage area, an edit buffer. If you insert or modify text, this buffer is changed, and the changes are displayed on the screen immediately. None of these changes are saved permanently on the hard disk, however, unless you issue an emacs write command. emacs displays a text window, which contains lines from your edit buffer. In order to determine the correct size for the text window, and also so that commands will work properly, emacs uses the current setting of the TERM environment variable. Thus, it is important that TERM be set correctly, and exported. This will not normally be an issue if you are working inside the math lab, but will be important if you access the math lab servers via rlogin. Your current position within the edit buffer, the point at which all insertions, deletions, and modifications take place, is marked by the cursor. When you are using emacs on the math lab servers, the cursor is marked by a solid rectangle. The insertion point lies immediately to the left of the cursor, i.e., between the character underneath the cursor, and the one to its left. At the bottom of the text window is a line in reverse video, which contains text that starts like -----Emacs:. This is the mode line, which describes what is going on in the text window. Underneath the mode line is another line in normal video, the echo area, into which you type emacs commands. Starting emacs To start an editing session with emacs, type emacs filename where filename is the name of the file you want to edit. The outline of a new window will appear. Select its position by moving the outline with the mouse, then click button1. The new window will have a title bar that reads “emacs: Emacs @hostname”, where hostname is the name of the math lab server that you are connected to. As emacs is starting up, messages will appear in rapid succession in the echo area; this indicates that various emacs files are being loaded. If filename exists, a copy of the file is loaded into the edit buffer, and emacs gives you a text window positioned at the beginning of the buffer. If filename does not exist, emacs gives you a window into an empty edit buffer, and a message in the echo area that this is a new file. In either case, filename will appear in the mode line, and you are now ready to begin working. 29

Emacs Key Sequences and Commands emacs recognizes two special keys – the Control key, which is the key marked “Ctrl” on the keyboard, and the Meta key, which is the key marked “Alt” on the keyboard. Many emacs commands require that you type one of these keys at the beginning. In the following, we will write “C-” when we mean “hold down the Control key”, and “M-” when we mean “hold down the Meta key”. For example, C-x means “hold down the Control key while typing x”, and M-y means “hold down the Meta key while typing y”. C-x b means “hold down the Control key while typing x, then release the Control key and type b”. Most of the useful emacs commands are short, as in the examples above; however, emacs has many longer commands, which involve typing full words after the Meta or Control key sequences. Commands that begin with Meta or Control are echoed in the echo area, so that you can see what you are doing. You can abort a partially typed or executing command by typing C-g; this is useful for clearing things up when emacs seems to be in a confused state. Leaving emacs To leave emacs, type C-x C-c. If you have not saved your edit buffer since the last change you made, emacs will ask you whether you want to save the buffer first. Positioning the Point emacs is a full-screen editor, which means that you can move the insertion point to any position within the current window. The easiest way to move the point is to use the mouse to select the position you want, then click button1. The cursor will move to the new position of the point. You can also move the point using keystrokes: C-b C-f C-p C-n C-a C-e

or or or or

← → ↑ ↓

move move move move move move

backward one character. forward one character. backward one line. forward one line. to beginning of line. to end of line.

Positioning the Window You can move the window up and down within the edit buffer, to work with different sections of your document. The most common window movement commands are: C-v or Page Down move forward one screenful. M-v or Page Up move backward one screenful. C-l move the window so as to centre the point. Inserting Text To insert characters, just type them. The characters are inserted into the buffer at the point. The cursor and all characters after it move forward to make room for the new characters. 30

To insert a blank line, type C-o, which opens a blank line after the point. Deleting Text To delete characters, use the key marked “Delete”, or the key marked “Backspace”. These keys delete the character before the point, causing the cursor and all characters after it to move backwards. Killing Text emacs makes a distinction between deleting text, where the text is not recoverable, and killing text, where the text is saved in an area called the kill ring, and may be recovered later. The command C-k kills from the point until the end of the current line. If you want to re-insert the most recently killed text, type C-y. This places the text at the point. Working with Large Areas of Text In addition to the point, emacs recognizes another location in the edit buffer called the mark. The area of text between the point and the mark is called the region. You set the mark by moving the cursor to the desired location, then typing C-space. emacs will say “mark set” in the echo area. Other than that, there is no indication from emacs as to the location of the mark. The region changes, therefore, when either the mark or the point is moved. emacs has several commands that operate on regions of text; for example, C-w kills the current region. The text from the killed region goes into the kill ring, and can be recovered with C-y. C-w is useful for deleting large areas of text; the combination of C-w and C-y is useful for moving large areas of text from one location in a file to another. Undo The command to undo is C-x u. The first time you give this command, it undoes the last change. The point moves to the area affected by the undo. If you repeat the undo command, earlier and earlier changes are undone, back to the limit of the changes that have been recorded. Word Searching You can ask emacs to position the cursor at the next occurrence of a certain string. The window will automatically be adjusted so that the cursor (and therefore, the string of interest) is in the centre of the screen. To begin a search for string str, type C-s. You will see this command in the echo area. Next, begin typing str. The characters you type will be echoed after C-s, and simultaneously, the point will move to the first occurrence of the string you have typed so far. When you are finished typing the string, type Esc. This terminates the search, and the point will be left at the first occurrence of the complete string. If you want the next occurrence of str, type C-s C-s Esc. If you want to search backwards in your document instead of forward, type C-r instead of C-s. You can use UNIX pattern matching facilities, similar to those provided by the shell for filename expansion, to specify classes of strings to search for. For more details, consult the emacs manual. 31

Out[1]= 8 In[2]:= to do the numerical calculation 3+5. Mathematica does this, and prints the output, 8. Mathematica output lines are prefixed with “Out[n]=”, where n is the number of the corresponding “In[n]:=” line. Note that “In[ ]:=” lines use the symbol “:=”, whereas “Out[ ]=” lines use the symbol “=”. Both symbols indicate assignment of a value; the difference between them is discussed in the section of this manual called “More Advanced Uses of Mathematica.” Once Mathematica is finished with your command, it provides you with a new “In[ ]:=” prompt. Leaving Mathematica To exit Mathematica, type Quit in response to an “In[ ]:=” prompt (the capital “Q” is important). In[2]:= Quit \$ Mathematica exits silently, returning you to the UNIX shell. Integer Arithmetic To get Mathematica to do simple arithmetic, simply type the expression you want evaluated. Mathematica understands the following symbols: + − ∗ / ˆ !

add subtract multiply (A blank space can be used instead.) divide. exponentiate. factorial. Below is an example of this kind of interaction with Mathematica:

In[1]:= Out[1]= In[2]:= Out[2]= In[3]:= Out[3]= In[4]:= Out[4]= In[5]:= Out[5]= In[6]:= Out[6]=

3 + 4 7 3 - 4 -1 3 * 4 12 3 4 12 3ˆ4 81 3 ! 6

In general, Mathematica ignores blanks, except when they denote multiplication. 34

Logical Comparison Mathematica will do comparisons on numbers. Comparison expressions involve the following symbols: == != > < >= = 4 Out[10]= False In[11]:= 3 == 4 Out[11]= False In[12]:= 3 ! = 4 Out[12]= True In[13]:= Real Arithmetic The easiest way to get Mathematica to do real arithmetic, is to include a real number (i.e., one with a decimal point) in the expression: In[13]:= 3 * 4.1 Out[13]= 12.3 In[14]:= Built-In Constants, the Function N[ ] Mathematica includes built-in constants such as π and e. In order to get numerical approximations to the values of these constants, you must use the Mathematica function N[ ]. In[15]:= Out[15]= In[16]:= Out[16]= In[17]:=

N[Pi] 3.14159 N[E] 2.71828

35

Note that the names of all Mathematica built-in constants and functions begin with capital letters. The arguments to Mathematica functions are surrounded by “[ ]”. The Mathematica expression N[expr] provides a numerical approximation to the value of expr. N[ ] can also be used with two arguments, as in N[expr, num] where num gives the number of decimal places you want to see in the output. For example: In[18]:= N[E,50] Out[18]= 2.71828182845904523536028747135266249775724709369996 Exact Arithmetic Mathematica does arithmetic on rational numbers, leaving the answer in rational form: In[19]:= 1/3 + 2/7 13 Out[19]= -21 In general, Mathematica will return the exact value of an expression (as opposed to the numerical approximation) unless you explicitly request numerical evaluation. In[20]:= Out[20]= In[21]:= Out[21]=

Sqrt[5] Sqrt[5] Sqrt[5.] 2.23607

In the above, we have used the Mathematica function Sqrt[ ]. Note that, in order to get a numerical approximation to the value of an expression, it is enough to include a number with a decimal point in that expression. Variables In order to re-use the value of an expression, it is necessary to give it a name. This is done by assigning the value of the expression to a variable. In[30]:= Out[30]= In[31]:= Out[31]=

a = 3 + 5 8 a 8

This kind of assignment is done using the symbol “=”. Variable names can be strings of characters; a blank signals the end of a variable name. Thus, the string “xy” means the variable named “xy”, while the string “x y” means to multiply the value of the symbol “x” by the value of the symbol “y”. You can choose any variable name you want, except that you should not pick the same name as any Mathematica built-in constants or functions. 36

Since these all begin with capital letters, choosing variable names that begin with lowercase letters is a good idea. In the above, note that Mathematica evaluated the assignment just like any other expression. The value of the assignment expression is the value assigned to the variable. Once you have assigned a value to a variable, you can use the variable in any expression you type, and Mathematica will substitute the value. In[32]:= a + 16 Out[32]= 24 It is important not to confuse “=”, which represents assignment, and “==”, which represents the relationship of being equal. In[34]:= 7 == a Out[34]= False In[35]:= 7 = a Set::setraw: Cannot assign to raw object 7. Out[35]= 8 In In[34], the expression asks whether 7 is equal to a. Mathematica correctly responds False. In In[35], the expression attempts to assign the value of a to the constant 7. Since this does not make sense, Mathematica complains. The error message comes from the Mathematica function Set[ ], which is the assignment function. To remove a variable definition, so that the variable name becomes an undefined symbol again, type variablename = . In[36]:= Out[36]= In[37]:= Out[37]= In[38]:= In[38]:= Out[39]=

a = 5 5 a 5 a = . a a

Note that, when the value is removed from a variable in this manner, Mathematica returns the variable name unchanged when it is used in any expression thereafter. As explained below, Mathematica considers any variable name without a value, to be an algebraic symbol. Symbolic Mathematics If you use a symbol other than a built-in constant or function, or a variable to which you have given a value, Mathematica considers it to be an algebraic symbol. In[40]:= x + 7 Out[40]= 7 + x Mathematica can manipulate symbolic algebraic expressions. In the process of evaluating an expression, it will often rearrange terms and simplify. 37

In[41]:= 3 x - x + 2 Out[41]= 2 + 2 x Symbolic expressions can be assigned to variables, just like numeric expressions. In[42]:= y = (b + c) Out[42]= b + c Mathematica provides built-in functions to expand and factor expressions. In[43]:= Expand[yˆ2] 2 2 Out[43]= b + 2 b c + c In[44]:= Factor[%] 2 Out[44]= (b + c) In the above, we have used the symbol “%”, which is a short form for the immediately previous Out[ ] value. Lists Mathematica frequently uses lists of objects; many Mathematica functions expect lists as arguments, or produce lists as output. A list can be created by enclosing a series of objects, separated by commas, in brace brackets {}. In[45]:= Out[45]= In[46]:= Out[46]=

l = {1,2,3,4,5} {1, 2, 3, 4, 5} l {1, 2, 3, 4, 5}

The empty list is denoted by {}. You can get at a single element of a list by typing name of list[[index]] where index is some expression, evaluating to an integer, that gives the position of the element in the list. In[47]:= l[[1]] Out[47]= 1 The Mathematica function Length[ ] gives the number of elements in the list. In[48]:= Length[l] Out[48]= 5 Many Mathematica operations can be applied to an entire list at a time. In[49]:= Out[49]= In[50]:= Out[50]=

l + 6.7 {7.7, 8.7, 9.7, 10.7, 11.7} lˆ6 {1, 64, 729, 4096, 15625} 38

Mathematica provides functions to manipulate lists, such as Append[ ], which adds an element to the end of a list, and Prepend[ ], which adds an element at the beginning of a list. Append[ ] requires two arguments; the name of the list, and the element to be appended to that list. Prepend[ ] similarly requires two arguments; the name of the list, and the element to be prepended to that list. Both functions return the new list that results from the operation. In[51]:= Out[51]= In[52]:= Out[52]=

Append[l,10] {1, 2, 3, 4, 5, 10} Prepend[l,11] {11, 1, 2, 3, 4, 5}

The function Take[ ] returns a sequence of elements from either the beginning or the end of a list. It requires two arguments; the name of the list, and the number of elements to return. If the number of elements is positive, the elements are taken from the beginning of the list. If the number of elements is negative, the elements are taken from the end of the list. In[53]:= Out[53]= In[54]:= Out[54]= In[55]:= Out[55]=

l={1,2,3,4,5} {1, 2, 3, 4, 5} Take[l,2] {1, 2} Take[l,-2] {4, 5}

The function Drop[ ] returns a list minus a sequence of elements from either the beginning or the end of that list. It requires two arguments; the name of the list, and the number of elements to delete. If the number of elements is positive, the elements are dropped from the beginning of the list. If the number of elements is negative, the elements are dropped from the end of the list. In[56]:= Out[56]= In[57]:= Out[58]=

Drop[l,1] {2, 3, 4, 5} Drop[l,-1] {1, 2, 3, 4}

Mathematica provides the Table[ ] function, which generates a list of elements. Table[ ] takes two arguments. The first argument is an expression, the second is an iterator. The expression is evaluated repeatedly, thus generating elements of the list; the number of evaluations is specified by the iterator. The iterator is itself a list. There are four forms for an iterator:

39

{max}, which indicates that the expression is to be evaluated max times. {i, max}, which indicates that the expression is to be evaluated for successive values of the variable i from 1 to max. {i, min, max}, which indicates that the expression is to be evaluated for successive values of the variable i from min to max. {i, min, max, step}, which indicates that the expression is to be evaluated for successive values of the variable i from min to max in steps of step. Below are some examples of the use of Table[ ]: In[59]:= Out[59]= In[60]:= Out[60]=

Table[Prime[i],{i,1,15}] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47} Table[{i,iˆ4},{i,3}] {{1, 1}, {2, 16}, {3, 81}}

The concept of iterator is an important one in Mathematica. Other Mathematica functions which use iterators are Sum[ ], Product[ ], and Do[ ]. Plotting Mathematica includes a powerful and general graphics package. The facilities that you will be interested in immediately are the ones that plot functions in two and three dimensions. The command to generate a two-dimensional plot is Plot[function,range], where function is a function of one variable, and range is a list that gives the range for that variable. For example, Plot[Sin[x],{x,0,2 Pi}] plots the values of sin(x) where x ranges from 0 to 2π. The output from a Plot[ ] is -Graphics-; also a new window will appear on your screen, with the plot inside it. This window will have a menu bar, with a File selection on it. To get rid of the graphics window, click button1 over the File selection. This causes a menu to pop up, containing a Quit selection. Click button1 over the Quit selection to cause the window to disappear. To plot more than one function in the same window, give a list of functions instead of a single function as the first argument to Plot[ ]. For example, Plot[{Sin[x],Cos[x]},{x,0,2 Pi}] plots the values of sin(x) and cos(x) where x ranges from 0 to 2π. The command to generate a three-dimensional plot is Plot3D[function,range1,range2], where function is a previously defined function of two variables, range1 is a list that gives the range for the first variable, and range2 is a list that gives the range for the second variable. For example, 40

Plot[Sin[x y],{x,0,3},{y,0,3}] plots sin(xy) for x ranging from 0 to 3 and y ranging from 0 to 3. You can give a list of functions to Plot3D[ ] if you want to plot more than one surface in the same picture. Mathematica provides many options to control the appearance of plots. These options, if present, form extra arguments to the Plot[ ] or Plot3D[ ] command. An option is written in the form option name → value. For example, Plot[Sin[x],{x,0,2 Pi},PlotLabel →"Plot of Sin(x)"] plots sin(x) in the range of x from 0 to 2π, and adds the specified label to the picture. You can send the graphics output from a plot command to the math lab printer. The command to do this is PSPrint[Out[n ]] where Out[n] generated the picture. The printer will render the plot in shades of gray; keep this in mind if you select colours for your plot. On-Line Documentation for Mathematica Functions To see documentation on a Mathematica function, type ?functionname: In[61]:= ?Dot a.b.c or Dot[a, b, c] gives products of vectors, matrices and tensors. The output from this command is called a usage message. If you don’t know the exact name of a function, you can use a wildcard character to get the names of all functions matching a pattern: In[62]:= ?Fac* FaceForm FaceGrids Factor FactorComplete

Factorial Factorial2 FactorInteger FactorList

FactorSquareFree FactorSquareFreeList FactorTerms FactorTermsList

Loading External Files Mathematica provides many built-in functions; these are available to you when you start Mathematica. There are also many packages of functions written to supplement these built-in functions; some of these are provided in the Mathematica directory, and others are provided in the directories assigned to lab courses. In either case, to get access to functions in a package, use the command {c, > {d, In[66]:= In[66]:=

l={a,b,c,d} {a, b, c, d} p=Permutations[l] {{a, b, c, d}, {a, b, d, c}, {a, c, b, d}, {a, c, d, b}, d, b, c}, {a, d, c, b}, {b, a, c, d}, {b, a, d, c}, {b, c, c, d, a}, {b, d, a, c}, {b, d, c, a}, {c, a, b, d}, {c, a, b, a, d}, {c, b, d, a}, {c, d, a, b}, {c, d, b, a}, {d, a, a, c, b}, {d, b, a, c}, {d, b, c, a}, {d, c, a, b}, {d, c, p=Permutations[l];

a, d, b, b,

d}, b}, c}, a}}

Sometimes, a Mathematica command can take a long time to complete. If you don’t want to wait for the command to finish, or if you suspect there is a problem with the command (such as an infinite loop), you can abort the computation by typing “Ctrl-c”. Mathematica will give you a new prompt, Interrupt>. Type “a” in response to this prompt, and the command will be terminated. In[67]:= l={a,b,c,d,e,f,g} Out[67]= {a, b, c, d, e, f, g} In[68]:= Permutations[l] ˆC Interrupt>a In[32]:= Using Mathematica with emacs Mathematica itself does not provide a very convenient user interface; in order to change a command slightly and rerun it (for example, to execute a function with different arguments), you must retype the entire command. Also, there is no way to print a Mathematica session, or to save it so that you can continue it at a later date. emacs in the math lab provides a math mode which allows you to use the emacs editor to enter and edit commands, then send them to Mathematica for execution. emacs math mode also allows you to save your Mathematica session as a file. This file can be printed, and can be used to continue your Mathematica session later. In order to run Mathematica under emacs, first start an emacs session on a file, then type the emacs command M-x start-math, which starts up a concurrent Mathematica session. When the Mathematica session is ready, the message “mathematica started - ...” will appear in the echo area. The usual Mathematica prompt will not appear in your window. Under emacs math mode, you divide your text file into regions called cells. Each new cell is delimited by a line of minus signs on the top, and another line of minus signs on the bottom. In order to create a new cell, press the “Tab” 42

52

PART TWO: ORIENTATION SESSIONS

labelled with a synonym, which gives a combination of keystrokes to accomplish the same thing. Hold down the “Alt” key and press the “F7” key. Move the window as before. Type “Alt F8”. Resize the window as before. Type “Alt F9”. Restore the window as before. Type “Alt F10”. Restore the window as before. Type “Alt F3”. Type “Alt F4”. Scrollbars Bring up another new window. Give this window focus, then type cat .Xdefaults. Notice that the output scrolls off the top of the screen. Move the mouse point into the scrollbar area on the right side of the window. Click button3 a few times. Notice what happens to the contents of the window. Now click button1 a few times. Notice what happens to the contents of the window. Ending a Session Give focus to the first window, the one titled with the name of the math lab server. Type exit, then press “Enter”. Notice that all the windows on the screen are closed, then a new welcome window appears.

55

that are running under the current shell. To get a listing of all the processes that you are running, type ps -u yourloginname. Notice that this listing is much longer than the earlier ones. In the new window, type math. This will start up Mathematica. In the first window, type ps -u yourloginname, and determine the process id of the Mathematica process. Type kill mathprocessid, and notice what happens to the Mathematica process in the second window. Printing Commands In order to see the status of the math lab printer queues, type lpstat. The queues that you are interested in are asc, for text files, and ps, for graphics files. If you are connected to titania, each of these queues will appear twice. The queues should all show a status of READY; if any of the queues shows up as DOWN, get in touch with the system administrator. To print “testfile”, type lpr -h -Pasc testfile. Now type lpstat to see that your print job (and those of other people) are now on the asc print queue. Notice that your job has a number; you can use this number to cancel your job, by typing cancel jobnumber. More Information Type man ps. Notice that the information is automatically presented to you using more. Manual information is available for all UNIX commands.

59

60

Leaving emacs Type C-x C-c. The emacs window will disappear, and you will get a shell prompt in your original window. Basic Editing ¿From the UNIX shell, type emacs testfile again. This time, when emacs has finished loading, the text area contains the text you entered previously into “testfile”. Click button1 of the mouse over various areas of this text, to see how the cursor changes position. With the cursor inside a text line, type C-b. Notice what happens to the cursor position. Type ←. Notice what happens to the cursor position. Try the other cursor movement commands, C-f, →, C-p, ↑,C-n, ↓, C-a, C-e. Type some characters with the cursor inside a text line. Notice how the new characters are inserted, and how the rest of the line moves to make space for the new characters. Use the backspace or delete key to delete characters. Notice how the characters are deleted, and the rest of the line moves in to fill the vacated space. Move the cursor down until the text scrolls off the top of the text area. Enter a few lines of text. Now try the window movement commands, C-v, “Page Up”, M-v, “Page Down”. When you reach the end of your edit buffer, emacs will beep at you, and the echo area will contain the message “Beginning of buffer” or “End of buffer”. Move the cursor to the beginning of a text line. Type C-k. The line will disappear. Move the cursor to elsewhere in the text area, and type C-y. Notice how the line is inserted. Kill the line again, using C-k, then type C-x u to undo the change. The message in the echo area is “Undo!”. The Mark Enter several lines of text. Move the cursor to the end of the last line you just entered, and type C-space. The echo area will contain the message “Mark set”. Now move the cursor to the beginning of the first line you just entered, and type C-w. Notice that the entire region of text disappears. Move the cursor to another area, and type C-y. Notice that all the text in the region is inserted. Recovery From Crash In order to simulate a crash, type “Alt-F4” to kill the emacs window. From the UNIX shell type ls to see that there is a file in your directory called “#testfile#”. Type emacs. When emacs is finished loading, type M-x recover-file, and respond to the questions that are asked in the echo area. emacs will load the auto-saved file, and you can continue editing.

61

Lab 4 – Introduction to Mathematica Starting Mathematica This session assumes that you have completed Labs 1 and 2, and are thus familiar with X windows and basic UNIX concepts. Log on to a math lab server; when your shell is ready, type math in response to the \$ prompt. Mathematica will start up, and you will see the following on your screen: \$ math Mathematica 2.2 for IBM RISC System 6000 Copyright 1988-93 Wolfram Research, Inc. -- Motif graphics initialized -In[1]:= Notice the message “--Motif graphics initialized--”. This indicates that your DISPLAY environment variable is set, and so Mathematica knows where to send graphics output. Notice the line “In[1]:=”. This is the Mathematica prompt; the cursor is positioned immediately after this prompt. This indicates that Mathematica is ready for you to Interaction with Mathematica Type an arithmetic expression for Mathematica to evaluate, for example, 17 + 22. Mathematica will respond with the answer, prefixed by the text “Out[1]=”. The above interaction should look like this: In[1]:= 17 + 22 Out[1]= 39 In general, the result of evaluating an expression in In[n ] is given in Out[n]. Input a few more arithmetic expressions; use the symbols “+”, “−”, “∗”, “/”, “ˆ”, and “!” for add, subtract, multiply, divide, exponentiate, and factorial, respectively. Leaving Mathematica To exit Mathematica, type Quit (the capital “Q” is important.) You will receive the \$ prompt again, indicating that you are back in the UNIX shell. In[2]:= Quit \$ Logical Comparisons Start Mathematica again. Type some logical comparison expressions for Mathematica to evaluate, using the symbols “==”, “! =”, “>”, “=”, and “ Sqrt[10], Sqrt[11], 2 Sqrt[3], Sqrt[13], Sqrt[14], Sqrt[15]} The Sum[ ] function takes two arguments, an expression to be summed, and an iterator which specifies how many of the expressions are to be summed. Find the sum of the first 100 integers: In[32]:= Sum[i,{i,100}] Out[32]= 5050 Matrices Specify a matrix as a list of lists, each sublist representing one row of the matrix. In[33]:= mat={{1,2,3,4,5},{a,b,c,d,e},{x,1,y,2,z}} Out[33]= {{1, 2, 3, 4, 5}, {a, b, c, d, e}, {x, 1, b + c, 2, z}} Notice that the matrix just looks like an ordinary list. Ask Mathematica to output the list in a form that looks like a matrix: In[34]:= MatrixForm[mat] Out[34]\\MatrixForm= 1 a x

2 b 1

3 c b + c 65

4 d 2

5 e z

Try some of the Mathematica functions for matrix manipulation, such as ., Det[ ], Inverse[ ], Transpose[ ]. In[37]:= Out[37]= In[38]:= Out[38]= > > > >

Transpose[mat] {{1, a, x}, {2, b, 1}, {3, c, b + c}, {4, d, 2}, {5, e, z}} mat . % {{55, a + 2 b + 3 c + 4 d + 5 e, 10 + 3 (b + c) + x + 5 z}, 2 2 2 2 2 {a + 2 b + 3 c + 4 d + 5 e, a + b + c + d + e , b + c (b + c) + 2 d + a x + e z}, {10 + 3 (b + c) + x + 5 z, b + c (b + c) + 2 d + a x + e z, 2 2 2 5 + (b + c) + x + z }}

Plotting Try generating a simple two dimensional plot. In[57]:= Plot[xˆ2,{x,-10,10}] Out[57]= -GraphicsAfter the “-Graphics-” line appears in your Mathematica session, an outline of a window will appear on your screen. Position the outline using the mouse, then click button1. The new window will contain the plot you requested. The title of the window will be “Mathematica Graphics: Out[n]”, where Out[n] is the “-Graphics-” line mentioned above. At the top of the graphics window is a menu bar, containing the selections File and View. Click button1 over the File selection. A menu will pop up, containing a Quit selection. Click button1 over Quit, and the graphics window will disappear. Try adding an option to your plot command: In[59]:= Plot[xˆ2,{x,-10,10},Axes->None] Out[59]= -GraphicsOn-Line Documentation Try using the “?” operator with the names of some of the functions we have seen so far. In[60]:= ?Sqrt Sqrt[z] gives the square root of z. In[60]:= ?Prepend Prepend[expr, elem] gives expr with elem prepended. Loading External Files Try loading a file from one of the math lab course directories: In[1]:= ?Graph 66

Information::notfound: Symbol Graph not found. In[1]:= 2,2->1,3->4,4->5,5->3}]] S[{1 → 2, 2 → 1, 3 → 5, 4 → 3, 5 → 4}]

More generally, if p and q are lists of permutations then p.q will return a list consisting of the product of each permutation in p with each permutation in q. Similarly Inverse[p] will return a list consisting of the inverses of the permutations in p. For example, In[6]:= In[7]:= In[8]:= Out[8]= In[9]:= Out[9]=

p={C[{1,2,3,4}],C[{1,2,3}]}; q={C[{1,2}],C[{1,3},{2,4}]}; p.q {(3 2), (3 4 2), (4 3 2 1), (4 2 1)} Inverse[p] {(4 3 2 1), (3 2 1)}

Given a list p of permutations, Subgroup[p] returns a list consisting of the permutations in the subgroup of Σn generated by p, where n is the largest integer appearing among the elements in p. p can be given in any of the three notations, but the output will be in cycle notation. However, Subgroup[p,M] or Subgroup[p,S] can be used to get mapping or substitution notation output. Order[X] returns the number of elements in the list X. LeftCosets[g,h] and RightCosets[g,h] return the left cosets and right cosets of the subgroup H generated by h within the subgroup G generated by g. The first coset listed is always H itself. For example, In[10]:= g = {C[{1,2}], C[{1,2,3}] In[11]:= h = {C[{1,2}]} In[12]:= LeftCosets[g,h] 104

Out[12]= {{(1), (2 1)}, {(3 2), (2 3 1)}, {(3 2 1), (3 1)}} In[13]:= RightCosets[g,h] Out[13]= {{(1), (2 1)}, {(3 2), (3 2 1)}, {(2 3 1), (3 1)}} If you only want a representative from each coset you can use LeftCosetReps[ ] or RightCosetReps[ ]. In[13]:= LeftCosetReps[g,h] Out[13]= {(1), (3 2), (3 2 1)} A list of the elements in a number of the common permutation groups can be obtained with GetGroup[name]. Similarly a list of generators for these groups can be obtained with GetGenerators[name]. Enter ?GetGroup or ?GetGenerators for a list of the groups available this way. In[14]:= GetGroup[D7] Out[14]= {(1), (2 7)(3 6)(4 5), (1 2)(3 7)(4 6), (3 4 5 6 7 1 2), (1 3)(4 7)(5 6), (5 7 2 4 6 1 3), (1 4)(2 3)(5 7), (7 3 6 2 5 1 4), (1 5)(2 4)(6 7), (2 6 3 7 4 1 5), (1 6)(2 5)(3 4), (4 2 7 5 3 1 6), (6 5 4 3 2 1 7), (1 7)(2 6)(3 5)} Several of the following functions return groups constructed from other groups. Some of these functions return a set of generators for the group and others return the complete list of elements in the group. In those cases where the output is a set of generators, the full group list can be obtained by composing with the Subgroup[ ] function. Centre[gen] returns the list of elements in the centre of the subgroup generated by gen. Note that the spelling of Centre[ ] cannot be varied; Center[ ] is a built-in Mathematica function with a different meaning. NormalizerGenerators[g,h] and NormalClosureGenerators[g,h] return a set of generators for, respectively, the normalizer and normal closure of the subgroup generated by h within the subgroup generated by g. NormalizerGenerators[ ] can be abbreviated to NG[ ]. NormalQ[g,h] returns True if the subgroup generated by h is normal in that generated by g and False otherwise. Usage Messages C C[c1,c2,. . .,ck], where each cj is a cycle {cj1 , cj2 , . . . , cjrj }, is the permutation (c11 c12 c1r1 )(c21 c22 c2r2 ) . . . (ck1 ck2 ckrk ). Centre Centre[g] gives the list of elements in the centre of the subgroup generated by the list of permutations g. Dot Dot[p,q], which can also be written as p.q, gives the product of permutations p and q. If p and q are lists of permutations then p.q is the list consisting of the product of each permutation in p with each permutation in q. GetGenerators GetGenerators[name] gives a list of generators for the permutation group name for some of the common permutation groups. 105

GetGroup GetGroup[name] gives a list of elements in the permutation group name for some of the common permutation groups. Inverse Inverse[p] gives the inverse of the permutation p. p can be in either mapping notation or cycle notation. If p is a list of permutations, then Inverse[p] gives the list of inverses of the permutations in p. LeftCosets LeftCosets[g,h], where g and h are lists of permutations, is a list giving the partition of the group generated by g into left cosets of the subgroup generated by h. Cosets are given as lists of group elements. LeftCosetReps LeftCosetsReps[g,h], where g and h are lists of permutations, gives a list of representatives of the left cosets of the subgroup generated by h in the group generated by g. M M[e1,e2,. . .,ek], where e1,e2,. . ., ek are integers, is the permutation i 7→ ei. NormalClosureGenerators NormalClosureGenerators[g,h] or NG[g,h], where g and h are lists of permutations, gives a list of generators for the smallest normal subgroup of the group generated by g which contains the group generated by h. NormalizerGenerators NormalizerGenerators[g,h] or NCG[g,h], where g and h are lists of permutations, gives a list of generators for the normalizer of the subgroup generated by h in the group generated by g. NormalQ NormalQ[g,h] where g and h are lists of permutations, returns True if the subgroup generated by h is normal in the group generated by g. Order Order[G], where G is a group given as a list of its elements, returns the number of elements in G. RightCosets RightCosets[g,h] where g and h are lists of permutations, is a list giving the partition of the group generated by g into right cosets of the subgroup generated by h. Cosets are given as lists of group elements. RightCosetsReps RightCosetsReps[g,h], where g and h are lists of permutations, gives a list of representatives of the right cosets of the subgroup generated by h in the group generated by g. 106

S S[s1,s2,. . .,sk], where s1,s2,. . ., sk are substitutions of the form a → b, is the permutation defined by the substitutions s1,s2,. . ., sk. Subgroup Subgroup[g] where g is a set of permutations, gives the group generated by g. ToCycles ToCycles[p] gives the permutation p in cycle notation. ToMappings ToMapping[p] gives the permutation p in mapping notation. ToSubst ToSubst[p] gives the permutation p in substitution notation. Examples 1. Is the Klein subgroup V4 a normal subgroup of the alternating group A4 ? Solution: In[1]:= g = {C[{1,2,3}], C[{2,3,4}] In[2]:= h = {C[{1,2},{3,4}],C[{1,3},{2,4}]} Then g is a set of generators for the alternating group A4 , and h is a set of generators for the Klein subgroup V4 of order 4. In[3]:= LeftCosets[g,h] Out[3]= {{(1), (2 1)(4 3), (3 1)(4 2), (4 1)(3 2)}, {(3 4 2), (3 2 1), (4 3 1), (2 4 1)}, {(4 3 2), (4 2 1), (2 3 1), (3 4 1)}} In[4]:= RightCosets[g,h] Out[4]= {{(1), (2 1)(4 3), (3 1)(4 2), (4 1)(3 2)}, {(3 4 2), (3 2 1), (4 3 1), (2 4 1)}, {(4 3 2), (4 2 1), (2 3 1), (3 4 1)}} Since we observe that the left and right cosets are equal, we conclude that V4 is a normal subgroup of A4 . To check our answer: In[5]:= NormalQ[g,h] Out[5]= True Exercises 1. Check whether the following set of permutations form permutation groups. a) {M [2, 3, 1, 5, 4], M [4, 1, 2, 5, 3], M [1, 3, 5, 2, 4], M [2, 1, 3, 4, 5], M [1, 2, 3, 4, 5]} b) {M [1, 2, 3, 4], M [2, 1, 4, 3], M [3, 4, 1, 2], M [4, 3, 2, 1]} c) {M [1, 2, 3, 4, 5], M [1, 5, 4, 3, 2], M [2, 1, 5, 4, 3], M [2, 3, 4, 5, 1], M [3, 2, 1, 5, 4], M [3, 4, 5, 1, 2], M [4, 3, 2, 1, 5], M [4, 5, 1, 2, 3], M [5, 1, 2, 3, 4], M [5, 4, 3, 2, 1]} 107

d) {M [1, 2, 3, 4, 5], M [1, 3, 5, 4, 2], M [1, 5, 2, 4, 3], M [4, 3, 5, 1, 2], M [4, 5, 2, 1, 3]} e) {M [1, 2, 3, 4, 5], M [1, 3, 5, 4, 2], M [1, 5, 2, 4, 3], M [4, 2, 3, 1, 5], M [4, 3, 5, 1, 2], M [4, 5, 2, 1, 3]} 2.

a) Find all permutation groups of degree 4 generated by two elements. b) Find all permutation groups of degree 5 generated by two elements. Exclude degenerate cases; that is, cases where one permutation is a power of the other, or where both fix one or more numbers. You should find 5 essentially different permutation groups.

3. Pick random pairs of permutations of degree 5 and determine which subgroup they generate. Repeat ten times or so and do the same for degrees 6 and 7. You will find that the different subgroups which occur have different orders, so you need only determine the order of the subgroup. You can do this with Order[Subgroup[gen]] and thus avoid producing screenfuls of output. 4. The transpositions {(1 2), (3 4), . . . , (1 n)} generate Σn . Can one generate Σn with two permutations? Try to find two permutations which generate Σ4 , then Σ5 and Σ6 . Make a conjecture for Σn for arbitrary n. Can you prove your conjecture? ∗

5. ( /n ) forms a group under multiplication mod n. Calculate ( /n ) for n = 6, 7, and 8. Experiment with larger values of n. Formulate a conjecture about its structure when n is prime. 6. Construct subgroups of Σ5 of as many different orders as possible. Is there one for every divisor of 5! = 120?

108

Normal Subgroups Prerequisites Permutation Groups Input Files /home/courses/B31/permutations.m Mathematical Discussion For elements a and b in a group G, the conjugate of b by a is defined as aba−1 . A subgroup H of G is normal if and only if the conjugate of any element of H by any element of G lies in H. To check if this is true, it suffices to pick a generating set for each group and check that the conjugate of each element of the generating set for H by any element of the generating set for G lies in H. Mathematica Functions Conjugate[a,b] returns the conjugate of b by a. In[1]:= Conjugate[C[{1,2,3,4,5}],C[{1,2}]] Out[1]= (1 5) If X is a list of permutations, then Conjugate[a,X] returns the list of conjugates of the elements of X by a. Usage Messages Conjugate Conjugate[a,b] gives the conjugate aba−1 of permutations a and b. Examples 1. Is V4 a normal subgroup of Σ5 ? Solution: In[1]:= V4={C[{1}], C[{1,2},{3,4}], C[{1,3},{2,4}], C[{1,4},{2,3}]}; In[2]:= a = C[{1,2,3,4,5}]; In[3]:= b = C[{1,2}]; Then a and b generate Σ5 . In[4]:= Conjugate[a,V4] Out[4]= {(1), (1 5)(2 3), (1 3)(2 5), (1 2)(3 5)} We see that the conjugates of V4 by a contain elements which are not in V4 , so V4 is not a normal subgroup of Σ5 . 2. Is the Frobenious group F20 a normal subgroup of Σ5 ? 109

Solution: In[1]:= h={C[{1,2,3,4,5}], C[{2,3,5,4}]}; Then h generates the Frobenious group F20 . In[2]:= F20=Subgroup[h] Out[2]= {(1), (5 4 2 3), (5 3 2 4), (2 5)(3 4), (1 2)(3 5), (3 4 5 1 2), (4 3 1 2), (5 4 1 2), (4 2 1 3), (1 3)(4 5), (5 2 4 1 3), (2 5 1 3), (5 2 1 4), (3 5 1 4), (1 4)(2 3), (2 5 3 1 4), (4 3 2 1 5), (3 4 1 5), (2 3 1 5), (1 5)(2 4)} In[3]:= a = C[{1,2,3,4,5}]; In[4]:= b = C[{1,2}]; Then a and b generate Σ5 . To check whether F20 is normal in Σ5 , you can conjugate h by a and by b, and see whether the resulting sets lie in F20 . In[4]:= Out[4]= In[5]:= Out[5]=

Conjugate[a,h] {(2 3 4 5 1)(2 4 3 1)} SubsetQ[F20,Conjugate[a,h]] False

Since the conjugates by a are not contained within F20 , we conclude that F20 is not a normal subgroup of Σ5 , and there is no need to test the conjugates by b. Exercises 1. Find all normal subgroups of S4 . 2. Find all normal subgroups of A5 .

110

Quotient Groups Prerequisites Permutation Groups Input Files /home/courses/B31/permutations.m Mathematical Discussion If H is a normal subgroup of G, then one can form a quotient group G/H whose elements are the left cosets of H in G. Since H is normal in G, this is equivalent to using right cosets. In G/H, the product of cosets S and T is the coset containing st, where s is any element in S and t is any element in t. Since H is normal in G, the resulting coset will be independent of the choice of representatives s and t which were chosen. As an alternative to using representatives, one could instead form the set ST , which would be the complete list of elements in the product coset. Examples 1. Let G be the group generated by In[1]:= g={C[{1,2}], C[{1,2,3,4}]}; and let H be the group generated by In[2]:= h = {C[{1,2},{3,4}],C[{1,3},{2,4}]}; Then G = S4 and H = V4 . In[3]:= Out[3]= In[4]:= Out[4]=

NormalQ[g,h] True Q=LeftCosets[g,h] {{(1), (2 1)(4 3), (3 1)(4 2), (4 1)(3 2)}, {(4 3), (2 1), (3 2 4 1), (4 2 3 1)}, {(3 2), (2 4 3 1), (3 4 2 1), (4 1)}, {(3 4 2), (2 4 1), (3 2 1), (4 3 1)}, {(4 3 2), (2 3 1), (3 4 1), (4 2 1)}, {(4 2), (2 3 4 1), (3 1), (4 3 2 1)}}

Q has 6 elements. To multiply the second by the third: In[5]:= Q[[2]].Q[[3]] Out[5]= {(4 3 1)(3 2 1)(3 4 2), (2 4 1)} We recognize the product as Q[[4]]. Q[[2]] contains only 2-cycles so it should have order 2. To verify this: In[6]:= Q[[2]].Q[[2]] 111

Out[6]= {(1), (2 1)(4 3), (3 1)(4 2), (4 1)(3 2)} which is H, the identity element of Q. Similarly Q[[5]] has only 3-cycles so it should have order 3. In[7]:= Q[[5]].Q[[5]].Q[[5]] Out[7]= {(1), (2 1)(4 3), (3 1)(4 2), (4 1)(3 2)} verifies that it does. Let x be (1 2) and let y be (1 2 3). Then xy = y 2 x. Since x ∈ Q[[2]] and x ∈ Q[[5]] we would expect these cosets to satisfy the same relationship. In[8]:= Out[8]= In[9]:= Out[9]=

Q[[2]].Q[[5]] {(3 1), (4 2), (2 3 4 1), (4 3 2 1)} Q[[5]].Q[[5]].Q[[2]] {(3 1), (4 2), (2 3 4 1), (4 3 2 1)}

{Q[[2]], Q[[5]]} generates Q since: Q[[5]].Q[[5]] = Q[[4]]; Q[[2]].Q[[5]] = Q[[6]]; Q[[5]].Q[[2]] = Q[[3]]. If we let K be the subgroup of G generated by x and y then K ∼ = Σ3 and the canonical ∼ ∼ map G → Q maps K isomorphically onto Q. So Q = K = Σ3 . Exercises 1. Let G be the permutation group generated by {(1 2 3)(1 4)(2 5)(3 6), (1 5 2 4)(3 6)}. G has order 72. Let H be the subgroup of order 9 generated by h = {(1 2 3), (5 6 4)}. H is a normal subgroup of G. What is the quotient group G/H? Let K be the subgroup generated by {(1 4)(2 5)(3 6), (1 5 2 4)(3 6)}. Verify that, under the canonical map G → G/H, K is mapped isomorphically onto G/H.

112

Sylow subgroups Prerequisites Permutations Groups Normal Subgroups Input Files /home/courses/B31/permutationgroups.m Mathematical Discussion Let G be a group and let H ⊂ G be a subgroup. Given x ∈ G, the set xHx−1 forms a group and is called a conjugate subgroup to H. H is a normal subgroup of G if and only if the only subgroup of G conjugate to H is H itself. Notice that if K = xHx−1 then H = x−1 Kx so that K is a conjugate subgroup to H if and only if H is a conjugate subgroup to K. A conjugate subgroup of H has the same order as H. Let p be a prime and let pn be the largest power of p dividing the order of G. A subgroup of G of order pn is called a Sylow p-subgroup of G. One part of the Sylow Theorem states that the number of Sylow p-subgroups of G is congruent to 1 modulo p so that in particular there is always at least one Sylow p-subgroup for each prime p dividing the order of G. A conjugate subgroup of a Sylow p-subgroup is clearly also a Sylow psubgroup. The second part of the Sylow Theorem says that, conversely, any two Sylow p-subgroups of G are conjugate to each other. Mathematica Functions Conjugates[g,h] returns the number of subgroups of the group generated by g which are conjugate to the subgroup generated by h. Thus Subgroup[h] is normal in Subgroup[g] if and only if Conjugates[g,h] equals 1. Usage Messages Conjugates Conjugates[g,h] is the number of subgroups of the group generated by the list of permutations g which are conjugate to the subgroup generated by the list of permutations h. Exercises 1. The subgroup generated by {(1 2 3 4), (1 3)} is isomorphic to D4 and is a Sylow 2-subgroup of Σ5 . How many Sylow 2-subgroups does Σ5 have? 2. Find a Sylow 2-subgroup of Σ6 and find one for Σ8 . How many Sylow 2-subgroups does Σ8 have?

113

Linear Groups Input Files /home/courses/B31/lineargroups.m Mathematical Discussion For any prime p, the integers modulo p form a field p . Given a field F , the collection of invertible n×n matrices with coefficients in F forms a group under matrix multiplication. This group is known as the nth general linear group of F , denoted Gln (F ). Any subgroup of Gln (F ) is called a linear group. Mathematica Functions To do arithmetic in the integers modulo n, /n , use the built-in function Mod[ ]. In[1]:= Out[1]= In[2]:= Out[2]= In[3]:= Out[3]=

Mod[26+87,13] 9 Mod[21*86,17] 4 Mod[2^12,7] 1

Computing powers modulo n can be done more efficiently with the function PowerMod[ ]. In[4]:= PowerMod[2,12,7] Out[4]= 1 The standard Mathematica notation for a matrix is a list of lists, but in this lab, matrices are written in Mathematica as lists of lists within the header L[ ]. Output appears in the standard mathematical notation for a matrix; i.e., as a rectangular array. After a value p is specified for the variable \$P rime, Mathematica will perform matrix operations modulo p, provided they are given using the header L[ ] as described above. In[5]:= In[6]:= In[7]:= In[8]:=

\$Prime=7; m1=L[{{1,2},{3,4}}]; m2=L[{{6,3},{2,5}}]; m1.m2 3 6 Out[8]= 5 1 In[9]:= \$Prime=11; In[10]:= m1.m2 10 2 Out[10]= 4 7 In[11]:= Inverse[m1] 114

9 1 7 5 In[12]:= Det[m2] Out[12]= 2 Out[11]=

The function ToL[ ] surrounds a list or list of lists by L[ ] and reduces its entries modulo \$P rime. Usage Messages L L[c1,c2,. . .,ck], where each cj is a list {cj1 , cj2 , . . . , cjrj }, is the matrix whose rows are {cj1 , cj2 , . . . , cjrj }. Matrix operations performed on matrices in this form will be reduced modulo \$P rime. ToL ToL[x], where x is a list or a list of lists, returns L[x] with its entries reduced modulo \$P rime. Examples 1. Does the set of permutations {M [2, 3, 1, 5, 4], M [4, 1, 2, 5, 3], M [1, 3, 5, 2, 4], M [2, 1, 3, 4, 5], M [1, 2, 3, 4, 5]} form a permutation group? Solution: In[1]:= A = {M[2,3,1,5,4],M[4,1,2,5,3],M[1,3,5,2,4],M[2,1,3,4,5], M[1,2,3,4,5]} In[2]:= Inverse[A] Out[2]= {M [3, 1, 2, 5, 4], M [2, 3, 5, 1, 4], M [1, 4, 2, 5, 3], M [2, 1, 3, 4, 5], M [1, 2, 3, 4, 5]} Since M [3, 1, 2, 5, 4], the inverse of M [2, 3, 1, 5, 4], is not in the set A, we conclude that A is not a group. 2. Does the set of matrices {L[{{1, 1, }, {1, 2}}], L[{{1, 0}, {0, 1}}]} form a linear group over 7 ? Solution: In[1]:= In[2]:= In[3]:=

\$Prime=7; B = {L[{{1,1,},{1,2}}],L[{{2,3,},{4,1}}],L[{{1,0,},{0,1}}]}; Inverse[B]   1 1 2 3 1 0 Out[3]= , , 1 2 4 1 0 1 so B is closed under taking inverses. To check if B is closed under products: In[4]:= B.B 115

Out[4]=



1 0

0, , 1

1 1, , 1 2

2 5

2, , 6

2 3

3, , 5

2 3, , 4 1

5 5

1, , 6

6 3

4 5



The list of products contains elements which are not in B, so B is not a group. Exercises 1. Check whether the following set of matrices form linear groups. a) {L[{{1, 0}, {1, 1}}], L[{{1, 0}, {2, 1}}], L[{{1, 1}, {1, 2}}], L[{{2, 1}, {1, 1}}], L[{{0, 2}, {1, 1}}], L[{{0, 2}, {1, 2}}], L[{{1, 2}, {1, 0}}], L[{{1, 2}, {2, 2}}], L[{{2, 1}, {0, 2}}], L[{{2, 2}, {1, 0}}], L[{{2, 2}, {2, 1}}], L[{{0, 1}, {2, 1}}], L[{{0, 2}, {1, 0}}], L[{{1, 1}, {2, 0}}], L[{{2, 0}, {1, 2}}], L[{{2, 0}, {2, 2}}], L[{{2, 2}, {0, 2}}], L[{{1, 0}, {0, 1}}], L[{{0, 1}, {2, 0}}], L[{{1, 1}, {0, 1}}], L[{{0, 1}, {2, 2}}], L[{{1, 2}, {0, 1}}], L[{{2, 0}, {0, 2}}], L[{{2, 1}, {2, 0}}]} in Gl2 ( 3 ). b) {L[{{0, 4}, {1, 0}}], L[{{3, 0}, {0, 2}}], L[{{0, 2}, {2, 0}}], L[{{0, 3}, {3, 0}}], L[{{4, 0}, {0, 4}}], L[{{1, 0}, {0, 1}}], L[{{2, 1}, {2, 0}}]} in Gl2 ( 5 ). 2. Find an element of order 3 in SL2 ( 3. Suppose r is an element of

5 ).

Find a subgroup of order 24 in SL2 (

5 ).

which  is not  a square. Let G(p) be the set of all a b matrices in GL2 ( p ) of the form with a, b ∈ p . Prove that G(p) is a br a subgroup of GL2 ( p ). What is its order? Compute G(p) for p = 3, 5. Make a conjecture about its structure in general. p

116

Group Actions Prerequisites Permutation Groups Linear Groups Input Files /home/courses/B31/lineargroups.m Mathematical Discussion An action of a group G on a set X consists of an operation which assigns to each pair of elements g ∈ G, x ∈ X an element g · x belonging to X in such a way that the following conditions are satisfied: (1) g · (h · x) = (gh) · x ∀g ∈ G, h ∈ G, x ∈ X (2) e · x = x ∀x ∈ X, where e is the identity element of G. For example, there is an action of the symmetric group Σn on the set of integers {1, 2, . . . , n}. Another example is the general linear group Gln (F ) which acts on the vectors of dimension n over the field F . The action of any element of G gives a permutation of the set X and the axioms are equivalent to saying that this association of a permutation to the elements of G is a group homomorphism. For x ∈ X, the orbit of x is the set {g · x | g ∈ G} of X, while the stabilizer of x is the subgroup {g ∈ G | g · x = x}. Their orders are related by |orbit(x)| ∗ |stabilizer(x)| = |G|. There is an action of a group on itself given by conjugation: a · b = aba−1 . The orbit of an element under this action is called its conjugacy class. The number of elements in the conjugacy class of a is given by |G|/|N (a)|, where N (a) is P the normalizer of a. A consequence of this is the class formula which states that |G| = |G|/|N (a)|, where the sum is taken over one element from each conjugacy class. There are p + 1 lines through the origin in the plane of 2-dimensional vectors over p , one through each of the points (x, 1) for x = 0, 1, . . . , p−1, plus one through the point (1, 0). We use u/v to denote the line through (u, v) with ∞ denoting the line through (1, 0). The action of Gl2 ( p ) on the plane induces an action on this set of lines. The action of any element of Gl2 ( p ) gives a permutation of the p + 1 lines and thus allows us to associate to it an element of Σp+1 . This association is a group homomorphism from Gl2 ( p ) to Σp+1 . Mathematica Functions If gen is a list of permutations and x is a positive natural number, then Orbit[gen,x] returns the orbit of x under the permutation group generated by gen. Similarly, if gen is a list of invertible n × n matrices and x is an n-dimensional vector then Orbit[gen,x] returns the orbit of x under the linear group generated by gen. 117

In[1]:= Out[1]= In[2]:= In[3]:=

Orbit[{C[{1,2,3}],C[{3,4,5}]},2] {1, 2, 3, 4, 5} \$Prime=5; Orbit[{L[{{1,1},{1,0}}]}, ToL[{2,3}]]  0 0 0 0 1 1 1 1 2 Out[3]= , , , , , , , , , 1 2 3 4 0 1 3 4 0 3 4 4 4 4 , , , , 4 0 1 2 4

2 , 1

2 , 2

2 , 3

3 , 0

3 , 2

3 , 3

Stabilizer[G,x] returns the stabilizer of the index x, where G is the list of elements (not just a generating set) in a permutation group. The same syntax can be used if G is a linear group and x is a vector. In[4]:= G=Subgroup[{C[{1,2,3}],C[{3,4,5}]}]; In[5]:= Stabilizer[G,3] Out[5]= {(1), (4 5 2), (5 4 2), (2 1)(5 4), (2 4 1), (2 5 1), (4 2 1), (4 5 1), (4 1)(5 2), (5 2 1), (5 4 1), (5 1)(4 2)} ConjugacyClass[gen,x] returns the conjugacy class of x in the group generated by gen where either x is a permutation and gen is a list of permutations or else x is an invertible matrix and gen is a list of invertible matrices. For example, SL2 (

5)

is generated by

In[6]:= {gen=L[[{{1,1},{1,0}}], L[[{{1,0},{1,1}}]}; Let In[7]:= m=L[[{{1,1},{1,0}}]; In[8]:=  ConjugacyClass[gen,m] 0 1 0 4 1 1 , , , Out[8]= 1 1 4 1 1 0 3 4 4 1 4 4 , , 0 3 4 2 1 2 For a matrix A in {0, 1, . . . , p, ∞}.

p,

1 4

4 , 0

2 1 , 4 4

2 1

4 , 4

3 1

0 , 3

3 4

0 , 3

3 0

1 , 3

LFT[A] returns a function giving the action of that matrix on

With \$P rime = 5 we get: In[9]:= A=L[[{{1,2},{2,1}}]; In[10]:= f=LFT[A] In[11]:= f[2] Out[11]= Infinity In[12]:= f[Infinity] Out[12]= 3 Using the integers 1, 2, . . . , p, p + 1 to represent the lines through the origin in the plane over p , with p standing for the line “0” and p + 1 standing for the line “∞”, the function LFTPermutation[A] gives the permutation coming from the matrix A. 118

In[13]:= LFTPermutation[A] Out[13]= (2 6 3 5) Usage Messages ConjugacyClass ConjugacyClass[gen,x] returns the conjugacy class of x in the group generated by gen, where either x is a permutation and gen is a list of permutations or else x is an invertible matrix and gen is a list of invertible matrices. LFT LFT[A], where A ∈ p and P rime = p, is a function giving the action of A on the lines {0, 1, . . . , p, ∞} through the origin in the plane over p . LFTPermutation LFTPermutation[A] gives the permutation in Σp+1 coming from the matrix A ∈ where \$P rime = p.

p,

Orbit Orbit[gen,x] gives the orbit of x under the action of the group generated by gen, where either gen is a list of permutations and x is a positive natural number, or else gen is a list of invertible n × n matrices and n is an n-dimensional vector. Stabilizer Stabilizer[G, x] is the stabilizer of x in G, where G is the list of elements in either a permutation group or a linear group, and x is a positive integer or a vector respectively. Exercises 1. Verify the class formula for the action of Sl2 ( 2. Determine the conjugacy classes in Sl2 ( groups other than its centre?

2 5) .

5)

on (

2 5) .

Does Sl2 (

5)

have any normal sub-

3. Are two elements in F20 which are conjugate in Σ5 also conjugate in F20 itself? 4. Let G be Sl2 ( m1 =



5 ).

1 1 0 1

Let 

,

m2 =



2 0

0 3



,

m3 =



0 −1

1 0



,

m4 =



3 2

1 1



.

Then {m1, m3} generates G and {m2, m4} generates a subgroup H of index 5. The powers of m1 are   1 j j m1 = . 0 1 The five right cosets of H in G each contain one of the powers of m1; label the cosets 1,2,3,4,5 with j standing for the coset containing m1j . This defines an action of G on {1, 2, 3, 4, 5}, or equivalently a homomorphism of G into Σ5 . 119

a) Check that the image of G lies in A5 . b) Prove that the image is in fact A5 . c) Identify the kernel of the mapping and prove that it gives an isomorphism of P Sl2 ( 5 ) with A5 .

120

Jordan Normal Form Input Files /home/courses/B32/MatrixOperations.m /home/courses/B32/JordanNormalForm.m Mathematical Discussion Let F be a field. A linear transformation T from F n to F n can be represented by an n × n matrix with entries in F . However, the matrix corresponding to T depends not just on T but also on the basis for F n which is used. Matrices representing the same linear transformation with respect to different bases are called conjugate or similar. Explictly, A and B will be similar if there exists an invertible matrix U such that B = U AU −1 . Consider the question of attempting to classify all the similarity classes of matrices. Jordan normal form provides a method of answering this question by means of an algorithm for producing, from a given matrix, a change of basis which rewrites that matrix in a standardized form, called the Jordan normal form of the matrix. Given square matrices A, B, it is then easy to determine if they are similar by comparing their Jordan normal forms. Many properties of matrices (e.g. determinant) do not change when the basis is changed. When dealing with such properties, Jordan normal form is a useful theoretical tool since to prove a theorem concerning such properties for all matrices, it suffices to check it only for matrices having the normal form. A matrix M in Jordan normal form has square blocks running along the diagonal with all other entries zero. Each block has an eigenvalue of M running along the (main) diagonal, ones running along the subdiagonal, and all other entries zero, where the subdiagonal means the diagonal immediately below the main diagonal. The number of rows or columns of a block is called its multiplicity. The total of the multiplicities of all the blocks corresponding to a given eigenvalue is called the multiplicity of that eigenvalue. The following is an example of a matrix in Jordan normal form.   2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 0   0 0 0 0 0 0  0 0 −3 0   0 0 0 0 0  0 0 1 −3 0   0 −3 0 0 0 0 0 0 0 0 .  0 1 −3 0 0 0 0  0 0 0   0 0 1 −3 0 0 0  0 0 0   0 0 0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 It has four Jordan blocks corresponding to eigenvalues 2, −3, −3 and 0, with multiplicities 2, 2, 3, and 3, respectively. The multiplicities of the eigenvectors 2, −3 and 0 are 2, 5, and 3 respectively. 121

Since the eigenvalues of a matrix form part of its Jordan normal form, it may be necessary to enlarge the field F in order to calculate the Jordan Normal Form of a matrix. For example, a matrix with coefficients in will in general have to be regarded as a matrix over in order to calculate its Jordan normal form. An outline of the mathematical procedure for finding the Jordan normal form of a square matrix follows. Let V be a vector space and let M be a square matrix of size N . We describe a method for determining a basis for V so that M has Jordan normal form with respect to this basis. The procedure is divided into six steps. In step 1 we find a basis over which the matrix M divides into blocks, each corresponding to a different eigenvalue. Steps 2 to 5 describe the procedure for choosing a new basis for each block over which that block breaks up into subblocks; these constitute all the Jordan blocks for that eigenvalue. Step 6 shows how to combine the results to form a final basis. STEP 1: First, from the characteristic polynomial of M , compute its eigenvalues e1 , . . ., ek with their corresponding multiplicities m1 ,. . ., mk . For each eigenvalue ei find a basis for the kernel of (M − ei I)mi , where I denotes the identity matrix of size N . Each of these bases will contain mi vectors of size N . By joining all of these bases we get a basis containing N vectors of size N , which we call a characteristic basis. When M is written in a characteristic basis, it divides into blocks, where every block corresponds to a different eigenvalue. Recall that rewriting the linear transformation A in a basis {b1 , b2 , ..., bs } is accomplished by taking the matrix product B −1 · A · B, where B is the matrix whose columns are the vectors b1 through bs . Let D be the matrix whose columns are the vectors of the characteristic basis. When the above method is applied to M and the characteristic basis, the resulting matrix R = D−1 · M · D breaks into blocks corresponding to the eigenvalues. To proceed further we must operate individually on each block. Let Ti be the mi × mi submatrix of D−1 · (M − ei I) · D. Then Ti equals the i-th block minus a multiple of the identity. Recall that the Cayley-Hamilton Theorem states that evaluating the characteristic polynomial of a matrix at that matrix gives 0. Since, by construction, 0 is the only eigenvalue of Ti , Cayley-Hamilton implies that some power of Ti is 0. STEP 2: Here we describe the procedure for changing basis so that the first Jordan subblock appears for a particular block Ti . We will write simply T for Ti , and let n denote its size. Recall that the nilpotency of a matrix A is the least integer k (if any) such that Ak = 0. Let n1 be the nilpotency of T . Since T n1 −1 6= 0 we can choose a vector b1 such that T n1 −1 · b1 6= 0. Let b2 = T · b1 , b3 = T · b2 , . . ., bn1 = T · bn1 −1 . Call {b1 , b2 , . . . , bn1 } the partial basis B1 . Complete this to a basis B for the vector space on which T acts. By rewriting T in B we will see the first Jordan subblock of T in the first n1 columns, while the remaining columns will be garbage. Our next goal will be to modify B by rechoosing the completion of the basis B1 to get the other Jordan subblocks of T . 122

STEP 3: Here we describe the general procedure of how to change basis to get all Jordan subblocks of T . Let S be the lower right (n − n1 ) × (n − n1 ) submatrix of T . Let n2 be the nilpotency of S. Since S n2 −1 6= 0 we can choose a vector z1 such that S n2 −1 · z1 6= 0. Suppose we were to proceed as in step 2 and do the following: a) Let z2 = T z1 , z3 = T z2 , . . ., zn2 = T zn2 −1 . b) Add {zi } to B1 to form a partial basis Z1 . c) Complete Z1 to a basis Z for the vector space on which T acts. 

 J1 ∗ ∗ Then, if we were to rewrite M in the basis Z it would have the form  0 J2 ∗ . 0 0 ∗ That is, the second Jordan subblock would appear correctly, but there would be garbage above that block. This is because even though S n2 · z1 = 0, it is possible that T n2 · z1 6= 0. To adjust for this we wish to subtract from z1 some vector v from the subspace spanned by B1 so that T n2 · (z1 − v) equals 0. If we can find such a v, then we apply steps a) - c) as above with f1 = z1 − v. Namely: a) Let f2 = T f1 , f3 = T f2 , . . ., fn2 = T fn2 −1 . b) Add {fi } to B1 to form a partial basis B2 . c) Complete B2 to a basis B 0 for the vectorspace on which T acts. When we rewrite M in the basis B 0 , the second Jordan subblock appears correctly as it does with Z, since v is in the subspace spanned by B1 , and thus has no effect on the second subblock. However, the garbage above the second subblock has disappeared because T2n · (z1 − v) = 0. It remains to choose the proper vector v. Since S n2 · z1 = 0, the vector X = T n2 · z1 lies in the subspace spanned by B1 . Hence, we wish to solve T n2 · v = X for v. In the basis B, we can write X = (x1 , x2 , ..., xn1 , 0, ...0). T n1 −n2 · X = T n1 · z1 = 0. Since T takes each basis vector to the next, T n1 −n2 · X = (0, . . . , 0, x1 , . . . , xn2 , 0, . . . , 0). Thus x1 = ... = xn2 = 0, so X = (0, . . . , 0, xn2 +1 , . . . , xn1 ). Therefore we can let v = (xn2 +1 , . . . , xn1 , 0, . . . , 0) in the basis B. STEP 4: We now proceed to get the third Jordan subblock. Let B denote the basis constructed so far — that is, the basis B 0 from the preceding step. Let S be the lower right (n − n1 − n2 ) × (n − n1 − n2 ) submatrix of T , and let n3 be the nilpotency of S. As above choose a vector z1 such that S n3 −1 · z1 6= 0. We subtract from z1 some vector v from the subspace spanned by B2 , so that T n3 · (z1 − v) equals 0. Since S n3 · z1 = 0, X = T n3 · z1 lies in the subspace spanned by B2 . Since, within each basis segment, T takes each basis vector to the next, using reasoning as above, we conclude it suffices to let v = (xn2 +1 , . . . , xn1 , 0, . . . , 0, xn2 +n3 +1 , . . . , xn1 +n2 , 0, . . . , 0) in the basis B. Then, as above, let f1 = z1 − v and as before: 123

a) Let f2 = T f1 , f3 = T f2 , . . ., fn3 = T fn3 −1 . b) Add {fi } to B2 to form a partial basis B3 . c) Complete B3 to a basis B for the vector space on which T acts. STEP 5: Repeat step 4 until a basis giving all the Jordan blocks of T is obtained. STEP 6: Applying steps 2 – 5 to each block T1 , . . . , Tk we obtain the corresponding bases C1 , . . . , Ck . We then combine these bases to form a basis C, which contains N vectors of size N . We now have the basis over which the matrix R from step 1 has Jordan normal form. To get the basis over which the matrix M has Jordan normal form we apply the matrix D from step 1 to each vector in the basis C. Mathematica Functions This section describes some utility functions which are useful in executing the algorithm described above. Given a list l, Multiplicities[l], returns the list of pairs of distinct elements in l matched with their multiplicities. In[1]:= Multiplicities[{5,5,4}] Out[1]= {{4, 1}, {5, 2}} Let M be a square matrix. CharacteristicBases[M] gives a basis obtained by combining the basis for the kernels of (M − eI)m , where e is an eigenvalue of M and m is its multiplicity. Thus, in this basis, the matrix M breaks into blocks corresponding to its eigenvalues. SubMatrix[M,{a,b},{c,d}] returns the submatrix of M with entries mij for a ≤ i ≤ b and c ≤ j ≤ d. Nilpotency[M] returns the least integer k such that M k = 0. If there is no such integer, it returns Infinity. PowerMatrix[M.k] returns the matrix M k . BasisVector[p,l] returns the vector {0, 0, . . . , 1, . . . , 0} of length l with the 1 in the pth position. For a vector v, a matrix M and an integer n, PartialBasis[v,M,n] returns the list of vectors {v, M.v, M 2 .v, . . . , M n−1 .v}. If l = {l1, . . . , lk} is a list in which each lj is in turn a list giving a basis of nj , then CombineBases[l] returns a list giving a basis for n1+...+nk obtained from the bases in l by appropriately padding with zeroes. FirstNonZeroColumnPosition[M, r] returns the number of the first nonzero column in the submatrix of M consisting of the rows strictly beyond row r. If w is a vector, B is list of vectors giving a basis, and n1 and n2 are integers, SelectionVector[w,B,{n1,n2}] is the vector obtained by applying Transpose[B] to the vector {w[[n1 + 1]], . . . , w[[n1 + n2]], 0, . . . , 0}. It is useful for finding the vector v described in Step 3. 124

Usage Messages BasisVector BasisVector[p,l] is the vector {0, 0, . . . , 1, . . . , 0} of length l with the 1 in the p-th position. CharacteristicBases CharacteristicBases[M], where M is a square matrix, gives a basis obtained by combining the basis for the kernels of (M −eI)m , where e is an eigenvalue of M and m is its multiplicity. Thus, in this basis, the matrix M breaks into blocks corresponding to its eigenvalues. CombineBases CombineBases[l], where l = {l1, . . . , lk} is a list in which each lj is in turn a list giving a basis of nj , returns a list giving a basis for n1+...+nk obtained from the bases in l by appropriately padding with zeroes. FirstNonZeroColumnPosition FirstNonZeroColumnPosition[M, r] gives the number of the first nonzero column in the submatrix of M consisting of the rows strictly beyond row r. Multiplicities Multiplicities[l], gives the list of pairs of distinct elements in the list l matched with their multiplicities. Nilpotency Nilpotency[M], where M is a matrix, gives the least integer k such that M k = 0. If there is no such integer, it returns Infinity. PartialBasis PartialBasis[v,M,n], where v is a vector, M is a matrix, and n is an integer, gives the list of vectors {v, M.v, M 2 .v, . . . , M n−1 .v}. PowerMatrix PowerMatrix[M.k], where M is a matrix, gives the matrix M k . SelectionVector SelectionVector[w,B,{n1,n2}], where w is a vector, B is list of vectors giving a basis, and n1 and n2 are integers, is the vector obtained by applying Transpose[B] to the vector {w[[n1 + 1]], . . . , w[[n1 + n2]], 0, . . . , 0}. SubMatrix SubMatrix[M,{a,b},{c,d}] returns the submatrix of M with entries mij for a ≤ i ≤ b and c ≤ j ≤ d.

125

Examples In[1]:= M ={{3,1,1,9/8,1,9/8,7/8,7/8,1}, {1,2,0,1/8,0,1/8,-1/8,-1/8,0}, {0,1,2,1/8,0,1/8,-1/8,-1/8,0}, {0,0,1,17/8,0,1/8,-1/8,-1/8,0}, {1,1,1,9/8,3,9/8,7/8,7/8,1}, {0,0,0,1/8,1,17/8,-1/8,-1/8,0}, {0,0,0,1/8,0,1/8,23/8,-1/8,0}, {-1,-1,-1,-7/8,-1,-7/8,-1/8,15/8,-1}, {-1,-1,-1,-7/8,-1,-7/8,-9/8,-1/8,2}}; We will find the Jordan Normal Form of M . STEP 1.1: Find the eigenvalues of M with their corresponding multiplicities. In[2]:= Out[2]= In[3]:= Out[3]=

v=Eigenvalues[M] {2, 2, 3, 2, 2, 3, 2, 2, 3} e = Multiplicities[v] {{2, 6}, {3, 3}}

This shows that the Jordan normal form must consist of a block of size 6 and a block of size 3, corresponding to the eigenvalues 2 and 3 respectively. Each block might be subdivided further into Jordan subblocks with the same eigenvalue. STEP 1.2: Find those two blocks. CharacteristicBases[M] produces a new basis B. In Mathematica matrices are presented as lists of rows. However to convert a linear transformation to a basis we need the matrix whose columns are the vectors of our basis and so we need to take the transpose. In[3]:= B = Transpose[CharacteristicBases[M]]; STEP 1.3: Rewrite the linear transformation M in the new basis, whose vectors are the columns of B. In[4]:= Blocks = Inverse[B].M.B; In[5]:= MatrixForm[Blocks] 11/4 1/8 0 1/8 0 0 0 −1/4 17/8 1 1/8 0 0 0 3/4 1/8 2 1/8 0 0 0 −1/4 1/8 0 17/8 1 0 0 0 1/8 2 1 0 Out[5]= −1/4 1/8 −9/4 −7/8 −1 −7/8 −1 1 0 0 0 0 0 0 0 63/20 0 0 0 0 0 0 3/20 0 0 0 0 0 0 −1/20

0 0 0 0 0 0 0 0 0 0 0 0 121/40 1/40 121/40 41/40 −7/40 113/40

STEP 1.4: Extract the submatrices T 1 and T 2. In[6]:= block1 = SubMatrix[Blocks,{1,6},{1,6}]; In[7]:= T1 = block1 - 2 IdentityMatrix[6]; In[8]:= MatrixForm[T1] 126

3/4 1/8 0 1/8 0 0 −1/4 1/8 1 1/8 0 0 3/4 1/8 0 1/8 0 0 Out[8]= −1/4 1/8 0 1/8 1 0 −1/4 1/8 0 1/8 0 1 −9/4 −7/8 −1 −7/8 −1 −1 In[9]:= block2 = SubMatrix[Blocks,{7,9},{7,9}]; In[10]:= T2 = block2 - 3 IdentityMatrix[3]; In[11]:= MatrixForm[T2] 3/20 41/40 1/40 Out[11]= 3/20 1/40 41/40 −1/20 −7/40 −7/40 For each of the matrices T 1 and T 2 we apply the steps to produce its Jordan normal form. STEP 2.1: Begin with T 1, whose size is 6×6. Find the least n1 such that T n 1 = 0 and T n1−1 6= 0. In[12]:= n1 = Nilpotency[T1] Out[12]= 4 STEP 2.2: Find a vector b1 such that T 1n1−1 · b1 6= 0, and complete it to a partial basis, basis1, as described in Step 2 of the mathematical discussion. We choose b1 to be the basis vector corresponding to the first non-zero column of T 1n1−1 . Create a new basis vector b1, and complete it to a partial basis, basis1, described in Step 2 of the mathematical discussion. In[13]:= In[14]:= Out[14]= In[15]:= Out[15]= In[16]:= Out[16]=

auxiliary = PowerMatrix[T1, n1-1]; p1 = FirstNonZeroColumnPosition[auxiliary, 0] 1 b1 = BasisVector[p1, n] {1, 0, 0, 0, 0, 0} basis1 = PartialBasis[b1, T1, n1] {{1, 0, 0, 0, 0, 0}, {3/4, −1/4, 3/4, −1/4, −1/4, −9/4}, {1/2, 1/2, 1/2, −1/2, −5/2, 1/2}, {3/8, 3/8, 3/8, −21/8, 3/8, 3/8}}

STEP 2.3: Complete basis1 to a basis Q1 for T 1; i.e. find n − n1 more linearly independent vectors. In[17]:= vectors = NullSpace[basis1] Out[17]= {{0, −3, 2, 0, 0, 1}, {0, 4, 2, 1, 1, 0}} In[18]:= Q1 = Join[basis1, vectors] Out[18]= {{1, 0, 0, 0, 0, 0}, {3/4, −1/4, 3/4, −1/4, −1/4, −9/4}, {1/2, 1/2, 1/2, −1/2, −5/2, 1/2}, {3/8, 3/8, 3/8, −21/8, 3/8, 3/8}, {0, −3, 2, 0, 0, 1}, {0, 4, 2, 1, 1, 0}} 127

STEP 2.4: Rewrite the linear transformation represented by the matrix T 1 in the basis Q1 in order to see the first Jordan block of size n1 × n1 (= 4 × 4). As before, we need to take the transpose. In[19]:= Qt1 = Transpose[Q1]; In[20]:= R1 = Inverse[Qt1].T1.Qt1; In[21]:= MatrixForm[R1] 0 0 0 0 −24/61 −56/61 1 0 0 0 1/61 165/61 0 1 0 0 −29/183 −88/183 Out[21]= 0 0 1 0 125/549 −359/549 0 0 0 0 −21/61 −49/61 0 0 0 0 9/61 21/61 At this point we have the b1, b2, b3, b4 we want. Now we need to choose b5 and b6. STEP 3.1: Find the least n2 such that S n2 = 0 but S n2−1 6= 0, where S is the lower right (n − n1) × (n − n1) submatrix of R1. In[22]:= auxiliary = SubMatrix[R1,{5,6},{5,6}]; In[23]:= n2 = Nilpotency[auxiliary] Out[23]= 2 STEP 3.2: Find the position of the first non-zero vector in the matrix R1n2−1 beyond row n1. In[24]:= auxiliary = PowerMatrix[R1,n2-1]; In[25]:= p2 = FirstNonZeroColumnPosition[auxiliary,n1] Out[25]= 5 STEP 3.3: Find the vector b5. In[26]:= Out[26]= In[27]:= In[28]:= Out[28]=

z1 = Q1[[p2]] {0, −3, 2, 0, 0, 0} auxiliary = Transpose[PowerMatrix[R1, n2]]; c1 = auxiliary[[p2]] {0, 0, 0, −1/3, 0, 0}

c1 is the vector X in Step 3 of the mathematical discussion. In[29]:= Out[29]= In[30]:= Out[30]=

v0 = SelectionVector[c1, Q1,{n1,n2}] {−1/4, 1/12, −1/4, 1/12, 1/12, 3/4} b5 = z1 - v0 {−1/4, −37/12, 9/4, −1/12, −1/12, 1/4}

SelectionVector[ ] has returned the vector v described in Step 3 of the mathematical discussion and written it, not in the basis Q1, but in the original basis. 128

STEP 3.4: Complete b5 to a partial basis and join with basis1. In[31]:= partialbasis = PartialBasis[b5,T1,n2] Out[31]= {{1/4, −37/12, 9/4, −1/12, −1/12, 1/4}, {−5/24, 43/24, −5/24, −13/24, −5/24, −5/24}} In[32]:= basis1 = Join[basis1,partialbasis] Out[32]= {{1, 0, 0, 0, 0, 0}, {3/4, −1/4, 3/4, −1/4, −1/4, −9/4}, {1/2, 1/2, 1/2, −1/2, −5/2, 1/2}, {3/8, 3/8, 3/8, −21/8, 3/8, 3/8}, {1/4, −37/12, 9/4, −1/12, −1/12, 1/4}, {−5/24, 43/24, −5/24, −13/24, −5/24, −5/24}} STEP 3.5: Since basis1 now contains 6 vectors it is a complete basis for T 1. Rewrite the linear transformation represented by the matrix T 1 in basis1 in order to see the complete Jordan normal form for T 1. In[33]:= Qt2 = Transpose[basis1]; In[34]:= R2 = Inverse[Qt2].T1.Qt2; In[35]:= MatrixForm[R2] 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 Out[35]= 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 In this example, the Jordan normal form of T 1 has only two blocks, so we skip Step 4 and proceed to Step 5. STEP 5.1: The algorithm for finding the Jordan normal form is repeated for the matrix T 2. After performing the operations and transformations the basis for T 2 is given by basis2, where basis2 = {{1, 0, 0, }, {3/20, 3/20, −1/20}, {7/40, −1/40, −1/40}}. STEP 5.2: Rewrite the linear transformation represented by the matrix T 2 in the basis basis2 in order to see the complete Jordan normal form for T 2. In[36]:= Qt3 = Transpose[basis2]; In[37]:= R3 = Inverse[Qt3].T2.Qt3; In[38]:= MatrixForm[R3] 0 0 0 Out[38]= 1 0 0 0 1 0 129

STEP 6.1: Combine the bases basis1 and basis2 to a single basis containing n vectors of size n. In[39]:= basis = CombineBases[basis1,basis2] Out[39]= {{1, 0, 0, 0, 0, 0, 0, 0, 0}, {3/4, −1/4, 3/4, −1/4, −1/4, −9/4, 0, 0, 0}, {1/2, 1/2, 1/2, −1/2, −5/2, 1/2, 0, 0, 0}, {3/8, 3/8, 3/8, −21/8, 3/8, 3/8, 0, 0, 0}, {1/4, −37/12, 9/4, −1/12, −1/12, 1/4, 0, 0, 0}, {−5/24, 43/24, −5/24, −13/24, −5/24, −5/24, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 3/20, 3/20, −1/20}, {0, 0, 0, 0, 0, 0, 7/40, −1/40, −1/40}} STEP 6.2: To get the final basis over which the linear transformation M has Jordan normal form, we need to apply the matrix B to each of the vectors in basis. In[40]:= jordanbasis = B.Transpose[basis] Out[40]= {{−2, 3/4, 1/2, 3/8, −1/4, −5/24, −1, −1/4, −1/8}, {0, −9/4, 01/2, 3/8, 1/4, −5/24, −1, −1/4, −1/8}, {0, −1/4, −5/2, 3/8, −1/12, −5/24, −1, −1/4, −1/8}, {0, −1/4, −1/2, −21/8, −1/12, −13/24, −1, −1/4, −1/8}, {0, 3/4, 1/2, 3/8, 9/4, −5/24, −1, −1/4, −1/8}, {0, −1/4, 1/2, 3/8, −37/12, 43/24, −1, −1/4, −1/8}, {1, 3/4, 1/2, 3/8, 1/4, −5/24, 0, −1/4, −1/8}, {1, 3/4, 1/2, 3/8, 1/4, −5/24, 0, 3/4, −1/8}, {1, 3/4, 1/2, 3/8, 1/4, −5/24, 5, 3/4, 7/8}} STEP 6.3: Rewrite M in jordanbasis to see the complete Jordan normal form. In[41]:= Inverse[jordanbasis].M.jordanbasis 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 Out[41]= 0 0 0 0 2 0 0 0 0 0 0 0 0 1 2 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1 3 0 0 0 0 0 0 0 0 1 3

130

Sequences

Input Files /home/courses/B43/sequences.m Mathematical Discussion The positive integers, also known as the natural numbers, will be denoted by or by or by P . A sequence is a function whose domain is the set of positive integers and whose range is , the set of real numbers. A sequence is written by giving its nth term — for example, (1/2n ). It is also the custom to write the sequence as {1/2, 1/4, 1/8, 1/16, . . .}. That is, we list the first few terms of the sequence, and the trailing dots mean that we pretend that we know how things will continue forever after. A key concept in relation to sequences is that of a limit. A sequence might or might not have a limit. Intuitively, a limit for a sequence will be a number L such that the nth term of the sequence gets closer and closer to L as n gets larger. The precise definition is that L is the limit of the sequence (an ) if, for every real number  > 0, there is an N ∈ such that |xn − L| <  for every n > N . Pn Associated to sequence (an ) is another sequence (sn ) defined by sn = k=1 an . Usually we refer to the sequence (sn ) as the series (an ) and we use the phrase “the series (an ) converges” to mean that the sequence (sn ) converges. Since the series is intended to correspond to our intuitive notion of the sum of all the elements in the sequence, we extend the terminology from ordinary (finite) sums and refer to elements of the original sequence (an ) as terms ofP the series. The elements (sn ) are called the partial sums of the sequence (an ). We write an for the series associated to the sequence (an ). For a series to converge, a necessary condition is that the terms of the original sequence must have a limit, and further that that limit must be 0. But this is not sufficient, since a series may have terms that tend to 0 and still not converge. The harmonic series (1/n) is the classic example. There are a number of techniques (comparison test, integral test, root test, ratio test, . . .) which attempt to determine whether or not a given series converges by examining the terms of the sequence itself, without attempting to explicitly compute the partial sums. P To apply the ratio test to the series an , we create a new sequence bn from the ratios bn = |an+1 /an |. If the sequence (bn ) converges to a limit L with L < 1 then the series (an ) converges, while if it converges to L with L > 1 then it diverges. If it either converges to 1 or fails to converge, then the test is inconclusive and gives no information one way or the other. Another way to check for convergence is to use the root test. This time the new sequence is formed by letting bn = |an |(1/n) . Again, we calculate the limit of this new sequence, if it has one, and see whether it is less than, greater than, or equal to 1. +

131

Mathematica Functions A sequence is a function on . Therefore, a sequence can be defined and its nth term can be evaluated using the usual Mathematica syntax for defining and evaluating functions. For example, the following defines the harmonic series. In[1]:= H[n ]:=1/n To display its 7th term: In[2]:= H[7] Out[2]= 1/7 A number of sequences, including H, have been defined in the file “sequences.m”. Let A be a sequence. A plot of the of the first k terms of the sequence can be obtained with sequence[A,k,m], which also prints the first m terms on the screen. If k and m are omitted, 20 terms will be plotted and 5 terms shown. Mathematica has a built-in function Limit[ ], but its results are not necessarily to be trusted. In[3]:= GP2[n ]:=2^(-n) In[4]:= Limit[GP2[n], n→Infinity Out[4]= 0 This is a case where it got the answer right. Another built-in Mathematica P function, NSum[A] might give a numerical approximation to the sum of the series An , but again itsP output is not always to be trusted. To see a list of some partial sums for the series An , use series[A]. In[5]:= sequence[series[GP2]]; plots the beginning of the list of partial sums for the series associated to the geometric progression GP 2. The sequence of ratios used by the ratio test can be obtained with ratiotest[A],and the sequence used by the root test can be obtained with roottest[A]. The functions described above allow you to examine terms of sequences and partial sums of series and to display them graphically. It must be emphasized, however, that while the output may be useful in developing intuition, it can in no way constitute a proof that a given number is or is not the limit. In fact, the whole notion of a limit is based on what happens “eventually” and this is reflected in the definition of a limit. The functions we have been describing can show you only some finite portion of the behaviour near the beginning of the sequence. Therefore, it is clear that on their own they cannot demonstrate convergence or lack of convergence. Usage Messages ratiotest ratiotest[A], where A is a sequence, is the sequence which is examined when applying the ratio test, to attempt to determine if the series formed from the terms of A converges. 132

roottest roottest[A], where A is a sequence, is the sequence which is examined when applying the root test, to attempt to determine if the series formed from the terms of A converges. Exercises 1. Find a sequence A for which Mathematica’s Limit[A[n],n→ Infinity] gives the wrong answer. (That is, not an example in which it gives up, but one in which it returns an incorrect answer.)

133

Conditionally Convergent Sequences Input Files /home/courses/B43/harmonic.m Mathematical Discussion P P A series an is called absolutely convergent if the series |an | converges. If a series is absolutely convergent then it converges, but it is possible for a series to converge even though it is not absolutely convergent. In this case the series is said to be conditionally convergent. TheP classic example of a conditionally convergent sequence is the alternating harmonic seriesP (−1)n+1 1/n. Let A = an be a conditionally convergent series, converging to S. One of the features of a conditionally convergent series is that, given any real number L, there is a rearrangement of the order of the terms of the series such that the rearranged series converges to L. To see this, consider the series A+ and A− consisting, respectively, of the positive terms in A and the negative terms in A. If one of these series converged the other would converge also; that is, if for example A+ converged to S+ , then A− would converge to S − S+P . But if both series converged, then A would be absolutely convergent since the series |an | would converge to S+ − S− . Thus, for a conditionally convergent series, both A+ and A− diverge. Given L, begin the rearranged series, R, by choosing the minimum number of terms from the beginning of A+ such that their sum exceeds L. This can be done, since the series A+ diverges, and so eventually its partial sums exceed L. Next, append to R the minimum number of terms from the beginning of A− , the sequence of negative terms, such that their sum is less than L − CS, where the “current sum”, CS, is the sum of the terms placed in R so far. This can be done for a similar reason to that described above, in this case, since A− diverges. The new CS, obtained by adding in these negative terms, will now be less than L. Returning now to A+ , deletion of those terms from A+ already used in R — a finite number of terms — won’t affect the divergence of the series. Choose the minimum number of terms from the deleted series, such that their sum exceeds L − CS. Continuing, the value of CS will alternate after each step from being greater than L to less than L. Since in each step we stop after the first term which causes L − CS to change sign, |L − CS| is bounded by the absolute value of that term. But since the series A is convergent, its terms converge to 0. Thus the size of the differences, |L − CS|, converges to 0 and so the partial sums converge to L. Mathematica Functions The functions in this package allow you to experiment with rearrangements of the alternating harmonic series. Since the series is alternating, A+ consists of the odd numbered terms and A− consists of the even numbered terms. P Substituting x = 1 into the Taylor Series log(1 + x) = (−1)n+1 xn /n shows that the alternating harmonic series converges to log(2). Suppose we wish to rearrange the series 134

√ so that it converges to 2. The first step √ is to find the number of positive terms required in order that their sum is greater than 2. For an odd positive integer start and real numbers x,y, with x > y, ExceedOdd[x,y, start], returns the least integer f inish such that y+

fX inish

1/k > x.

k=start;k odd

It also sets the variable CurrentOdd to be the next unused odd number; i.e. f inish + 2. In[1]:= s=Sqrt[2]; In[2]:= ExceedOdd[s,0,1] Out[2]= 5 This tells us that 1 + 1/3 + 1/5 >

2, while 1 + 1/3
y and k an odd integer, returns the least integer z such that y + k=start;k odd 1/k > x. Exercises 1. Find the beginning of the rearrangement of the harmonic series which converges to the sixth digit of your student number. Determine how many terms you must add 136

to be certain that every subsequent partial sum is within .1 of the sixth digit of your student number. Explain why you’ve gone far enough. 2. Given positive integers o and e, find the sum of the rearrangement of the harmonic series consisting of taking the first o positive terms, followed by the first e even terms, followed by the next o positive terms, then the next e negative terms, and continuing in this way alternating between taking the next o positive terms and the next e negative terms.

137

Congruences Input Files /home/courses/B70/congruences.m

Mathematical Discussion Let p be a prime. For 1 ≤ a ≤ p − 1, to find the inverse of a modulo p we use the fact that ap−1 ≡ 1 (mod p) (Fermat’s Little Theorem), from which we see that ap−2 reduced modulo p is the inverse of a. More generally, if a is relatively prime to n, the inverse of a modulo n is φ(n) − 1, where φ(n) is the order of the group of units in the ring /n . φ(n), known as the Euler phi function, is determined by a prime decomposition of n using the facts that (1) φ (q r ) = q r − q r−1 for a prime q, and (2) φ(st) = φ(s)φ(t) when s and t are relatively prime. For an integer n, let νp (n) denote the number of times p divides n. For example v2 (40) = 3. We find a formula for νp (n!). Obviously νp (xy) = νp (x) + νp (y). If pt ≤ m < pt+1 , then νp (m) = νp (m − pt ). Repeated application of the above formulas shows that if n = a0 + a1 p + a2 p2 + . . . + ak pk Pk is the p-adic expansion of n, then νp (n!) = i=0 ai νp (pi !). By induction on t, we get that νp (pt ) = 1 + p + p2 + . . . + pt−1 = (pt − 1) /(p − 1). Therefore νp (n!) =

k X i=0

 ai pi − 1 /(p − 1) = (n − (a0 + a1 + . . . + ak )) /(p − 1).

Notice in particular, that νp (n!) < n, or, equivalently, that pn /n! is divisible by p. Let m1 and m2 be relatively prime positive integers. Then there exist integers r and s such that rm1 + sm2 = 1. According to the Chinese Remainder Theorem, there exists a solution to the system x ≡ b1 (mod m1 ) . x ≡ b2 (mod m2 ) Explicitly, b = b2 rm1 + b1 sm2 is a solution, since b ≡ b1 sm2 = b1 (1 − rm1 ) ≡ b1 (mod m1 ) and similarly, b ≡ b2 (mod m2 ). If c is also a solution, then c ≡ b (mod m1 ) and c ≡ b (mod m2 ), so that c − b is a multiple of the least common multiple, m1 m2 , of m1 and m2 . Thus, the system has a unique solution modulo m1 m2 . Therefore, the problem of solving congruences modulo n is reduced to that of the special cases where n is a power of a prime, which we consider next. 138

Let f (x) be a degree k polynomial with integer coefficients. f (x) ≡ 0 (mod p) is be solved by factoring f (x) modulo p. We will not consider techniques for doing this, but assume as a starting point that the solutions of f (x) ≡ 0 (mod p) are known. Suppose now we wish to solve the congruence f (x) ≡ 0 (mod pr+1 ), having previously solved the congruence f (x) ≡ 0 (mod pr ). Let a be a solution to f (x) ≡ 0 (mod pr ). That is, f (a) ≡ 0 (mod pr ), with 0 ≤ a < pr − 1. By Taylor’s Theorem f (a + tpr ) = f (a) + tpr f 0 (a) + t2 p2r f 00 (a)/2! + . . . + tk pkr f (k) (a)/k! ≡ f (a) + tpr f 0 (a) (mod pr+1 ), since earlier discussion implies that all the other terms are divisible by p at least r + 1 times. Thus a + tpr is a solution of f (x) ≡ 0 (mod pr+1 ) if and only if t is a solution of f (a) + tpr f 0 (a) ≡ 0 (mod pr+1 ). Using the fact that f (a) ≡ 0 (mod pr ), this congruence can be divided by pr to obtain an equivalent congruence (f (a)/pr ) + tf 0 (a) ≡ 0 (mod p). Knowledge of how to compute inverses modulo p is sufficient to solve the latter congruence. Mathematica Functions Congruence[y,b,m]. Either ModSolve[ ] or BruteForce[ ] can be used to solve a linear congruence ax ≡ b (mod m). ModSolve[ ] solves the congruence by finding an inverse to a as described above, while BruteForce[ ] simply tests values of x until the solution is found. BruteForce[ ] returns a list of the solutions: In[1]:= BruteForce[Congruence[28x,4,244]] Out[1]= {Congruence[x, 35, 44], Congruence[x, 96, 44], Congruence[x, 157, 44], Congruence[x, 218, 44], } ModSolve[ ] returns the equivalent statement: In[2]:= ModSolve[Congruence[28x,4,244]] Out[2]= Congruence[x, 35, 61] ModSolve[ ] and BruteForce[ ] can also be used to solve a system of two congruences of the form x ≡ b1 (mod m1 ), x ≡ b2 (mod m2 ). In[3]:= ModSolve[Congruence[x,2,3]],Congruence[x,3,5] Out[3]= Congruence[x, 8, 15] Usage Messages BruteForce BruteForce[Congruence[ax,b,m], where a, b, and m are integers, gives the list of solutions modulo m of the congruence ax ≡ b (mod m). BruteForce[Congruence[x,b1,m1],Congruence[x,b2,m2]] returns {Congruence[x, b, L]}, where L is the least common multiple of m1 and m2, and b is the solution of the system x ≡ b1 (mod m1 ), x ≡ b2 (mod m2 ). Congruence Congruence[y,b,m], where b and m are integers, is the congruence y ≡ b (mod m). 139

ModSolve ModSolve[Congruence[ax,b,m], where a, b, and m are integers, gives the solution of the congruence ax ≡ b (mod m). ModSolve[Congruence[x,b1,m1],Congruence[x,b2,m2]] returns Congruence[x, b, L], where L is the least common multiple of m1 and m2, and b is the solution of the system x ≡ b1 (mod m1 ), x ≡ b2 (mod m2 ). Examples 1. Solve the system of congruences x ≡ 2 (mod 3), x ≡ 3 (mod 5), x ≡ 2 (mod 7). Solution: In[1]:= Out[1]= In[2]:= Out[2]=

ModSolve[Congruence[x,2,3]],Congruence[x,3,5] Congruence[x, 8, 15] ModSolve[Congruence[x,8,15]],Congruence[x,2,7] Congruence[x, 23, 105]

2. Solve the congruence x3 + 4x2 + 5x + 2 ≡ 0 (mod 27). Solution: In[1]:= In[2]:= Out[2]= In[3]:= Out[3]=

f=x^3+3x^2+5x+2; df=D[f,x] 5 + 8x + 3x2 BruteForce[Congruence[f,0,3]] {Congruence[x, 1, 3], Congruence[x, 2, 3]}

Proceeding now to modulus 9, we consider first the solutions resulting from Congruence[x, 1, 3]. In[4]:= f/.x→1 Out[4]= 12 In[5]:= df/.x→1 Out[5]= 16 In[6]:= ModSolve[Congruence[16t,-12/3,3]] Out[6]= Congruence[t, 2, 3] which gives the solution 1 + 2 ∗ 3 = 7 modulo 9. Similarly, Congruence[x, 2, 3] yields In[7]:= f/.x→2 Out[7]= 36 In[8]:= df/.x→2 Out[8]= 33 In[9]:= ModSolve[Congruence[33t,-36/3,3]] Out[9]= Congruence[t, 0, 1] which means that all of t ≡ 0, 1, or 2 are solutions modulo 3. This gives the solutions 2 + 0 ∗ 3 = 2, 2 + 1 ∗ 3 = 5, and 2 + 2 ∗ 3 = 8 modulo 9. Thus f ≡ 0 (mod 9) if and only if x ≡ 7, 2, 5, or 8 modulo 9. 140

Proceeding now to modulus 27: In[10]:= Out[10]= In[11]:= Out[11]= In[12]:= Out[12]=

f/.x→7 576 df/.x→7 208 ModSolve[Congruence[208t,-576/9,3]] Congruence[t, 2, 3]

which gives the solution 7 + 2 ∗ 9 = 25 modulo 27. In[13]:= Out[13]= In[14]:= Out[14]= In[15]:= Out[15]=

f/.x→2 33 df/.x→1 36 ModSolve[Congruence[33t,-36/9,3]] Indeterminate

which means that x ≡ 2 (mod 9) yields no solutions modulo 27. In[16]:= Out[16]= In[17]:= Out[17]= In[18]:= Out[18]= In[19]:= Out[19]= In[20]:= Out[20]= In[21]:= Out[21]=

f/.x→5 252 df/.x→5 120 ModSolve[Congruence[120t,-252/9,3]] Indeterminate f/.x→8 810 df/.x→8 261 ModSolve[Congruence[261t,-810/9,3]] Congruence[t, 0, 1]

which gives solutions 8 + 0 ∗ 9 = 8, 8 + 1 ∗ 9 = 17, and 8 + 2 ∗ 9 = 26 modulo 27. Therefore the solutions are 25, 8, 17 and 26 modulo 27. 3. Solve the congruence x2 + 18x − 23 ≡ 0 (mod 200). Solution: In[1]:= In[2]:= Out[2]= In[3]:= Out[3]=

f=x^2+18x-23; df=D[f,x] 18 + 2x BruteForce[Congruence[f,0,2]] {Congruence[x, 1, 2]}

Proceeding to modulus 4: In[4]:= f/.x→1 Out[4]= −4 141

In[5]:= Out[5]= In[6]:= Out[6]=

df/.x→1 20 ModSolve[Congruence[20t,-(-4)/2,2]] Congruence[t, 0, 1]

which gives the solutions 1 + 2 ∗ 0 = 1 and 1 + 2 ∗ 1 = 3 modulo 4. Modulo 8: In[7]:= f/.x→ {1,3} Out[7]= {−4, 40} In[8]:= df/.x→ {1,3} Out[8]= {20, 24} In[9]:= ModSolve[Congruence[20t,-(-4)/4,2]] Out[9]= Indeterminate In[10]:= ModSolve[Congruence[24t,-40/4,2]] Out[10]= Congruence[t, 0, 1] which gives the solutions 3 + 0 ∗ 4 = 3 and 3 + 1 ∗ 4 = 7 modulo 8. In[11]:= BruteForce[Congruence[f,0,5]] Out[11]= {Congruence[x, 3, 5], Congruence[x, 4, 5]} Modulo 25: In[12]:= Out[12]= In[13]:= Out[13]= In[14]:= Out[14]=

f/.x→ {3,4} {40, 65} df/.x→ {3,4} {24, 26} ModSolve[Congruence[24t,-40/5,5]] Congruence[t, 3, 5]

which gives the solution 3 + 3 ∗ 5 = 18 modulo 25. In[15]:= ModSolve[Congruence[26t,-65/5,5]] Out[15]= Congruence[t, 2, 5] which gives the solution 4 + 2.5 = 14 modulo 25. Modulo 200: In[16]:= Out[16]= In[17]:= Out[17]= In[18]:= Out[18]= In[19]:= Out[19]=

ModSolve[Congruence[x,3,8],Congruence[x,18,25]] Congruence[x, 43, 200] ModSolve[Congruence[x,3,8],Congruence[x,14,25]] Congruence[x, 139, 200] ModSolve[Congruence[x,7,8],Congruence[x,18,25]] Congruence[x, 143, 200] ModSolve[Congruence[x,3,8],Congruence[x,14,25]] Congruence[x, 39, 200]

Therefore the solutions are 43, 139, 143, and 39 modulo 200.

142

Sieves Input Files /home/courses/B70/sieves.m Mathematical Discussion A sieve on the collection of positive integers is a method for producing a desired subset by making multiple passes through the set, eliminating some undesired elements during each pass, in such a way that every undesired element is removed during some pass. The sieve of Eratosthenes produces the set of primes by eliminating composite numbers. Beginning with the integers greater than 1, the first pass deletes all proper multiples of 2; that is, all multiples except for 2 itself. The next pass removes proper multiples of 3 from the remaining set, and so on, with each pass removing all √ proper multiples of the smallest element of the set which has not yet been used. After [ m] passes, the beginning of the list will consist of the primes up to m. Other interesting subsets of the integers can be defined as the result of using sieves with slight modifications on the rule used in Eratosthenes’ sieve for deciding which elements are to be eliminated during a pass. For example, let’s begin again with the set of positive integers. The least element apart from 1, we will consider as already “used” is 2, so suppose we strike every second element from the set; that is, eliminate all even numbers. The least remaining unused element is 3 so we strike every third element from the remaining set; that is, eliminate 5, 11, 17, . . .. The next pass eliminates every 7th element and so on with each pass deleting every kth element, where k is the least unused element of the set at the beginning of the pass. The set of numbers remaining, 1, 3, 7, 9, 13, . . . have been called “lucky numbers” and have some density properties similar to those of primes. Mathematica Functions ESieve[S,n] gives the numbers from 1 to n with proper multiples of elements in the set S deleted. ESieves[n] gives the set of the intermediate lists obtained by applying Eratosthenes sieve to the numbers up to n. For k ≥ 2, LSieve[k,X] gives the list obtained by deleting every kth element from the list X. LSieves[ ] is similar to ESieve[ ] but for the sieve of “lucky numbers”. Toggle[1,n] is the set {1, 2, . . . , n}. For 2 ≤ k ≤ n, Toggle[k,n] is defined inductively from Toggle[k-1,n] by reversing the sign of every kth element. TSieve[k,n] gives the subset of Toggle[k,n] consisting of those elements with positive signs. TSieves[n] produces the list whose kth entry is the list Toggle[k,n]. Usage Messages ESieve ESieve[S,n], where n is an integer and S is a set of integers, gives the numbers from 1 to n with the multiples of elements in the set S deleted. 143

ESieves ESieves[n] gives the set of the intermediate lists obtained by applying Eratosthenes sieve to the numbers up to n. LSieve LSieve[k,S], where k is an integer greater than 1 and S is a list, gives the list obtained from S by deleting every kth element. LSieves LSieves[n] gives the set of the intermediate lists obtained by applying the “lucky numbers” sieve up to n. Toggle Toggle[k,n], where k > 1 and n are positive integers, is defined inductively from Toggle[k-1,n] by reversing the sign of every kth element. Toggle[1,n] is {1, 2, . . . , n}. TSieve TSieve[k,n], where k and n are integers, gives the subset of Toggle[k,n] consisting of those elements with positive signs. TSieves TSieves[n], where n is an integer, produces the list whose kth entry is the list Toggle[k,n]. Exercises 1. Determine which integers remain in the final list produced by TSieves[n].

144

Powers

Input Files /home/courses/B70/powermod.m Mathematical Discussion Consider the problem of calculating xn . Whether implemented through hardware, software, or pencil-and-paper, multiplication and division operations require looping and thus take an order of magnitude longer than addition, subtraction, and testing. Since integers are stored on a computer in binary form, multiplication and division by 2 is an exception, since these can be implemented by shifting the bits left or right. Consequently, we will count only the number of multiplication operations, ignoring the time taken for the operations of addition, subtraction, testing to see if a number is even or odd, and dividing by 2. Calculating xn recursively by means of xn = x ∗ xn−1 requires n − 1 multiplications. However we could for example compute x16 using only 4 multiplications by repeated squaring. Given an integer n, let half(n) be [n/2], the integer obtained by dividing n by 2 and dropping the remainder. Since half(n) < n for all n > 0, if half() is applied repeatedly to n, eventually 0 is reached. Given n, form a sequence of O’s and I’s by repeatedly applying the operation half() and recording the remainders of the division in the sequence. Thus 160 yields the sequence OOOOOIOI. No costly multiplication or division operations are required to compute this sequence. The integer n can be recovered from its sequence by beginning from 0, and treating the entry I in the sequence as the operation I(k) = 2k + 1 and O as the operation O(k) = 2k. xn can be computed by beginning from 1 and applying the above sequence by treating O to mean y → y 2 and I to mean y → x ∗ y 2 . Thus each O requires 1 multiplication and each I requires 2. Since n produces a sequence of length [log2 (n) + 1], the maximum number of multiplications required to compute xn by this method is 2 log2 (n) + 1. Mathematica Functions OISequence[ ] returns the list described above. In[1]:= OISequence[160] Out[1]= {O, O, O, O, O, I, O, I} OISequenceTable[ ] produces a more detailed listing containing the intermediate steps in the calculation of OISequence[ ]. In[2]:= OISequenceTable[160] 145

160 80 40 20 Out[2]= 10 5 2 1

Even Even Even Even Even Odd Even Odd

O OO OOO OOOO OOOOO OOOOI OOOOOIO OOOOOIOI

The built-in Mathematica function PowerMod[ ], which computes integral powers of an integer modulo an integer, is based on this method. OIPowerModsTable[ ] shows intermediate steps in the calculation of PowerMod[ ]. In[3]:= OIPowerModsTable[3,160,17] OOOOOIOI 3 OOOOOIO 9 OOOOOI 5 OOOOO 8 Out[3]= OOOO 13 OOO 16 OO 1 O 1 Usage Messages OIPowerModsTable OIPowerModsTable[x,n,m], where x, n and m are integers, produces a table showing the intermediate steps in the calculation of xn modulo m. OISequence OISequence[n], where n is an integer, is the list of O’s and I’s obtained by repeated application of the operation of dividing by 2 and dropping remainder. OISequenceTable OISequence[n], where n is an integer, produces a table showing the intermediate steps in the calculation of the list of O’s and I’s obtained by repeated application of the operation of dividing by 2 and dropping remainder.

146

Orbits Prerequisites Group Actions Input Files /home/courses/B70/orbit.m Mathematical Discussion ∗

If a is relatively prime to n, then a is in the group of units modulo n, ( /n ) . Multiplication by a gives an automorphism of /n . So the subgroup generated by a ∗ in ( /n ) acts on /n by multiplication. Mathematica Functions Orbit[a,k,n] gives the orbit of k under the action on /n described above. Warning: This function will go into an infinite loop if a is not relatively prime to n. Usage Messages Orbit Orbit[a,k,n], where a, k, and n are integers with a relatively prime to n, gives the orbit of k under the action of multiplicative by powers of a.

147

Egyptian Fractions Input Files /home/courses/B70/egyptian.m Mathematical Discussion Let x be a positive real number such that 0 ≤ x ≤ 1. If x = 0, set f1 equal to 0. If x > 0, then by the Archimedean property of the real numbers, there exists an integer d such that 1/d ≤ x. Let d1 be the largest such integer and set f1 = 1/d1 . We call f1 the first Egyptian fraction approximation to x. By applying the same procedure to the error term, x−f1 , which is greater than or equal to 0 by construction, we produce an Egyptian fraction approximation f2 to x − f1 . We call f1 + f2 the second Egyptian fraction approximation to x. Continuing, we construct the nth Egyptian fraction approximation f1 + f2 + . . . + fn to x by setting fn to be the first Egyptian fraction approximation to x − (f1 + . . . + fn−1 ). If f = 1/d is the first Egyptian fraction approximation to y, then 1/d ≤ y < 1/(d − 1), so the error, r, in the approximation satisfies r = y − 1/d < 1/(d − 1) − 1/d = 1/(d(d − 1)). In particular, if y ≤ 1/k then d ≥ k so r < 1/(k(k − 1)). It follows that the error term in the nth approximation is bounded by the nth term of the sequence 1/2, 1/6, 1/42, 1/(42.43), 1/(42.43)(42.43 + 1), . . . . Thus the sequence of Egyptian fraction approximations to x converges (quite quickly) to x. Mathematica Functions For a real number x such that 0 ≤ x ≤ 1, and a positive integer n, Egypt[x,n] returns a list {f1 , f2 , . . . , fn , r} where f1 + f2 . . . + fn is the nth Egyptian fraction approximation to x, and r = x − (f1 + . . . + fn ) is the error term. Usage Messages Egypt Egypt[x,n], where x is a positive integer such that 0 ≤ x ≤ 1, and n is a positive integer, returns a list {f1 , f2 , . . . , fn , r} where f1 + f2 . . . + fn is the nth Egyptian fraction approximation to x, and r = x − (f1 + . . . + fn ) is the error term.

148

Carmichael Numbers Input Files /home/courses/B70/carmichael.m

Mathematical Discussion A positive integer n is called a Carmichael number if p−1 divides n−1 for all primes p dividing n.

Mathematica Functions CarmichaelList[ ] returns a list of some Carmichael numbers. Usage Messages CarmichaelList CarmichaelList[ ] returns a list of some Carmichael numbers.

149

Graph Theory Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m Mathematical Discussion Let G = (V, E) be a simple directed graph with n vertices. We let V (G) and E(G) denote the vertices and edges of G respectively. G can be represented as an n × n matrix A with  1 if (i, j) ∈ E Aij = . 0 if (i, j) ∈ /E A is called the adjacency matrix of A. For each u ∈ V , the adjacency list of u is {v ∈ V | (u, v) ∈ E}. It is sometimes convenient to regard an undirected graph H as a directed graph, containing for each edge e ∈ E(H) one edge in each direction between the endpoints of e. The adjacency matrix of the resulting graph is symmetric. An algorithm which operates on a graph is said to be efficient if the number of steps required in the worst case is bounded by a polynomial in the number of vertices and edges of the graph. If W is a subset of V , the graph induced by G on W is the graph whose vertex set is W and whose edges are those edges of G which join vertices in W . This is also known as the subgraph of G spanned by W . If E 0 is a subset of E, the graph G − E 0 is the graph whose vertices are the same as those of G, but whose edges are obtained by deleting from E the edges in E 0 . If V 0 is a subset of V , the graph G − V 0 is the graph obtained from G by deleting the vertices in V 0 together with any edge which has at least one of its endpoints in V 0 . If H is a graph with the same vertices as G, then the graph union G ∪ H is the graph with the same set of vertices and whose set of edges is E(G) ∪ E(H). The graph intersection G ∩ H is defined similarly using E(G) ∩ E(H). If H is a graph with the same vertices as G, then the graph difference G − H is defined as the graph whose vertices are the same as those of G, but whose edges are obtained by deleting from E the edges in E(H). In other words, G − H = G − (E ∩ E(H)). If G and H are graphs, the cartesian product G × H of the two graphs is defined as the graph whose vertex set is V (G) × V (H) with an edge joining (g, h) to (g 0 , h0 ) whenever g = g 0 and there is an edge from h to h0 in H or whenever h = h0 and there is an edge from g to g 0 in G. The join G ∗`H of the two graphs is defined as the graph whose vertex set is the disjoint union V (G) V (H), and whose set of edges consists of E(G) ∪ E(H) together with an edge joining each pair of vertices where one is in G and the other in H. The complete graph Kn is the graph with n vertices and an edge between every pair of vertices. The graph complement of G is Kn − G, where n = |V (G)|. A k-partite graph G is one in which the vertices of G can be partitioned into k disjoint sets G1 ,G2 ,. . .,Gk in such a way that there are no edges from v to w if v and w are vertices 150

within the same set Gi . If {r1 , r2 , . . . , rk } is a list of k-positive integers, the complete kpartite graph Kr1 ,...,rk is the graph whose vertices are formed by taking the disjoint union of sets G1 , . . . , Gk , where |Gi | = ri , with an edge from each vertex in Gi to each vertex in Gj whenever i 6= j. Mathematica Functions FromOrderedPairs[E], where E is a list of edges. Each edge is a list of two integers from the set {1, . . . , n} which give the starting vertex of the edge followed by the terminal vertex. Note that FromOrderedPairs[{{1,3}}] describes a graph with 3 vertices, in which vertex 2, which does not appear explicitly in the list of edges, is an isolated vertex. In[1]:= G=FromOrderedPairs[{{1,2},{1,3}}] Out[1]= Graph[{{Nil, 1, 1}, {Nil, Nil, Nil}, {Nil, Nil, Nil}}, {{−0.5, 0.866025}, {−0.5, −0.866025}, {1., 0}}] The output begins with a slightly modified form of of the adjacency matrix in which Nil is used rather than 0 to indicate “no edge”; the remainder is information used to draw the graph. Usually you will not want to see this output, and will enter instead: In[2]:= G=FromOrderedPairs[{{1,2},{1,3}}]; To see a picture of your graph use ShowGraph[ ]. In[3]:= ShowGraph[G]; By default, ShowGraph[ ] will use the numbers {1, . . . , n} to label the vertices. If you wish, you can supply a second parameter giving a list of n labels to be used instead. In[4]:= ShowGraph[G,{A,B,C}] FromUnorderedPairs[ ], using the same syntax as FromOrderedPairs[ ], except that the order in which the vertices are listed within each edge is not significant. or FromUnorderedTriples[ ] where each edge is given as a triple, the third element being the weight. In[5]:= G=FromUnorderedTriples[{{1,2,7},{1,3,5}}]; ShowGraph[ ] can be used with any of these four types of graphs: directed or undirected; weighted or unweighted. It adjusts automatically to the type of graph being displayed, showing vertices in red and weights in black. For a large graph, particularly a directed graph in which some edges are drawn as arcs to allow for edges in each direction, weights and point labels might overlap visually, and it might be difficult to distinguish some of the edges. In such cases you may get more information by examining the graph’s adjacency list or edge data. Given a graph G, you can recover the edge data with ToOrderedPairs[ ], ToUnorderedPairs[ ], ToOrderedTriples[ ], or ToUnorderedTriples[ ], depending on the type of graph. Edges[G] returns the modified adjacency matrix of G, with “Nil” representing “no edge”. For a weighted graph, the ij entry will be the weight of the edge from the ith vertex to the jth. Thus we can 151

GraphJoin GraphJoin[g,h] constructs the join of graphs g and h. GraphProduct GraphProduct[g,h] constructs the product of graphs g and h. GraphUnion GraphUnion[g,h] constructs the union of graphs g and h. GraphUnion[n,g] constructs n copies of graph g, where n is an integer. GridGraph GridGraph[n.m] constructs an n ∗ m grid graph, the product of paths on n and m vertices. InduceSubgraph InduceSubgraph[g,s] constructs the subgraph of graph g induced by the list of vertices s. K K[n] creates a complete graph on n vertices. K[r1,r2,r3,...,rk] creates a complete k-partite graph of the prescribed shape. M M[g] gives the number of edges in graph g. MakeUndirected MakeUndirected[g] returns a graph with an undirected edge for each directed edge of graph g. Path Path[n]constructs a tree consisting only of a path on n vertices. RandomGraph RandomGraph[n,p,{l,h}] constructs a random labelled graph on n vertices with an edge probability of p and edge weights of integers drawn uniformly at random from the range (l, h). RandomGraph[n,p,{l,h},Directed] similarly constructs a random directed graph. ShowGraph ShowGraph[graph] generates and displays a graph, with labels on the edges if the graph is weighted. Straight lines will be used for edges if the graph is undirected; arcs with arrowheads will be used if the graph is directed. ShowGraph[graph,labels] allows for the specification of labels for the vertices. Star Star[n] constructs a star on n vertices, which is a tree with one vertex of degree n−1. ToAdjacencyLists[g] ToAdjacencyLists[g]constructs an adjacency list representation for graph g. 154

ToOrderedPairs[g] ToOrderedPairs[g] constructs a list of ordered pairs representing the edges of undirected graph g. ToOrderedTriples[g] ToOrderedTriples[g] constructs a list of ordered triples representing the edges of directed weighted graph g. ToUnorderedPairs[g] ToUnorderedPairs[g] constructs a list of vertex pairs representing graph g, with one pair per undirected edge. ToUnorderedTriples[g] ToUnorderedTriples[g] constructs a list of vertex triples representing weighted graph g, with one triple per undirected edge. V V[g] gives the order or number of vertices of graph g. Wheel Wheel[n] constructs a wheel on n vertices; this is the join of K[1] and Cycle[n-1].

155

Shortest Paths Prerequisites Graph Theory Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/allpairs.m Mathematical Discussion Let G = (V, E) be a positively weighted directed graph, and let u belong to V . If we think of the weights as representing distances between the vertices, Dijkstra’s Algorithm is an efficient algorithm for finding the shortest path from u to v for each v ∈ V . Let w(x, y) denote the weight of the edge from x to y, using the minimum if there is more than one such edge and ∞ if there is no edge. Edges with infinite weight will never be selected by the algorithm as part of our minimum length path, but it is convenient to regard G as a complete simple graph in this way. The algorithm proceeds by expanding a set of vertices, S, while maintaining a function P (v) on the vertices of G in such a way that P (v) always gives the shortest path from u to v which passes only through vertices in S. Let L(v) be the length of P (v); that is, the sum of the weights of the edges in P (v). Initially set S equal to {u} with P (v) = {(u, v)}. At each stage, add to S a vertex v ∈ V −S for which L(v) is minimum, and then for each v 0 ∈ V − S, replace P (v 0 ) by {(v 0 , v)} ∪ P (v) whenever L(v) + w(v, v 0 ) < L(v 0 ). In this manner, P (v 0 ) is adjusted whenever the addition of v to S creates a shorter path from v 0 through points of S. Because v is always chosen with L(v) minimum, P (v) always gives a minimum length path from u to v for all v ∈ S. The algorithm concludes when S equals T , at which point P (v) gives a minimum length path from v to u for each v ∈ V . If G is an unweighted graph then by the length of a path in G we mean the number of edges the path contains. In this case, if A is the adjacency matrix of G, then the ij entry of Ak gives the number of paths (not necessarily simple paths) from i to j. This is because a path of length k − 1 from i to P s will give rise to a path of length k from i to j if Asj = 1 and n k−1 not if Asj = 0. Since Akij = s=1 Ak−1 represents is Asj , assuming by induction that Ais k the number of paths of length k − 1 from i to s, Aij represents the number of paths of length k from i to j. Mathematica Functions Dijkstra[G,u] returns a pair {p, l} of lists. The list p describes the shortest path in the graph G from each vertex to u; the list l gives the lengths of these paths. 156

In[1]:= G=FromOrderedTriples[{{1,2,1},{1,3,3},{1,5,6}, {2,3,1},{2,4,3}, {3,1,1},{3,2,2},{3,4,1}, {4,1,3},{4,5,2},{5,4,1}}]; In[2]:= Dijkstra[G,2] Out[2]= {{3, 2, 2, 3, 4}, {2, 0, 1, 2, 4}} The output is interpreted as follows. In the second list, l, the jth entry gives the minimum distance from vertex j to u. In the first list, p, the jth entry gives the next vertex along the shortest path from j to u. Thus the shortest path from vertex 5 to 2 has length 4 and begins by going from 5 to 4. It then proceeds to 3 and from there to 2. The second parameter can be a list of vertices, in which case the output will AllPairsShortestPath[g] returns a matrix whose ij entry is the length of the shortest path in g from vertex i to j. To use the method of taking the kth power of the adjacency matrix to find the number of paths of length k between vertices in an unweighted graph, you must first convert the adjacency matrix back to standard form by replacing “N il” by “0”. In[3]:= H=FromOrderedPairs[{{1,2},{1,3}}] Compare In[4]:= Edges[H] Out[4]= {{Nil, 1, Nil}, {Nil, Nil, 1}, {Nil, Nil, Nil}} with In[5]:= Edges[H]/.Nil→0 Out[5]= {{0, 1, 0}, {0, 0, 1}, {0, 0, 0}} Usage Messages AllPairsShortestPath AllPairsShortestPath[g] returns a matrix, where the (i, j) entry is the length of the shortest path in g between vertices i and j. Dijkstra Dijkstra[g,v] returns the shortest path spanning tree and associated distances from vertex v of graph g. Exercises 1. Two people have an 8 liter jug of wine which they wish to divide equally between them. They have an empty 5 liter jug and an empty 3 liter jug, but have no means of measuring volume other than by pouring back and forth between the various jugs. We wish to find the minimum number of pourings required to divide the wine equally. (In the final configuration, the two large jugs will contain 4 liters of wine and the other will be empty.) There are 24 triples of non-negative integers which add to 8 and for which the 2nd and 3rd numbers are less than or equal to 5 and 3 respectively. 1. (8,0,0) 9. (5,1,2) 17. (3,3,2) 157

2. 3. 4. 5. 6. 7. 8.

(7,1,0) (7,0,1) (6,2,0) (6,1,1) (6,0,2) (5,3,0) (5,2,1)

10. 11. 12. 13. 14. 15. 16.

(5,0,3) (4,4,0) (4,3,1) (4,2,2) (4,1,3) (3,5,0) (3,4,1)

18. 19. 20. 21. 22. 23. 24.

(3,2,3) (2,5,1) (2,4,2) (2,3,3) (1,5,2) (1,4,3) (0,5,3)

Consider the graph {{1, 10}, {1, 15}, {2, 1}, {2, 3}, {2, 14}, {2, 15}, {3, 1}, {3, 2}, {3, 10}, {3, 19}, {4, 1}, {4, 6}, {4, 15}, {4, 18}, {5, 2}, {5, 3}, {5, 4}, {5, 6}, {5, 14}, {5, 19}, {6, 1}, {6, 4}, {6, 10}, {6, 22}, {7, 1}, {7, 10}, {7, 15}, {7, 21}, {8, 3}, {8, 4}, {8, 7}, {8, 10}, {8, 18}, {8, 19}, {9, 2}, {9, 6}, {9, 7}, {9, 10}, {9, 14}, {9, 22}, {10, 1}, {10, 7}, {10, 24}, {11, 1}, {11, 14}, {11, 15}, {11, 23}, {12, 3}, {12, 7}, {12, 11}, {12, 14}, {12, 19}, {12, 21}, {13, 4}, {13, 6}, {13, 11}, {13, 14}, {13, 18}, {13, 22}, {14, 2}, {14, 10}, {14, 11}, {14, 24}, {15, 1}, {15, 18}, {15, 24}, {16, 3}, {16, 11}, {16, 15}, {16, 18}, {16, 19}, {16, 23}, {17, 6}, {17, 7}, {17, 15}, {17, 18}, {17, 21}, {17, 22}, {18, 4}, {18, 10}, {18, 15}, {18, 24}, {19, 3}, {19, 15}, {19, 21}, {19, 24}, {20, 6}, {20, 11}, {20, 19}, {20, 21}, {20, 22}, {20, 23}, {21, 7}, {21, 10}, {21, 19}, {21, 24}, {22, 6}, {22, 15}, {22, 23}, {22, 24}, {23, 10}, {23, 11}, {23, 22}, {23, 24}, {24, 10}, {24, 15}} Explain the significance of this graph in this problem in use it to help solve the problem.

158

Depth First Search Prerequisites Graph Theory Input Files Graphics/Animation.m Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/dfs.m Mathematical Discussion A subgraph H of G is said to be a spanning subgraph if it contains all the vertices of G. A tree is a connected graph which contains no circuits. A forest is a union of trees. Let G = (V, E) be a simple directed graph. Depth first search is a method of ordering the vertices of G in a manner which is useful in many algorithms. In addition to the ordering of the vertices, it produces a tree which provides a classification of the edges of G. We begin by choosing a vertex u ∈ V and assigning 1 as its depth first index. We also initialize CV , the “current vertex”, to be u and initialize a tree T as {u}. As we proceed, we add edges to T in such a way that it remains a tree rooted at u and contains every vertex whose depth first index has already been assigned. If v is the current vertex, choose the next CV arbitrarily from among those vertices in the adjacency list A(v) whose depth first index has not yet been assigned, if any such vertices exist. If none exist, then set CV to be v’s parent in the tree T . Each time CV becomes a vertex whose depth first index has not previously been assigned, set the depth first index of that vertex to the next unused integer, and add the edge from the previous CV to the new CV to T . The search concludes when the current vertex returns to u after all vertices in A(u) have been visited. At this point, every vertex which is reachable from u will have been assigned a depth first index. If this does not exhaust V , a new vertex whose depth first index has not been assigned can be chosen and the search continued with a new tree rooted at this vertex. This procedure can be repeated until every vertex in V has been assigned a depth first index. The union of all the directed trees produced forms a spanning forest. The depth first indices and forest produced depend not only on G, but also upon the choices made when picking elements from the adjacency lists, and when beginning a new search. The spanning forest F partitions the edges of G into four types: (a) tree edges (those in F itself); (b) back edges (edges from a vertex to one of its ancestors in the tree of F containing it); (c) forward edges (edges from a vertex to one of its descendents in the tree of F containing it); 159

(d) cross edges (none of the above); Depth first search can also be applied to undirected graphs. In this case only tree edges and back edges are produced. Now let G = (V, E) be a connected undirected graph. Any v ∈ V having the property that G − v is disconnected is called an articulation point. A graph is called n-connected if it cannot be disconnected by the removal of n − 1 (or fewer) vertices. A 2-connected graph is called a block; blocks contain no articulation points. G can be written as a union of those of its subgraphs which are blocks; the blocks meet at articulation points of G. Since, in general, a depth first search beginning at u yields all vertices reachable from u, in the case of an undirected graph it identifies the connected component of the graph containing u. Depth first search can be used to identify blocks and articulation points by maintaining an additional function on vertices, P (v), as the search is conducted. The procedure is based on the fact that a vertex v 6= u is an articulation point if and only if it has a child x which would become disconnected from u by the removal of v. The function P (v) which records this information is as follows. When v first is assigned its depth first index DF I(v), initialize P (v) to be min({DF I(v)} ∪ {DF I(w)}) where the union is taken over all w ∈ A(v), excluding the parent of v, such that DF I(w) has already been assigned. Then, every time CV returns to v from some vertex x, set the value of P (v) to min(P (v), P (x)). The idea is that P (v) always gives the depth first index of some vertex which is reachable from v without following any tree edges in the direction from child to parent; i.e. by following only a combination of tree edges in the direction away from the root, or following back edges. When CV returns to v from some vertex x, if P (x) ≥ DF I(v) it means that without v the vertex x would have no path back to any vertex above v in the tree, and so v is an articulation point. By maintaining a stack to which we add edges as they are explored, we can identify the elements in the block containing x by popping the stack down to (v, x). This works, since the block consists of (v, x) together with all edges added after it, minus those which were previously popped from the stack as other blocks were identified. Depth first search can also be used to identify strongly connected components in a directed graph by maintaining a slightly different function Q(v) on the vertices. When v is first assigned its depth first index DF I(v), initialize Q(v) to be min({DF I(v)}∪{DF I(w)}, where the union is taken over all w ∈ A(v) such that DF I(w) has already been assigned, and w is not part of a previously detected strongly connected component. Then every time CV returns to v from some vertex x, set the value of Q(v) to min(Q(v), Q(x)). When we have completed searching the adjacency list of v, if Q(v) = DF I(v) it means that there is no way back from v to any vertex visited prior to v, and so the strongly connected component containing v lies entirely in the piece of the tree lying under v. After all previously detected strongly connected components have been deleted, any remaining vertex in the piece of the tree lying under v must have a path back to v. Therefore those vertices which remain in this subtree form the strongly connected component containing v. This algorithm uses a stack in a manner similar to the preceding one to identify the elements in a component, each time one is detected. This time vertices, rather than edges, are placed on the stack as they are first visited. In addition, the algorithm maintains a function on vertices, STACKED(v), which records whether or not v is on the stack. 160

This is used to identify which vertices are part of a previously detected strongly connected component. If v has already been assigned a depth first index and STACKED(v) = False, then v is in a previously detected component. Mathematica Functions DepthFirstSearch[g,v] allows you to single-step through the depth first search of the graph g beginning from the vertex v. DFSB[g] and DFSSCC[g] allow you to singlestep through, respectively, the depth first search for blocks of an undirected graph g, and the depth first search for strongly connected components of a directed graph g. All of the functions in the graph theory section which allow you to single-step through an algorithm present a menu containing the following options: • • • • • • •

quit (q); Mathematica command (!command); continue one step (1); continue n steps (Integer n); continue until completed (c); show configuration, data only (d); show configuration, data plus graphics (g).

Any response other than the ones listed in the menu will be ignored, and the menu will be presented again. Entering a positive integer n causes the next n steps of the algorithm to be executed, while entering “c” causes the algorithm to proceed to completion. The definition of a “step” varies from one algorithm to another in a way that you are likely to find intuitive. Entering “d” or “g” causes the present state of certain variables in the algorithm to be displayed; the “g” option also presents this information graphically. The data and graphics displayed varies from one algorithm to another, and are described in detail for each algorithm in the section describing that algorithm. You can use the “!command” option to execute any mathematica command from within the program. For example, if you enter !2 + 3, the program will respond with 5. This option is intended to allow you to examine the value of variables other than those given in the response to “d”. However, since the response to “d” displays all the variables in which you are likely to be interested, it is unlikely that you will want to use this option very often. In fact, you would have to examine the source code to find the names of any other variables you might wish to display. Note that the name of a variable in the source code is not always the same as its label in the output of “d”. Another possible use for this option is to change the value of one of the variables “on the fly” to explore other possibilities. Of course, algorithms are not designed with the idea that people might make random changes in the values of their variables in the middle of execution, so exercising this option in this way could lead to unpredictable results. Finally, entering “q” exits from the trace of the algorithm. If DepthFirstSearch[ ] is executed on an undirected graph, “d” displays the following information: 161

• STATE • Current node • VISITED • Depth First Search numbers • ANCESTORS

• DESCENDANTS

either “searching” or “finished”. the current vertex. the list of nodes which have previously been the current vertex. a list. The ith entry is the depth first index of vertex i where the depth first index of an unvisited vertex is listed as 0. a list. The ith entry is a list of those vertices which are ancestors of vertex i in the tree being constructed by the depth first search. a list. The ith entry is a list of those vertices which are descendants of vertex i in the tree being constructed by the depth first search.

• Tree edges • Back edges For a directed graph, the following are also displayed: • Cross edges • Forward edges Tree edges, Back edges, Cross edges, and Forward edges are lists of those edges of the specified type among the edges explored so far. The information from VISITED can also be obtained from Depth First Search numbers. The legend for the display produced by “g” is as follows: visited vertices and tree edges are drawn in red; back edges are drawn in cyan; cross edges are drawn in orchid; forward edges are drawn in green; unvisited vertices and unexplored edges are drawn in black. For DFSB[ ], “d” displays the following information: • STATE • Current node • VISITED • Depth First Search numbers •P • PARENTS • Edges stacked • Blocks found

a list whose ith entry is P (i). a list whose ith entry is the parent of vertex i in the tree being constructed. a list of edges on the stack; used to produce the elements of a block every time one is identified. a list of the blocks already identified. A block is displayed as a list of edges.

STATE, Current node, VISITED, and Depth First Search numbers are as in DepthFirstSearch[ ]. 162

In the display produced by “g”, blocks found so far are coloured so that all the edges of a given block are in the same colour. Edges not yet assigned to blocks are drawn in black. Visited vertices are drawn in red; unvisited vertices are drawn in black. For DFSSCC[ ], “d” displays the following information: • STATE • Current node • Depth First Search numbers •Q • PARENTS • Vertices stacked • Components found • STACKED

a list whose ith entry is Q(i). the list of vertices currently on the stack. the list of components already identified. A component is displayed as a list of vertices. a list giving the function STACKED(v). Each each entry is either True or False.

STATE, Current node,VISITED,Depth First Search numbers, and PARENTS are as in DFSB[ ]. The information from STACKED can also be obtained from Vertices visited. In the display produced by “g”, components found so far are coloured so that all the vertices of a given component are in the same colour. Unassigned vertices are drawn in black; tree edges are drawn in red. For a graph g and vertex v ∈ V (g), DFSAnimation[g,v] gives an animation of the depth first search of g beginning from v; each frame shows the next step in the execution of the algorithm. Usage Messages DepthFirstSearch DepthFirstSearch[g,v]traces the depth first search algorithm on graph g starting from vertex v. DFSAnimation DFSAnimation[g,v] produces an animation of a depth-first traversal of graph g starting from vertex v. DFSB DFSB[g] traces the depth first search for blocks on undirected graph g. DFSSCC DFSSCC[g] traces the depth first search for strongly connected components on directed graph g.

163

Branchings Prerequisites Graph Theory Depth First Search Input Files Graphics/Animation.m Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/edmonds.m Mathematical Discussion An out-tree is a rooted directed tree in which there is a (directed) path from the root to every other vertex. A branching is a directed forest in which each (weak) component is an out-tree. Equivalently, a directed forest is a branching if and only if it has at most one edge entering each vertex. Let G = (V, E) be a weighted directed graph. Edmonds’ algorithm provides an efficient method of finding a branching B such that the sum of the weights of the edges in B is maximum. Using the second description of branching above, it tries to construct the desired branching B by examining the vertices of G, and for each vertex v which is the endpoint of at least one edge of positive weight, adding to B the edge of maximum weight among those entering v. Adjustments must be made, however, in the event that such a choice would result in a circuit. Since the problem of determining which adjustment to make in such a case is a global problem, not a local one, circuits are collapsed as they are detected in a manner which allows the decision to be postponed until a later stage. The algorithm has two phases: a collapsing phase and a reconstructing phase. The collapsing phase proceeds as follows. Initialize a set BV of vertices and a set BE of edges to be empty. During each step, select a vertex v which is not in BV and add it to BV . If v is not the endpoint of any edge having positive weight, proceed to the next vertex. Otherwise, let e be the edge of maximum weight among those entering v. If the addition of e to BE does not complete a circuit then add e to BE and proceed to the next vertex. Otherwise, form a new graph by collapsing to a point the circuit contained in BE ∪ {e}. That is, replace the vertices and edges within the circuit by a single vertex u, where the edges between u and any another vertex x are in 1 − 1 correspondence with the edges between vertices in the circuit and x. Do not add the new vertex or the edges beginning or ending at it to BV or BE (although they may be placed there later as the algorithm proceeds). Assign weights of edges which either begin at u or are not incident to u to be the same in the new graph as their counterparts in the previous graph. For edges of the form (x, u), assign the weight 164

w(x, u) = w(x, y) + w(emin ) − w(ey ), where (x, y) is the edge in the previous graph which gave rise to (x, u), emin is the edge of minimum weight in the circuit, and ey is the edge in the circuit which ends at y. Proceed until all vertices are in BV . The formula for the weight of edges of the form (x, u) is can be explained by considering the following example: FromOrderedTriples[{{1,2,2},{2,3,4},{3,1,5}, {4,3,γ}]. Compare case1 where we let γ = 1 to case2 where γ = 3. In case1 the maximum weight branching is {(2, 3), (3, 1)}, while in case2 it is {(4, 3), (3, 1), (1, 2)}. In each case, after (3, 1) and (1, 2) have been added to BE , the edge (2, 3) is explored and discovered to complete a circuit. At this point it cannot be determined which edges from the circuit will form part of the maximum weight branching, since that depends on the weight of the edge (4, 3) which has not yet been explored, so the decision is postponed by collapsing the circuit. The formula for the assignment of the weight of the edge (4, u) in the collapsed graph causes it to be negative in case1 and positive in case2. The algorithm will then proceed to add the edge (4, u) to BE in case2 but not in case1, thus allowing it to distinguish between the two cases. During the reconstruction phase, expand the collapsed circuits (which may in turn contain other collapsed circuits) in the reverse order to that in which they were collapsed. When expanding the vertex u to reproduce the circuit which gave rise to it, add to BE all edges but one in the newly expanded circuit. Omit the edge emin in the case where there was no edge in BE ending at u. In the case where there was an edge (x, u) in BE , omit the edge ey , where (x, y) is the edge which gave rise to (x, u). In the graph obtained at the completion of the collapsing phase, it is clear that the edges of that graph which are in BE form a maximum weight branching for it, since in that graph we were able to make the optimal choice at each vertex without creating any circuits. To complete the proof that this algorithm produces a maximum weight branching, use induction to check that as each circuit is expanded, the edges of the resulting graph which are placed in BE by the reconstruction process form a maximal weight branching for that graph. Mathematica Functions Edmonds[g] allows you to single-step through the application of Edmonds algorithm to the graph g. For Edmonds[ ] , “d” displays the following information: • • • • •

STATE BE BV Vi Sum of weights of BE •i

one of “collapsing”, “reconstructing”, or “finished”. the list of edges in the current graph which are in BE . the list of vertices in the current graph which are in BV . the list of vertices in the current graph. the sum of the weights of those edges in the current graph which are in BE . the number of circuit collapses which were made to produce the graph currently under consideration. The initial graph is G0 and other graphs are labelled Gi as they are produced. 165

Note that Sum of weights of BE is relevant only for the current graph; the sum goes down when a collapse occurs since the sum no longer includes weights of edges in the collapsed circuit. “g” displays the current graph. Usage Messages Edmonds[g] Edmonds[g] provides interactive trace of Edmond’s algorithm on graph g.

166

Spanning Trees Pre-requisites Graph Theory Depth First Search

Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/prims.m /home/courses/C32/kruskals.m Mathematical Discussion Let G = (V, E) be a positively weighted connected simple undirected graph. We wish to choose edges which connect all the vertices in such a way that the sum of the weights of the chosen edges is minimal. The set of edges chosen will always be a tree, since otherwise there would be unneeded edges which could be dropped. Thus we wish to find a minimum weight spanning tree. One efficient algorithm for doing this is Prim’s algorithm described as follows. Let w(e) be the weight of e ∈ E. To begin, choose any vertex in V and initialize the tree T as the empty set. If W is the set of vertices chosen so far and W 0 = V − W , then in each step of the algorithm choose an edge e = (v, v 0 ) where v ∈ W , v 0 ∈ W 0 , such that w(e) is minimum among edges joining vertices in W to vertices in W 0 . Then add v 0 to W and add e to T . Another algorithm for producing minimum weight spanning trees is Kruskal’s algorithm. Kruskal’s algorithm forms a set S of edges by adjoining to S, at each stage, the edge of least weight whose addition to S does not produce a cycle. The proofs that these algorithms work are similar. In each case, one begins with a minimum weight spanning tree TM , and shows that because of the way the edges are chosen in the algorithm, it must be possible to replace edges from TM by edges of equal weight chosen by the algorithm. In this way one gradually modifies TM without affecting the total weight, until it becomes the tree found by the algorithm. Thus the tree found by the algorithm also has minimum weight. Mathematica Functions Prims[g,v] allows you to single-step through the application of Prim’s algorithm to the graph g beginning from the vertex v. v can be omitted, in which case a starting vertex will be chosen randomly. You will be presented with the menu described in the section “Depth First Search”. 167

For Prims[ ] , “d” displays the following information: • • • • •

STATE Start node VISITED UNVISITED L

• Tree edges

the set W . the set W 0 . a list representing a function on V whose value on each vertex gives the minimum distance from that vertex to some vertex in W the list of edges in the tree constructed so far.

It is convenient to maintain the function L, adjusting it each time an element is added to W , to facilitate the choice of the next tree edge. In the display produced by “g”, vertices in W and tree edges are drawn in red, with remaining vertices and edges in black. Kruskals[g] allows you to single-step through the application of Kruskal’s algorithm to the graph g. For Kruskals[ ] , “d” displays the following information. • STATE • MWT • Current edge

the set of edges chosen so far.

There is no graphics option for this function. Usage Messages Kruskals[g] Kruskals[g] traces Kruskal’s algorithm on graph g. Prims Prims[g] traces Prim’s algorithm on graph g using a random start vertex. Prims[g,s] uses start vertex s.

168

Planarity Pre-requisites Graph Theory Depth First Search

Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/planarity.m Mathematical Discussion A graph is called planar if it is isomorphic to a graph in 2 in which no edges cross. A planar embedding of a subgraph H of G is called G-admissible if it can be extended to a planar embedding of G. Even if G is planar, it may be that a given planar embedding of H is inadmissible. A subgraph B of G is called a bridge of G relative to H if either: a) B = (u, v) for some edge (u, v) such that u, v ∈ V (H) but (u, v) ∈ / E(H) or b) B has at least two “points of contact” and B is a connected component of G − H together with all edges from vertices in H to ones in G. (A point of contact is a vertex of B ∪ H.) If B is a bridge relative to H, then a planar embedding of H can be extended to a planar embedding of H ∪ B if and only if there exists a face of H containing all points of contact of B. There can be at most two such faces. Let G be a graph. Since a graph is planar if and only if each of its blocks is planar, to determine whether or not G is planar it suffices to consider the case where G is a block. We may also assume that G is simple, since self-loops and parallel edges can always be added to a planar graph without disturbing planarity. Beginning with some circuit G0 contained in G, (which exists since G is a block), we describe a procedure for adding the edges of G in a planar fashion in such a way that an impasse will be reached if and only if G is non-planar. Let Gj be the embedding already constructed of some subgraph of G. Assuming Gj 6= G, since G is a block it will have at least one bridge relative to Gj . If G has at least one bridge relative to Gj which is embeddable in a unique face of Gj , then choose such a bridge and embed it to form Gj+1 . If every bridge of G relative to Gj can be embedded in two faces, then choose any bridge and embed it in one of those faces to form Gj+1 . Continue until a planar embedding of G has been constructed. If at any stage a bridge is encountered which cannot be embedded in any face, then G is non-planar. 169

The algorithm depends upon making all “forced moves” before those in which there is a choice. If, instead, some bridges which can be placed in either of two faces are embedded ahead of bridges embeddable in only one face, it is possible that an inadmissible embedding Gj+1 may be reached, even though G is in fact planar. Mathematica Functions PlanarTrace[G] allows you to single-step through the planarity-testing algorithm on the block G. In this implementation of the algorithm, during each step, a bridge is chosen as described above, but the entire bridge is not necessarily embedded during the step. Instead, a path in the bridge from one point of contact of the bridge to another is selected, and that path is added to the embedded subgraph. For PlanarTrace[ ] , “d” displays the following information. • STATE • graph • embedded

• faces • bridge

• path • bridges

one of “in progress”, “embeddable”, or “not embeddable”. the list of edges in the graph being tested. the list of edges in the subgraph which has been embedded so far. Before any steps are executed, it is initialized as some circuit in the graph. the list of faces. Each face is a list which gives the vertices in the boundary of that face. the chosen bridge from which a path joining one point of contact to another will be selected for embedding. It is given as a list of edges. the path which is about to be added to the embedded subgraph. a list of all bridges of the original graph relative to the graph obtained by adding path to the embedded subgraph. During the next step, one of these bridges will be chosen as bridge.

The legend for the display produced by “g” is as follows: The edges of the subgraph embedded before the current step are drawn in blue. The edges of the path to be embedded next are drawn in red. The remaining edges of the chosen bridge are drawn in magenta. All other edges are drawn in green. Note that the graphics do not actually show a planar embedding of the embedded subgraph. They merely indicate the order in which edges could be added to give a planar embedding. To produce a planar embedding proceed as follows. Begin by drawing the circuit which consists of the edges shown by “d” or “g” as embedded before any executing any steps. Then as you execute each step, add the edges in path by joining its two endpoints (which should already be on your figure) without crossing any of the previously drawn lines. 170

PlanarQQ[G] indicates whether the undirected graph G is or is not planar by returning True or False. Usage Messages PlanarQQ PlanarQQ[g], indicates whether or not the graph g has a planar embedding. PlanarTrace PlanarTrace[g] allows the user to go through the planarity testing algorithm on the undirected graph g step-by-step using the choices from Menu.

171

Networks Prerequisites Graph Theory Depth First Search Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/networks.m Mathematical Discussion A transport network consists of a simple directed graph together with a pair of selected points known respectively as the source and sink, such that there is at least one directed path from source to sink. A flow for the network N consists P of an assignment of weights to N such that for all vertices other than source and sink, incoming weights = P outgoing weights. A transport network with capacities consists of a network in which each edge e is assigned a capacity c(e) ≥ 0. A feasible flow for a network with capacities is a flow f such that 0 ≤ f (e) ≤ c(e) for all edges e. Let N be a transport network with capacities, with source x and sink y. Given a feasible flow f on N , let f (N ) =

X

f (x, v) −

(x,v)∈E(N )

X

f (v, x).

(v,x)∈E(N )

f (N ) is called the value of the flow f . It represents the net number of items transported from source to sink if f (u, v) items are passed from u to v for each edge (u, v) ∈ E(N ). source and sink, f (N ) is also equal to X

(v,y)∈E(N )

f (v, y) −

X

f (y, v).

(y,v)∈E(N )

(i.e. the net number of items leaving the source equals the net number of items arriving at the sink). We wish to find a feasible flow for which f (N ) is maximum. Let Q = (v0 , v1 , . . . , vk ), where x = v0 and y = vk , be a path from x to y in the underlying undirected graph of N . Thus for each edge (vi , vi+1 ) in Q, either (vi , vi+1 ) belongs to E(N ), called a forward edge, or else (vi+1 , vi ) belongs to E(N ), called a backward edge. Let  c(vi , vi+1 ) − f (vi , vi+1 ) if (vi , vi+1 ) forward ∆(i) = . f (vi+1 , vi ) if (vi , vi+1 ) backward 172

Intuitively, ∆(i) > 0 represents inefficiency in f in the sense of either an edge which is not being used to capacity or an edge which is transporting backwards towards the source. If ∆(i) > 0 ∀i, then Q is called a flow augmenting path and can be used to construct a new feasible flow f 0 which increases f (N ) by setting  if e is not an edge of Q  f (e) f 0 (e) = f (e) + ∆ if e is a forward edge of Q  f (e) − ∆ if e is a backward edge of Q, where ∆ = min{∆(i)}. It is immediate that if f (N ) is maximum, then N has no augmenting paths; it can be checked that, conversely, if N has no augmenting path, then f (N ) is maximum. Given f , define a directed graph N f by V (N f ) = V (N ) and (u, v) ∈ E(N f ) if and only if either (u, v) ∈ E(N ) and c(u, v) − f (u, v) > 0 or else (v, u) ∈ E(N ) and f (v, u) > 0. Then a path from x to y in N f is equivalent to an augmenting path for f in N . Since a search for paths in N f from x to y can be conducted efficiently by any of a number of earlier methods, this provides an efficient method of finding a feasible flow having maximum value. We refer to this maximum value as the “capacity of the network”. Suppose now that N is a transport network with capacities in which there is a number a(e) associated to each edge e representing the cost of transporting one unit along that edge. Given W such that W is not greater than the capacity of the network, we wish to find a feasible P flow f which transports W units at minimum cost. That is, we wish to find f such that f (u, v)a(u, v) is minimum. To construct such an f we search at each stage for the cheapest augmenting path. We begin with the feasible flow f (u, v) = 0 for all (u, v). Initialize a function π(u) on V (N ) by π(u) = 0 for all u ∈ V (N ). At each stage, we search for paths of cost π(y) in the graph consisting of {(u, v) | π(v) − π(u) = a(u, v)}. Thus we begin by looking for paths with zero cost. The search is conducted by means of a labelling operation which proceeds as follows. Begin by labelling the source x. If p has been already labelled, then for each edge (p, q), label q if either π(q) − π(p) = a(p, q) and f (p, q) < c(p, q) or else π(p) − π(q) = a(q, p) and f (q, p) > 0). Continue labelling until no more vertices can be labelled. This effectively implements a breadth first search over the subgraph of N f for which {(u, v) | π(v) − π(u) = a(u, v)}. If a vertex u gets labelled in this procedure, it means that there exists an augmenting path from x to u having cost π(u). Thus, if y becomes labelled, we augment using such a path, remove all labels, and (assuming f (N ) still less than W ) search again. However if y does not get labelled, then there is no augmenting path of cost π(y). In this case, we increment π(v) by 1 for all unlabelled v and continue the search with the new values of π. 173

Mathematica Functions Let N be a transport network with capacities and let f be a feasible flow {{{u1 , v1 }, f1 , c1 }, {{u2 , v2 }, f2 , c2 }, . . . , {{uk , vk }, fk , ck }}, where fj and cj are the flow and capacity for the jth edge (uj , vj ). Vertex 1 will be interpreted as the source, and the highest numbered vertex will be interpreted as the sink. If g is such a list, MaxFlow[g] allows you to single-step through the algorithm which searches for augmenting paths, beginning from the given flow, until a flow with maximum value is reached. For MaxFlow[ ] , “d” displays the following information: • graph • Initial flow parameters • Maximum capacity parameters • Current flow parameters • Current total flow from source

the list of the edges in the network. a list giving the initial flow for each edge. a list giving the capacity of each edge. a list giving the current flow for each edge. the value of the current flow.

and will not change during the execution of the algorithm. In the variables which are lists, the ith entry gives the value on “g” presents a further menu with the following choices of which graph to display: • • • •

Graph Graph Graph Graph

of of of of

network with current flow numbers shown as weights (c) network with maximum flow numbers shown as weights (m) network with initial flow numbers shown as weights (i) augmenting network for last step executed (a)

Entering “c”, “m”, or “i” displays the graph N using the indicated numbers to label the edges. Entering ”a” displays the graph N cf , where cf is the current flow, with the ith edged labelled with the value of ∆(i). into Mathematica as a list {{{u1 , v1 }, a1 , c1 }, {{u2 , v2 }, a2 , c2 }, . . . , {{uk , vk }, ak , ck }}, where aj and cj are the cost and capacity for the jth edge (uj , vj ). Vertex 1 will be interpreted as the source, and the highest numbered vertex will be interpreted as the sink. If g is such a list, MinCostFlow[g,W] allows you to single-step through the algorithm which finds a minimum cost flow whose value is W , provided that W is not greater than the capacity of the network. If W is greater than the capacity of the network, the function will state this and exit. For MinCostFlow[ ] , “d” displays the following information: • graph

the list of the edges in the network. 174

• Current flow parameters • Maximum capacity parameters • Cost parameters • • Current vertex numbers • vertex labels from last step

a list giving the current flow for each edge. a list giving the capacity of each edge. a list giving the cost associated to each edge. a list giving the current values of the function π(v). a list giving the number of the round on which each vertex was labelled. That is, the labelling process is done in a series of rounds in which the existing labelled vertices are used to produce new labelled vertices. The source is considered to have been labelled on round 0. Unlabelled vertices are indicated with −1.

• Current total flow from source • Current total cost of flow In the variables which are lists, the ith entry gives the value of that variable on the ith edge or ith vertex. The edges are ordered as in No graphics have been implemented for this function. Usage Messages MaxFlow[g] MaxFlow[g] finds the maximum flow possible through the network g. g is given as a list of the form {{{a, b}, c, d}, {{e, f }, g, h}, . . .} in which each triple represents a directed edge of a graph followed by current and maximum-allowed flows along that edge. MinCostFlow MinCostFlow[g, v] finds the flow through the network g which transports v units at minimal cost. g is given as a list of the form {{{a, b}, c, d}, {{e, f }, g, h}, . . .} in which each triple represents a directed edge of a graph followed by the cost of transporting one unit along that edge and the maximum allowed flow along that edge.

175

Matching Prerequisites Graph Theory Depth First Search Input Files Graphics/Animation.m Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/matching.m Mathematical Discussion A matching of an undirected graph G is a subset M of E(G) such that no vertex occurs as an endpoint of more than one edge in M . We refer to a vertex as being matched if it is the endpoint of some edge in M . A perfect matching is a matching M in which every vertex is matched. We wish to find a matching with the maximum possible number of edges. Given a matching M , vertices not occurring as endpoints of edges in M are called free vertices for M . An alternating path for M is a simple path in G in which consecutive edges alternate between being in M and not being in M . An M -augmenting path for M is an alternating path between free vertices. An alternating path P for M can be used to construct a matching M 0 with |M 0 | = |M |+1 by setting M 0 = (M −(M ∩P ))∪((E(G)−M )∩P ). We refer to this as “inverting” along the path P . Conversely, if M 0 is a matching with |M 0 | > |M | then we can construct an M augmenting path for M as follows. Let G0 be the graph with V (G0 ) = V (G) and E(G0 ) = E(M ) ∆ E(M 0 ), where X ∆ Y = X ∪ Y − X ∩ Y , known as the symmetric difference of X and Y . By definition of a matching, each connected component of G0 is an alternating path in G for each both M and M 0 . But since |M 0 | > |M |, at least one component in G0 has more edges from M 0 than from M and that component forms an M -augmenting path for M . Let M be a matching in G and let v be a free vertex for M . We describe an algorithm which will either produce an M -augmenting path beginning at v or show that one does not exist. To keep track of whether paths have even or odd lengths, we use a labelling process in which each vertex is either unlabelled or labelled “inner” or “outer”. As the algorithm proceeds, we construct a tree T such that T contains every vertex which has been labelled and such that every path in T is an alternating path for M . The construction is such that the vertices in every path in T beginning at v alternate “outer”, “inner”, “outer”, 176

“inner”, . . ., where the edges from “inner” to “outer” are in M and those from “outer” to “inner” are not. To begin, label v “outer” with all other vertices unlabelled and initialize T by setting T = {v}. At each stage, pick an edge (x, y) which has not previously been explored and in which x is labelled “outer”. If y is a free vertex then the path from v to x in T followed by (x, y) constitutes an M -augmenting path, and we are done. Therefore assume that y is not free. If y is previously unlabelled, then, letting (y, z) be the edge in M containing y, label y “inner”, z “outer”, and add the edges (x, y) and (y, z) to T . If, instead, y is already labelled as “inner”, an even length circuit has been detected. That is, T ∪ {(x, y)} contains a circuit of even length. In this case, this completes the exploration of the edge (x, y) with no action taken. If, instead, y is already labelled as “outer”, then an odd length circuit has been detected. An odd length circuit provides flexibility, since it yields both an even and an odd length path between any two vertices on the circuit. In order keep all options open, this choice is deferred by collapsing the circuit to a point. A collapsed circuit is called a blossom. In the resulting graph G0 , label the point B which corresponds to the circuit “outer”. Construct an induced matching on G0 by placing an edge incident to B in the matching if one of the edges collapsed to produce it was in M on G. Repeat this procedure until an M -augmenting path has been produced (in some graph produced from the original by collapsing circuits), or until all edges incident to all outer edges in the graph presently under consideration have been explored. If all eligible edges have been explored without an M -augmenting path having been found, then it can be shown that v cannot be part of an M -augmenting path. In fact, no vertex in the tree T including those which are part of collapsed circuits, can be part of any M -augmenting path. T is called a Hungarian tree in this case. If an M -augmenting path is located in some collapsed graph, then there is a corresponding M -augmenting path in the original. To reconstruct this path, expand the circuits in the reverse order to that in which they were collapsed. If (p, B) and (B, q) are part of the M -augmenting path in the collapsed graph, then in the reconstructed graph obtained by expanding B, construct the path by selecting any representative (c, q) for the edge not in the matching in the collapsed graph, while choosing the edge (p, a) in M to correspond to the edge which is in the matching. To complete this to a path, join a to c by following the even length path around the circuit from a to c. In the case where B was an endpoint of the path in the collapsed graph, there is no edge (p, B) and thus no a, but we use v, the root of the search, in its place. Continued application of the above procedure gives an efficient algorithm for finding a matching with the maximum number of edges. Suppose now that G is a weighted graph and that we wish to find a matching M for G such that the total sum of the weights of the edges in M is maximum. Let w(u, v) denote the weight of the edge (u, v). A variation on the procedure above solves this problem. Although the procedure can be modified to work in general, we will consider here only the case of bipartite graphs G. This simplifies the algorithm due to the impossibility of finding odd length circuits, thus eliminating the need to consider collapsing circuits. The problem can be reformulated in terms of linear programming utilizing an auxiliary function y(v) defined on the vertices. The dual linear programming problem is to minimize 177

the sum of the y(u)’s subject to the constraints y(u) + y(v) ≥ w(u, v) for all (u, v) ∈ E(G) and y(u) ≥ 0 for all u ∈ V (G). Under this reformulation, the problem can be formulated as that of finding a matching M and a function y(v) such that the following conditions are satisfied: (i) for each edge (u, v), either (u, v) ∈ / M or else y(u) + y(v) = w(u, v); (ii) for each vertex u either y(u) = 0 or else u is matched. M will then be a solution to the original problem and y will be a solution to the dual problem. In the algorithm that follows, condition (i) will be satisfied by all edges at all times while an increasing number of vertices will be made to satisfy condition (ii). Initially we set y(u) = max{w(u, v)}/2 for all u. Thus condition (i) is initially satisfied for every edge. At each stage, let G0 denote the subgraph whose edges satisfy y(u)+y(v) = w(u, v). Pick a vertex u not yet satisfying condition (ii); that is, a free vertex u with y(u) > 0. Within the graph G0 , conduct the labelling process described in the preceding algorithm beginning from u. If the search yields an M -augmenting path, then inverting in that path adds u to the set of matched edges and thus adds it to the set of vertices satisfying (ii) without destroying that condition at any of the other vertices. Also since the matching was changed only on edges in the graph G0 , condition (i) remains true for all edges. If, instead, the search terminates in a Hungarian tree, modify the values of y as follows. Let δ = min{δ 0 , δ 00 } where δ 0 = min{y(u) | u outer} and δ 00 = min{y(u) + y(v) − w(u, v) | u outer and v unlabelled}. Subtract δ from y(v) for all outer vertices v, and add it to y(v) for all inner vertices y(v). Since we had found a Hungarian tree, this won’t disturb condition (i). However if δ = δ 00 , it will have the effect of adding edges to G0 , while if δ = δ 0 , it will make y(v) = 0 for an outer (thus matched) vertex v. In the first case we can continue the search for an M -augmenting path on our enlarged G0 . In the second case, inverting along the path joining v to u in the tree of labelled vertices causes condition (ii) to become satisfied at u (because it then becomes matched) without destroying that condition at v (since y(v) = 0). Since the graph G0 can be enlarged only finitely many times, eventually condition (ii) becomes satisfied at u. Mathematica Functions Matching[g] allows you to single-step through the application to the graph g of the algorithm for finding a matching with the maximum number of edges. As the algorithm proceeds the graph is altered as circuits are collapsed and as Hungarian trees are removed. These items are saved on a stack, so that the graph, including the augmenting path which has been found, can be reconstructed by popping the stack. For Matching[ ] , “d” displays the following information:

178

• STATE • VLABS

• MATCHING •S •T • PATH • LABELS • GPRIME • INDEX • EDGES

• STACK

• FREE

one of “choose free vertex”, “explore edge”, “popping stack”, or “maximum matching found”. a list containing labels for the vertices in the graph G0 . These are the labels that will appear if the graphics option is selected. Blossoms are labelled b1, b2, . . . , as they are found. The variables described later use the order of the vertices shown in this list. Thus, if one of them refers to the edge {1, 2}, it means the edge in the graph G0 joining the first entry in VLABS to the second. the list of the edges in the matching in the current graph. the list of explored edges in the current graph. the tree spanned by outer and inner vertices constructed so far. a list of vertices. Every time an augmenting path is discovered it is given in PATH as the vertices along that path. a list which describes each vertex in G0 as one of “outer”, “inner”, or “unlabelled”. the current graph G0 . New graphs are numbered as they are produced with the initial graph assigned index 0. the number of the current graph. the edges of the graph G0 ; obtained by applying ToUnorderedPairs[ ] to G0 . This should be a more readable description of the graph G0 than GPRIME. a list describing the stack. Each element is a list whose first element is either the string “tree” or the string “blossom”, and whose second element gives the edges of the tree or blossom. The remaining elements are used for reconstructing the state of the previous graph when the stack is popped; they are probably of interest only to programmers. the list of free vertices in G0 .

“g” displays two graphs: the current graph and its subtree T . Edges in M appear in red, other edges in black. When an augmenting path is found, its matched edges are shown on the graph of the tree in orchid, and its unmatched edges in blue. Outer vertices appear in green, inner vertices in red, unlabelled vertices in gray. MaxWtBMatching[g] allows you to single-step through the application to the weighted bipartite graph g of the algorithm for finding a maximum weight matching. For MaxWtBMatching[ ] , “d” displays the following information:

179

• • • • • • • • •

STATE MATCHING S T PATH LABELS GPRIMEEDGES FREE Y

the list of edges of the graph G0 . a list whose ith entry is the value of the function y on vertex i of G.

STATE, MATCHING, S, T, PATH, LABELS, and FREE are as in the preceding algorithm. There is no graphics option for this algorithm. Usage Messages Matching Matching[g]traces the maximum cardinality matching algorithm on graph g. MaxWtBMatching MaxWtBMatching[g] traces the algorithm for finding the maximum weight matching on a weighted bipartite graph g.

180

Tours Prerequisites Graph Theory Depth First Search Input Files Graphics/Colors.m Graphics/Spline.m /home/courses/C32/graphtheory.m /home/courses/C32/colorize.m /home/courses/C32/planarity.m /home/courses/C32/eulerian.m Mathematical Discussion An Eulerian path is a path which follows each edge exactly once. An Eulerian circuit is an Eulerian path which ends at the starting point. Let G be a connected undirected graph. It is clear that if G has an Eulerian circuit, then G has no odd-degree vertices. Conversely, if G has no odd-degree vertices, then we can produce an Eulerian circuit in G as follows. Begin by choosing any vertex w as the starting point and initialize the “current vertex”, CV , to be w. Suppose by induction that a simple path E has been constructed from w to CV in such a way that the graph G0 obtained by removal of E, plus any vertices this would leave isolated, is connected. So G0 contains a simple path P joining CV to w, beginning with say the edge e0 . If e0 is the only edge in G0 incident to CV , then we can add it to E, since G0 − e will remain connected except for its now isolated vertex CV . If e0 is not the only edge in G0 incident to G, then let e = (CV, v) be any other edge incident to CV and add e to E. CV is still connected to w in G0 − e by means of P . Since the only two vertices of odd degree in G0 − e are v and w, they lie in the same connected component of G0 − e. Thus removal of e has failed to disconnect CV from v and so G0 − e is still connected and the induction is complete. Continuing this procedure eventually traces out an Eulerian circuit in G. Mathematica Functions EulerianTrace[G] allows the user to single-step through the procedure described above for producing an Eulerian circuit in an Eulerian graph G beginning from vertex 1. This function can also be called in the form EulerianTrace[G,v]; in this case vertex v will be used as the starting vertex. If the graph G is not in fact Eulerian, the function will state this and exit. The “d” option for EulerianTrace[ ] shows the path constructed so far. The “g” option displays the graph with the starting vertex in magenta, the current vertex in green, 181

the path constructed so far in red with edges numbered according to their order in the path, and the remainder of the graph in blue. EulerianQ[G] indicates whether the undirected graph G is or is not Eulerian by returning True or False. EulerianQ[G,Directed] is the corresponding function for directed graphs G. Usage Messages EulerianQ EulerianQ[g] returns True if graph g is Eulerian, meaning there exists a tour which includes each edge exactly once. EulerianQ[g,Directed] returns True if directed graph g is Eulerian. EulerianTrace EulerianTrace[g] allows the user to step through the algorithm for finding an Eulerian circuit in the Eulerian graph g.

182

Extension Fields Input Files /home/courses/C49/extensionfields.m Mathematical Discussion The characteristic of a field F is the least positive integer k such that k = 0 in F , where characteristic 0 is conventionally used to denote the case where there is no such k. If the characteristic of F is not 0, then it must be a prime. A field of characteristic 0 always contains the rationals; one of characteristic p for p > 0 contains p . Given an irreducible polynomial f (x) ∈ F [x] of degree n, let K = F [x]/(f (x)), where (f (x)) denotes the principal ideal generated by f (x). Then K is an extension field of K. The classes in K represented by the elements 1, x, x2 , . . ., xn−1 form a basis for K as a vector space over F , so K is a degree n extension of F . Every element of K can thus be represented by a polynomial in F [x] of degree less than n; we refer to this as the standard form of the element. The “theorem of the primitive element” can be interpreted as saying that the fields and p have the property that if F is one of these fields then every finite extension field of F is of the form F [x]/(f (x)) for some irreducible polynomial f (x). The functions below assist with computations in such extension fields. Mathematica Functions To do computations in the extension field K = F [x]/(f (x)), where F equals use CreateField[f,p], where p is the characteristic of F .

or

p,

In[1]:= K=CreateField[x^3+x^2+2,3] F[poly,K] can now be used to put polynomials into their standard form. In particular, this can be used to do arithmetic within the field K. In[2]:= F[(2x^2+1)(x^2+x+2), K] Out[2]= 2x2 + 2 The variable appearing in poly must be the one used in the definition of the field K. Usage Messages CreateField CreateField[f,p] is the field F [x]/(f [x]) where f is a polynomial with integer coefficients and F is p if p > 0 or if p = 0. F F[f,K], where K is an extension field of p or created with CreateField[ ], and f is a polynomial in the variable used to define K, returns the standard form of f as an element of K. 183

Finite Fields Prerequisites Extension Fields Input Files /home/courses/C49/extensionfields.m /home/courses/C49/FiniteFields/finitefields. Mathematical Discussion For each prime p and for each integer m there is a unique (up to isomorphism) field with pm elements. Under multiplication the nonzero elements of a finite field form a group which is always cyclic. A generator for this cyclic group is referred to as a primitive root for the finite field. If the field is p it is often called a primitive pth root of unity. Mathematica Functions Generator[K] returns a primitive root for the finite field K, where K was created with CreateField[ ]. Given a primitive root b for K, JacobiLogarithm[f,K,b] returns the least value of j such that f = bj in K, with “Infinity” used for the logarithm of 0. In[1]:= In[2]:= Out[2]= In[3]:= Out[3]= In[4]:= Out[4]=

K=CreateField[x^3+x^2+2,3] b=Generator[K] 2+x JacobiLogarithm[2x^2+x+1,K,b] 7 F[b^7,K] 2x2 + x + 1

ListElements[K] gives a primitive root and a complete list of the elements in K as powers of that root. Usage Messages JacobiLogarithm JacobiLogarithm[f,K,b], where K is a field, b is a primitive root in K, and f belongs to K, is the least value of j such that f = bj in K. Generator Generator[K], where K is a field, is a primitive root for K. ListElements ListElements[K] gives a primitive root and a complete list of the elements in the field K. 184

Examples 1. Let b be a primitive root for the field K. Knowledge of the Jacobi logarithms of the elements of the form 1 + bj is sufficient to add elements which are written as powers of b as illustrated below. In[1]:= K=CreateField[x^3+x^2+2,3] In[2]:= b=Generator[K] Out[2]= 2 + x To find b3 + b5 as a power of b, write b3 + b5 = b3 (1 + b2 ). In[3]:= JacobiLogarithm[1+b^2,K,b] Out[3]= b7 Therefore b3 + b5 = b3 b7 = b10 . To check: In[4]:= JacobiLogarithm[b^3+b^5,K,b] Out[4]= b10 Exercises 1. Let K be 3 [x]/(x3 + x2 + 2). Choose another irreducible cubic g(x) over an explicit isomorphism between 3 [x]/(g(x)) and K. 2. For q prime, how many irreducible polynomials of degree q are there over

3.

Give

p?

3. The Fibonacci numbers f (n) are defined recursively by f (0) = 0, f (1) = 1, f (n) = f (n − 1) + f (n − 2). a) Show that f (n) = (an − (−1/a)n )/(a + 1/a) where a2 − a − 1 = 0. b) The function FibonacciList[n] computes a list of the first n Fibonacci numbers. The recursion formula also makes sense modulo p, for p prime. Examine the list of the first n Fibonacci numbers mod p, produced by Mod[FibonacciList[n],p]. Notice that they recur periodically. Explain why the Fibonacci numbers mod p are periodic and determine an upper bound on their period as a function of p. 4. Let q(x) equal x3 − 3x + 5. For a prime p, Factor[xˆ3-3x+5, Modulus→p] gives the factorization of q(x) modulo p. Explore this factorization for various values of p, noting for which primes it is irreducible, for which it factors as irreducible quadratic times linear, and for which it has three linear factors. Try and spot the condition on p which determines whether it factors as quadratic times linear as opposed to one of the other possibilities. You might find the following useful. It defines a function which returns the number of factors in a product of polynomials in x. numfactors[f ] := Exponent[f /. ? (Head[#]==Plus &) → x,x]

185

Symmetric Polynomials Input Files /home/courses/C49/galois.m Mathematical Discussion A symmetric polynomial in the variables {x1 , x2 , . . . , xn } is one which is invariant under any permutation of the variables. The coefficient of tn−k in (t + x1 ) · · · (t + xn ) is called the kth elementary symmetric polynomial, in the variables {x1 , x2 , . . . , xn }. Every symmetric polynomial can be expressed uniquely as a polynomial in the elementary symmetric polynomials. Explicitly, the elementary symmetric polynomials, s1 ,s2 ,. . .,sn , are given by: s1 =x1 + x2 + . . . + xn , X s2 = xi xj , i 11 it is possible to have nonisomorphic groups for which the percentages of the occurance each cycle type is identical. So for n > 11, the information provided by factoring the polynomial at large numbers of primes is insufficient by itself to determine the Galois group. Nevertheless it provides a large amount of information about the group. For example, |G| =

1 . fraction of primes at which f factors linearly

According to the Chebotarev density theorem, if a given partition occurs as a cycle type in G, then at least one prime for which its factorization has the appropriate degrees will appear before N = 70(log(discriminant(f ))2 . The prime number theorem says that N , so that is approximately how the number of primes less than N is approximately log(N) many primes we must test to be sure that we have seen every cycle type which will occur. Mathematica Functions For a permutation group G given as a list of its elements, CycleTypes[G] outputs all the cycle types occurring in the permutations in G; for each type it gives the number of permutations having that type and their density (i.e. the number divided by the order of the group). As with cycles of length 1 which are generally omitted in notation, 1’s are not displayed in the partitions, so enough 1’s to make the sum add to n are assumed. For example, if n = 5, then {2, 2} stands for the partition 5 = 2 + 2 + 1. The top line of the output gives the partitions, the second line contains the number of elements having each partition, and the third line gives the density of each partition. In[1]:= G=Subgroup[{C[{1,2,3}],C[{1,2}]}]; In[2]:= CycleTypes[G] {} {2} {3} Out[2]= 1 4 5 0.17 0.5 0.33 Let f be a polynomial of degree n with integer coefficients. FactorTypes[f,k] factors f modulo p for the first k primes p; it returns statistics on the number of primes for which the various partitions of n appear as the degrees of the irreducible factors. The output has the same format as that for CycleTypes[ ]. It discards information from primes which divide the discriminant of f , so the total of the second line may be slightly less than k. In[1]:= f=x^3-2; In[2]:= FactorTypes[f,50] {} {2} {3} Out[2]= 7 24 17 0.14 0.48 0.34 199

Usage Messages CycleTypes CycleTypes[G], where G is a permutation group, outputs all the cycle types occurring in the permutations in G including for each type the number and density of permutations having that type. FactorTypes FactorTypes[f,k], where f is a polynomial with integer coefficients and k is a positive integer, factors f modulo p for the first k primes p and, discarding those primes which divide the discriminant of f , returns statistics on the number of primes for which the various partitions of n appear as the degrees of the irreducible factors. Examples 1. Determine the Galois group G of x4 + x + 2. Solution: In[1]:= f=x^4+x+2; In[2]:= Factor[f, Modulus→3] Out[2]= 2 + x + x4 Therefore G contains a 4-cycle. In[3]:= Factor[f, Modulus→5] Out[3]= (2 + x)(1 + 4x + 3x2 + x3 ) Therefore G contains a 3-cycle. The only subgroup of Σ4 which contains both 4-cycle and a 3-cycle is Σ4 itself, so G ∼ = Σ4 . 2. Determine the Galois group G of x4 + x + 2. In[1]:= f=x^5-5x+12; In[2]:= Factor[f, Modulus→3] Out[2]= x(2 + x + x2 )(2 + 2x + x2 ) Therefore G contains a product of two 2-cycles. In[3]:= Factor[f, Modulus→7] Out[3]= 5 + 2x + x5 Therefore G contains a 5-cycle. In[4]:= FactorTypes[f,50] {} {5} {2, 2} Out[4]= 4 18 26 0.08 0.36 0.52 In the first 50 primes, there were examples where it factored linearly, some where it factored as a product of two quadratics and a linear factor, and others for which it was irreducible. So far, at no prime have any of its factors been cubic or quartic. To see how many primes we must test before we can be sure that there will never be such a factor: 200

In[5]:= k=70N[Log[Discriminant[f]]^2] Out[5]= 22615.5 Therefore we must test all primes less than 22615.5. In[6]:= k/Log[k] Out[6]= 2256 Thus approximately 2256 primes must be tested. In[7]:= Prime[2256] Out[7]= 19961 Therefore 2256, which was only an approximation, is in fact too low. After some experimentation we discover: In[7]:= Prime[2526] Out[7]= 22619 which is the first prime greater than k, so we test the first 2526 primes. In[8]:= FactorTypes[f,2526] {} {5} {2, 2} Out[8]= 245 999 1279 0.10 0.40 0.51 Since no other factor types have emerged, there are no more, and so we conclude that G has no cycle types containing a 3-cycle or 4-cycle. Inspection of the transitive subgroups of Σ5 shows that only D5 has precisely the cycle types found, so G ≡ D5 . In[9]:= D5=Subgroup[{C[{1,2,3,4,5}],C[{2,5},{3,4}]}]; In[10]:= CycleTypes[D5] {} {5} {2, 2} Out[10]= 1 4 5 0.10 0.40 0.50 Exercises 1. Compute the Galois groups of the following rational polynomials (with as much certainty as possible): a) 12x4 − 15x3 + 20x2 − 30x + 60, x4 + 5x + 5 (Compare the results with those obtained using the cubic resolvent.) b) x5 + x4 − 4x3 − 3x2 + 3x + 1, x5 + 15x + 12, x5 + 15x + 12, x5 + 10x2 + 24 c) x6 + 2x5 + 3x4 + 4x3 + 5x2 + 6x + 1 d) x7 + 9x2 + 7 2. Compute the Galois groups of randomly chosen quintics and sextics. 3. A subgroup G of Σn is called doubly transitive if for each set of pairs (i1 , i2 ), (j1 , j2 ) in {1, . . . , n} with i1 6= i2 , there is an element g ∈ G such that g(i1 ) = j1 and g(i2 ) = j2 . Show that the only doubly transitive subgroups of Σ5 are Σ5 , A5 , and F20 . 201

4. Let f (x) be a rational quintic polynomial with roots r1 , r2 , r3 , r4 , and r5 . Let h(x) = (x − (r1 + r2 ))(x − (r1 + r3 ))(x − (r1 + r4 ))(x − (r1 + r5 ))(x − (r2 + r3 ))(x − (r2 + r4 ))(x − (r2 + r5 ))(x − (r3 + r4 ))(x − (r3 + r5 ))(x − (r4 + r5 )). The Galois group of f (x) over is doubly transitive if and only if h(x) is irreducible over . Consider the special case f (x) = x5 + ax + b. a) Compute h(x). Hint: The coefficients of h are symmetric, so they are polynomials in a and b. In theory the functions in the section “Symmetric Polynomials” could be used to determine these polynomials, but the large number of terms in the expansion of h makes this method impractical. Instead, using a few numerical values of a and b, use the computer to get numerical approximations to the roots of f and then compute h for these values of a and b. Comparing h to the values of a and b for a few different a’s and b’s should lead to the correct expression for the coefficients of h in terms of a and b. Prove that your guess is in fact correct. b) Check that h(x) is reducible whenever f (x) = x5 + 20c4 x + 32c5 for some c. What is the discriminant of f ? What is the Galois group of f ?

202

Curves Input Files /home/courses/C54/trihedron.m /home/courses/C54/3planes.m /home/courses/C54/evolute.m /home/courses/C54/involute.m /home/courses/C54/curvature.m Mathematical Discussion Let γ = (x(t), y(t), z(t)), a ≤ t ≤ b be a twice differentiable curve in 3 . Let p = γ(t) be a point on γ. Let s(t) denote the arc length of γ from γ(a) to γ(t). It is often convenient to describe points on γ by the value of s at the point. s0 (t) = kγ 0 (t)k = k (x0 (t), y 0 (t), z 0 (t)) k. The unit tangent vector to γ at p is T = 0 γ (t)/s0 (t) = dγ/ds. Let P = w/kwk, where w = dT /dt is the vector obtained by differentiating T componentwise. Differentiating kT · T k = 1, shows that P · T = 0, so P is perpendicular to T for every t. P is called the principal normal vector to γ at p. The plane spanned by the vectors T and P is called the osculating plane to γ at p. It is the plane containing the velocity and acceleration vectors of a point moving along the curve. The vector B = T × P is called the binormal to γ at p. The length of kdT /dsk is called the curvature to γ at p, denoted κ. Intuitively, κ measures the rate at which the curve is tending to turn away from its tangent line. Differentiating the equation 0 = T · B gives 0 = κP · B + T · (dB/ds) = T · (dB/ds) so that dB/ds is perpendicular to T . Similarly 1 = B · B implies that dB/ds is perpendicular to B. Thus dB/ds = λP for some λ. Let τ be −λ. τ is called the torsion of γ at p. Since B is perpendicular to the osculating plane, intuitively kτ k measures the rate at which the curve is tending to depart from its osculating plane. In particular, if γ is contained in a plane, then τ = 0. Similarly, differentiating the equations P · T = 0, P · P = 1, P · B = 0 allows us to find the components of dP/ds. We discover that dP/ds = −κT + τ B. If γ is a circle of radius ρ, then at any point γ(t) on the circle, κ = 1/ρ, and the center of the circle is located at γ(t) + ρP (t). Motivated by this, in general we let ρ be 1/κ and call it the radius of curvature. We call the point p + ρP the center of curvature of γ at P . The curve γ˜ (t) = γ(t) + ρ(t)P (t) traced out by the centers of curvatures is called the evolute of γ. Conversely, γ is called an involute of γ˜ . A given curve can have many involutes. Let γ(t) be an involute of γ˜ . Consider the special case where the curves lies in the plane 2 . Thus τ = 0. Given γ˜ , we wish to determine γ. To use γ˜ (t) = γ(t) + ρ(t)P (t) to determine a point γ(t) on γ, we must determine ρ and P . d˜ s ˜ d˜ s d˜ γ d˜ γ dγ dρ dP dρ dρ T = = = + P +ρ = T + P − κρT = P. ds ds d˜ s ds ds ds ds ds ds 203

˜ This determines P (up to sign) as being the direction of the tangent T˜ to dγ(t). Also comparing lengths and integrating gives that ρ = ±˜ s + C for some constant C. Thus each choice of the constant C gives an involute. In particular, for each point on γ˜ there is a choice for C which makes s˜ + C equal to zero at that point. This choice of C yields an involute which touches γ˜ at that point. Mathematica Functions A line segment in n is written in Mathematica by enclosing a list of its two endpoints, each of which is in turn a list of n co-ordinates, within the header Line[ ]. For example, In[1]:= Line[{{0,0,0},{1,2,3}}]; is the line joining the origin to (1, 2, 3). Similarly, a plane in n is written in Mathematica by enclosing a list of three points in the plane, each of which is in turn a list of n co-ordinates, within the header Plane[ ]. A curve f : → 3 is specified as a function of a real variable which returns a list of three real numbers. In[2]:= f[t ]:={t,t^2,t^3} The tangent vector dT to f at f (u) having length |d| is given by Tangent[f,u,d]. In[3]:= Tangent[f,3.,1] Out[3]= Line[{{3., 9., 27.}, {3.03601, 9.21645, 27.9756}}] The direction of the tangent is actually computed by using a small secant line going from f (u) to f (u + du), where by default du equals 0.01. If you want greater accuracy, you can specify a smaller value of du as a fourth argument to Tangent[ ]. In[4]:= Tangent[f,3.,1,0.0001] Out[4]= Line[{{3., 9., 27.}, {3.03613, 9.21679, 27.9756}}] Most of the functions in this package will accept such an optional argument. The multiple dP of the principal normal vector to f at f (u) is given by PrincipalNormal[f,u,d]. In[5]:= PrincipalNormal[f,3.,1] Out[5]= Line[{{3., 9., 27.}, {2.68455, 8.07611, 27.2166}}] OsculatingPlane[f,u,d] returns the plane containing f [u] and the other endpoints of Tangent[f,u,d] and PrincipalNormal[f,u,d]. The multiple dB of the binormal vector to f at f (u) is given by Binormal[f,u,d]. Given a list l of values for t, Draw3D[Trihedron[f,l,d]] produces a picture showing the piece of the curve f for −1 ≤ t ≤ 1 together with the multiples of length d of the unit tangent, principal normal, and binormal vectors, at each point specified by l. The vectors are drawn in red, blue, and green respectively. In this, and most of the other functions which draw curves, the curve is drawn by plotting 120 points. You can pass an additional (fourth) argument to these functions specifying some other number of points to use, where 204

a larger value will give a more accurate picture but will take longer to produce. To see the projection of the figure into the xy-plane use Draw[ ] in place of Draw3D[ ]. Similarly Drawyz[ ] and Drawzx[ ] give projections onto the yz- and zx-planes respectively. To get the curvature, torsion, radius of curvature, or centre of curvature of f at u, use Curvature[f,u], Torsion[f,u], RadiusOfCurvature[f,u], or CentreOfCurvature[f,u] respectively. Draw3D[Evolute[f,l]] produces a picture showing the piece of the curve f for −1 ≤ t ≤ 1 together with the centre of curvature at the point f [u] for each u in the list l. The centres of curvature are joined with lines, so that using several values in the list l will give a sketch of the evolute to f . If f is a function specifying a curve in 2 , Draw[Involute[f,u]] draws the piece of the curve f for −1 ≤ t ≤ 1, together with an involute to f which touches f at the point f [u]. If l is a list of real numbers, Draw[Involutes[f,l]] produces a plot as above, with an involute through f [u] for each entry u in the list l. Usage Messages Binormal Binormal[f,u,d], where f is a function of a real variable returning a list of three real numbers and u and d are real numbers, is the multiple dB of the binormal vector B to f at f [u]. Curvature Curvature[f,u], where f is a function of a real variable returning a list of three real numbers and u is real number, is the curvature to f at f [u]. Draw Draw[g], where g is a list of graphics commands, produces a picture of the projection onto the xy-plane of the graphics specified by g. Draw3D Draw3D[g], where g is a list of graphics commands, produces a picture of the graphics specified by g. Evolute Evolute[f,l], where f is a function of a real variable returning a list of three real numbers, and l is a list of real numbers, returns graphics showing the centre of curvature at the point f [u] for each u in l. The centres of curvature are joined by line segments. The image of the interval [−1, 1] under f is also shown. The graphics can be displayed with Draw[ ] or Draw3D[ ]. Involute Involute[f,u], where f is a function of a real variable returning a list of two real numbers, and u is a list of real numbers, returns graphics showing the image of the interval [−1, 1] under f , along with an involute to f passing through f [u]. The graphics can be displayed with Draw[ ]. Involutes Involutes[f,l], where f is a function of a real variable returning a list of two real 205

numbers, and l is a list of real numbers, returns graphics showing the image of the interval [−1, 1] under f along with an involute to f passing through the point f [u] for each u in the list l. The graphics can be displayed with Draw[ ]. OsculatingPlane OsculatingPlane[f,u,d], where f is a function of a real variable returning a list of three real numbers, and u and d are real numbers, is the plane specified by f [u] and the multiple of length d of the unit tangent and principal normal vectors to f at f [u]. PrincipalNormal PrincipalNormal[f,u,d], where f is a function of a real variable returning a list of real numbers, and u and d are real numbers, is the multiple dP of the principal normal vector P to f at f [u]. Tangent Tangent[f,u,d], where f is a function of a real variable returning a list of real numbers, and u and d are real numbers, is the multiple dT of the unit tangent vector T to f at f [u]. Torsion Torsion[f,u], where f is a function of a real variable returning a list of three real numbers, and u is real number, is the torsion to f at f [u]. Trihedrons Trihedrons[f,l,d], where f is a function of a real variable returning a list of three real numbers, l is a list of real numbers, d is a real number, and n is an integer, returns graphics showing the image of the interval [−1, 1] under f together with d-times the unit tangent, principal normal, and binormal vectors at the image of each point in l. The graphics can be displayed with Draw[ ] or Draw3D[ ].

206

Surfaces Input Files /home/courses/C54/cfield.m Mathematical Discussion Let σ = (x(u, v), y(u, v), z(u, v)), for (u, v) ∈ X ⊂ 2 , be a three-times differentiable surface in 3 . Let p = σ(u, v) be a point on σ. In the tangent plane to σ at p, the vectors r1 = (∂x/∂u, ∂y/∂u, ∂z/∂u) and r2= (∂x/∂v,∂y/∂v, ∂z/∂v) form a basis. Set gij = ri · rj g11 g12 for 1 ≤ i, j ≤ 3. The matrix F = is called the first fundamentamental form g21 g22 of σ at p. √ Let n = (r1 × r2 )/ g where g = det F . Define vectors r1 and r2 by the properties:  1, if i = j ri · rj = . 0, if i 6= j √ √ Explicitly, r1 = (r2 × n)/ g and r2 = (n × r1 )/ g. Let  2  ∂ x ∂2y ∂2z r11 = , , , ∂u2 ∂u2 ∂u2  2  ∂ x ∂2y ∂2z r12 = r21 = , , , and ∂u ∂v ∂u ∂v ∂u ∂v  2  ∂ x ∂2y ∂2z r22 = , , . ∂v 2 ∂v 2 ∂v 2   b11 b12 Set bij = rij · n for 1 ≤ i, j ≤ 2. The matrix is called the second fundamental b21 b22 form of σ at p. Mathematica Functions A surface f : → 3 is specified as a function of a list of two real variables which returns a list of three real numbers. In[1]:= f[{s ,t }]:={s+t,s^2+t,s+t^2} Notice that f must have a single argument consisting of a list with two entries, rather than a pair of arguments. FormI[f ][u,v] and FormII[f ][u,v] give the first and second fundamental forms of f at the point f [u, v]. In[2]:= Out[2]= In[3]:= Out[3]=

FormI[f][{2.,3.}] {{18., 11.}, {11., 38.}} FormII[f][{2.,3.}] {{−0.42145, 0}, {0, −0.25287}} 207

Usage Messages FormI FormI[f][{u,v}], where f is a function of a list of two real variables returning a list of three real numbers, and u, v are real numbers, is the first fundamental form of f at the point f [u, v]. FormII FormII[f][{u,v}], where f is a function of a list of two real variables returning a list of three real numbers, and u, v are real numbers, is the second fundamental form of f at the point f [u, v].

208

Phase Portraits Programs /home/courses/C56/phaseportraits Mathematical Discussion A two-dimensional vector field on 2 is an assignment of a vector in 2 to each point in 2 . In other words, it is a function from 2 to 2 . For example, if f : 2 → is a real-valued function on , then the gradient of f , ∇f = (∂f /∂x, ∂f /∂y), is a vector field. Consider the surface of a river. Ignoring the component which is perpendicular to the surface of the river, the current at each point gives a two-dimensional vector field. Imagine a leaf dropped in the water at some point. Given the current at each point, we wish to find the path followed by the leaf. Let γ(t) = (x(t), y(t)), be a differentiable curve in 2 . The tangent vector to γ(t) is given by γ 0 (t) = (x0 (t), y 0 (t)). Let V = (F, G) be a vector field. Suppose γ(t) has the property that at each point its tangent vector is the vector field V . Such a curve is called an integral curve for the vector field. The components of γ satisfy the system of differential equations x0 (t) = F (x(t), y(t)) y 0 (t) = G(x(t), y(t)). It is convenient to use vector notation. Let X(t) = (x(t), y(t)), X 0 (t) = (x0 (t), y 0 (t)). Then the system can be written efficiently as X 0 (t) = V (X(t)). Picard’s Theorem guarantees a unique solution to such a system in the neighbourhood of each point. Thus V has a unique integral curve through each point. A plot of these integral curves is called a phase portrait of the system. The vector field W = (−G, F ) has the property that at every point V · W = 0. Thus at each point, the integral curve of W is perpendicular to the integral curve of V . The set of integral curves of W are called the orthogonal trajectories to the set of integral curves of V . The integral curves of V have a natural direction, the direction of increasing values of t. However there is no natural direction for its orthogonal trajectories; we could equally well have chosen to use W = (G, −F ) to produce them. Points where V = 0 are called critical points of V . The integral “curve” through a critical point consists merely of the point itself. Since integral curves do not meet, no other integral curve can actually enter the critical point; however critical points can sometimes be limits of other integral curves as t → ∞ or t → −∞. Such critical points are referred to as “sinks” or “sources” respectively. Critical points exhibit variety of phenomenon such as nodes, saddle points, and spirals. Program Descriptions The program phaseportraits allows you to enter a two-dimensional vector field V on 2 and to construct its phase portrait by displaying integral curves. When phaseportraits is started, it displays a window containing some buttons, some areas for entering 209

210

Complex Functions Input Files /home/courses/C60/complexfunctions.m Mathematica Functions A complex number x + iy is entered into Mathematica in the form Complex[x,y]. If x and y are numerical, Mathematica will treat the expression x + yI as equivalent to Complex[x,y], and Mathematica functions can be applied to it as explained in the section “Introduction to Mathematica”. The functions in this package extend the built-in Mathematica functions Exp[ ], Sin[ ], Cos[ ], Tan[ ], Cot[ ], Sec[ ], Csc[ ], Log[ ], and the arithmetical operations “+”, “−”, “∗”, “/”, “ˆ” so that they will accept non-numerical complex arguments. In[1]:= z=Complex[x,y]; In[2]:= z^2 Out[2]= Complex[x2 − y 2 , 2xy] In[3]:= Exp[Complex[x,y]] Out[3]= Complex[E x Cos[y], E x Sin[y]] In[4]:= Exp[Complex[3,2]] Out[4]= Complex[E 3 Cos[2], E 3 Sin[2]] In[5]:= Exp[3 + 2 I] Out[5]= Complex[E 3 Cos[2], E 3 Sin[2]] In[6]:= Exp[x + y I] Out[6]= E x+Complex[0,y] In the last case, where x + yi is not written in the required form, and the number. The output can be used to extract the real and imaginary parts of common combinations of complex functions. The Mathematica function InputForm[ ] can be applied to display the output in a way which may make it easier to convert the expressions to forms suitable for use by other programs. In[7]:= InputForm[Sin[Complex[x,y]]] Out[7]= Complex[Cos[x]/E^y - (E^y*Sin[x])/2, -(E^y*Cos[x])/2 + Sin[x]/E^y] Usage Messages Complex Complex[x,y] is the complex number x + yi.

211

Complex Mappings Prerequisites Complex Functions Programs /home/courses/C60/complexwindows Mathematical Discussion An n × n real-valued matrix M is called orthogonal if M M t = I, where M t is the transpose of M . Equivalently, M is orthogonal if and only if the rows of M form an orthonormal basis for n . We will consider the special case n = 2. Another equivalent formulation is that M is orthogonal if and only if M p · M q = p · q for all vectors p,q in 2 ; this is in turn equivalent to saying that M preserves lengths of vectors and angles between vectors. By preserving angles we mean that it preserves both the size and the direction of the angle. That is, if the direction of q is obtained by rotating p counterclockwise by θ, then the direction of M q is obtained by rotating M p counterclockwise by θ. A matrix is a nonzero multiple of an orthogonal matrix if and only if it preserves angles. Let f : → be a complex-valued function of a complex variable. Let u and v be the real and imaginary parts of f . Under the identification of with 2 , f corresponds to F (x, y) = (u(x, y), v(x, y)). Suppose that F is differentiable as a function from 2 to 2 at the point p = (a, b). The derivative of F at p is given by the Jacobian matrix   ∂u ∂u  ∂x (p) ∂y (p)  . dF =    ∂v ∂v (p) (p) ∂x ∂y f is complex differentiable at a + ib if and only if F is differentiable as a function from 2 to 2 at the point p = (a, b) and the Cauchy-Riemann equations ∂u/∂x(p) = ∂v/∂y(p) and ∂u/∂y(p) = −∂v/∂x(p) are satisfied. By examination of dF we see that the CauchyRiemann equations are satisfied if and only if dF is a multiple of an orthogonal matrix. Thus f is complex differentiable at w = (a + ib) with f 0 (w) 6= 0 if and only if the corresponding function F : 2 to 2 is differentiable and angle-preserving at (a, b). Such a function is said to be conformal at w. Program Descriptions The program complexwindows allows you to enter a function w from 2 to 2 , create a picture in the plane, and see the image of that picture under the function w. When complexwindows is started, it displays a window containing some buttons, some areas for entering text, and two large windows containing the co-ordinate axes. Buttons are activated by clicking on them with the left mouse button. 212

complexwindows initializes the function w to be the identity function. To specify a function w = (u(x, y), v(x, y)), type the u and v components into the text areas near the bottom labelled u and v respectively. Use standard mathematical notation including parentheses where appropriate, except that multiplication must be stated explicitly using the symbol ∗. For example, 2 times x must be entered as 2 ∗ x, not as 2x or 2 x. The symbol ˆ can be used for the power operation. complexwindows understands “+”,“−”,“∗”,“/”,“ˆ”, and the functions exp(), sin(), cos(), tan(), log(), and sqrt(). After typing in your formula, press the “parse” button to the left. If no syntax errors are detected, the message “finished parsing” will appear in the messages area at the bottom. Otherwise, “parsing failed” appears. Other error messages appear in the window from which you called the program. For example, if you entered “factorial(x)” the message “undefined function factorial” would appear. You can use the mouse to draw in the large left hand window; the image of the drawing under the function w will appear in the right hand window. To draw, press the left mouse button at some point in the left hand window and move it while holding the mouse button down. The image of the path followed by the mouse until the button is released will be drawn in the left window. Simultaneously, the image under w of the figure being traced in the left window will appear in the right window. To add to the picture, release the button, move the mouse to a new location, and draw again. Pressing the middle mouse button in the left window, displays the co-ordinates of the point at which it was pressed in the left window, and the co-ordinates of the image of that point under w in the right window. Initially, each window shows the rectangle with x-values from about −230 to 230 and y-values from about −310 to 310. The portion of the plane shown can be changed by replacing the value to the right of the word “scale” which appears below each window and pressing the button labelled “apply”. Pressing the button at the top marked “Colour” with the left mouse button brings down a menu from which you can select a colour for drawing. This does not affect the colour of the figure already drawn. The current colour is marked with a diamond shape. Menu selection is made by clicking the right mouse button on the desired item. The “Functions” menu provides a few predefined functions that you can select instead of entering their real and imaginary parts directly. Activating the button at the top marked “Clear” clears the drawing area and its image; activating the “Exit” button exits the program. You should be able to observe preservation or non-preservation of angles according to whether or not the function entered has or does not have a complex derivative with a nonzero value at the point. Since complex-valued functions must be entered by giving their real and imaginary parts, you may find it convenient to begin a Mathematica session and use the functions in /home/courses/C60/complexfunctions.m to produce formulas for the real and imaginary parts of complex-valued functions.

213

Convex Hulls Input Files /home/courses/C60/convexhull.m Mathematical Discussion Let H ⊂ be the half-plane to one side of the line z = u + vt, where u, v ∈ , t ∈ , and v 6= 0. The line can be rewritten as b(z − u) = it where b = i/v, so H can be described as one of {z | b(z −u) = it and t ≥ 0} or {z | b(z −u) = it and t ≤ 0}. Notice that b cannot be 0. Replacing b by −b if necessary, we may assume H = {z | b(z − u) = it and t ≥ 0}. Equivalently, H equals {z | Im b(z − u) ≥ 0}, where Im w denotes the imaginary part of the complex number w. Let p(z) be a polynomial in a complex variable z. Suppose that the half-plane H = {z | Im b(z − u) ≥ 0} contains no roots of p(z). Let {r1 , r2 , . . . , rn } be the roots of p(z). So p(z) = (z − r1 )(z − r2 ) · · · (z − rn ). Then p0 (z)/p(z) = 1/(z − r1 ) + 1/(z − r2 ) + . . . + 1/(z − rn ). Since rj ∈ / H, Im b(rj − u) < 0 ∀j. Thus if z ∈ H, then Im b(z − rj ) = Im b(z − u) − Im b(rj − u) > 0. and so Im 1/(b(z − rj )) < 0 ∀j. Therefore if z ∈ H then Im p0 (z)/bp(z) = Im (1/(b(z − r1 )) + 1/(b(z − r2 )) + . . . 1/(b(z − rn ))) < 0 so that z cannot be a root of p0 . We conclude that a halfplane containing no roots of p(z) also contains no roots of p0 (z). A set X ⊂ is called convex if for every pair of points u, v ∈ X, the line joining u to v lies in X. Let S = {a1 , a2 , . . . , an } be a set of points in . The convex hull of S is the smallest convex set containing S. It will be a polygon bounded by some of the lines joining points in S. Let X be the convex hull of the roots of the polynomial p(z). For each boundary line L of the polygon X, the plane to one side of L lies outside the polygon and thus has no roots of p(z). By the above, this plane also has no roots of p0 (z). It follows that all the roots of p0 (z) also lie within the polygon X. We can summarize this by saying the roots of the derivative of a polynomial always lie within the convex hull of the roots of the polynomial. Mathematica Functions For a polynomial p, ConvexHull[p] produces a display showing the roots of p, the convex hull of those roots, and the roots of p0 . The boundary lines of the convex hull are drawn in blue, with the roots of p in green and those of p0 (z) in red. Usage Messages ConvexHull ConvexHull[p], where p is a polynomial of a complex variable, produces a display showing the roots of p, the convex hull of those roots, and the roots of p0 . 214

PART FOUR: REFERENCE MATERIALS

UNIX Commands Quick Reference cancel cat cd chmod cp echo emacs export hostname kill lpr lpstat ls man mkdir more mv passwd ps pwd rlogin rm rmdir vi = Ctrl-c

cancel a printer job print file to screen change working directory change permissions on a file copy file print value of a variable create and edit text files make variable available for later commands print name of login machine terminate processes print a file show status of printer queues list contents of directory online documentation of UNIX commands create a new directory print file to screen, a page at a time move file change your password list processes print working directory remote login remove file remove directory create and edit text files set value of a variable abort executing command

215

VI Reference Card Enter the Editor vi filename

If no such file exists yet, it will be created.

Exit the Editor :w :q :q! :wq :ZZ

write the edit buffer as a permanent file quit,ignoring changes since last w force a quit – save no changes write and quit – save changes same as wq Cursor Motion

← Backspace h Ctrl-H → Space l ↑ k Ctrl-P ↓ j Ctrl-N + 0 ˆ \$ b or B e or E w or W H L nG \$G

move left one space same as ← same as ← same as ← move right one space same as → same as → move up one line same as ↑ same as ↑ move down one line same as ↓ same as ↓ retreat to first nonblank character of previous line advance to first nonblank character of next line move to first character on current line same as 0 move to end of current line back up one word move forward to end of word move forward to beginning of next word move to top of screen move to first nonblank character of last line on screen move to nth line of file move to last line of file

Window Control Ctrl-b Ctrl-f

move back full length of window move forward full length of window 216

Ctrl-d Ctrl-u Ctrl-l

scroll down half a window scroll up one half a window redraw current screen

Insertion A a I i O o

append text at end of line append text after cursor insert text at beginning of line insert text before cursor open line above current line and insert open line below current line and insert

Symbols for Text Areas w b e 0 ˆ \$ ) ( }} {{

word backward word end of word beginning of line beginning of line end of line forward to the end of the sentence back to the beginning of the sentence forward to the end of the paragraph backward to the beginning of the paragraph

Deletion x dsymbol ndsymbol dd

delete delete delete delete

character under cursor text area represented by symbol text area, repeat n times current line

Change, Substitute, Replace csymbol ncsymbol r R s S

change text area represented by symbol to text typed in, up to “Esc” change text area to text typed in, up to “Esc”; repeat n times replace a single character replace characters on the screen with characters typed in, up to “Esc” substitute characters typed in, up to “Esc”, for single character substitute text typed in, up to “Esc”, for entire line

Yank and Paste ysymbol nysymbol p

yank text area represented by symbol yank the text area; repeat n times put yanked or deleted text after cursor 217

P

put yanked or deleted text before cursor

Repeat, Undo . u

repeat last command that changed the buffer undo last command that changed the buffer

Searching /pattern ?pattern n

search for next occurrence of pattern search for preceding occurrence of pattern repeat the last search command

read contents of named file into edit buffer

Recovery from Crash vi -r filename vi -r

recover the named file list saved files

218

Keybindings for Emacs Math Mode Commands • • • • • • • • • • •

2 M-x start-math TAB M-a M-e M-k ESC TAB C-c C-c C-c C-b C-x [ C-x ] C-c C-h

• C-c C-H • C-c C-e • C-c C-f • C-c C-r

start Mathematica create new empty cell move to beginning of cell move to end of cell kill cell (delete and place in kill ring) complete symbol at point to mathematica function interrupt Mathematica computation show if Mathematica is engaged in computation join cell to preceding cell join cell to following cell help on symbol; equivalent to Mathematica’s ? except that output goes to separate buffer extended help on symbol; ??-analog of C-c C-h after \w \W \sc \Sc

Registers

Commands Dealing with Emacs Lisp eval sexp before point C-x C-e eval current defun C-M-x eval region M-x eval-region eval entire buffer M-x eval-current-buffer read and eval minibuffer M-ESC re-execute last minibuffer command C-x ESC read and eval Emacs Lisp file M-x load-file load from standard system directory M-x load-library

Simple Customization Here are some examples of binding global keys in Emacs Lisp. Note that you cannot say "\M-#"; you must say "\e#". (global-set-key "\C-cg" ’goto-line) (global-set-key "\e\C-r" ’isearch-backward-regexp) (global-set-key "\e#" ’query-replace-regexp) An example of setting a variable in Emacs Lisp:

copy region to register insert register contents

C-x x C-x g

save point in register move point to saved location

C-x / C-x j

Writing Commands

Info enter the Info documentation reader

C-h i

Moving within a node: scroll forward scroll reverse beginning of node

An example: SPC DEL . (dot)

Moving between nodes: next node previous node move up select menu item by name select nth menu item by number (1–5) follow cross reference (return with l) return to last node you saw return to directory node go to any node by name

n p u m n f l d g

Other: run Info tutorial list Info commands quit Info search nodes for regexp

(defun hcommand-namei (hargsi) "hdocumentationi" (interactive "htemplatei") hbodyi)

h ? q s

(defun this-line-to-top-of-screen (line) "Reposition line point is on to the top of the screen. With ARG, put point on line ARG. Negative counts from bottom." (interactive "P") (recenter (if (null line) 0 (prefix-numeric-value line)))) The argument to interactive is a string specifying how to get the arguments when the function is called interactively. Type C-h f interactive for more information. c 1987 Free Software Foundation, Inc. Copyright designed by Stephen Gildea, March 1987 v1.9 for GNU Emacs version 18 on Unix systems Permission is granted to make and distribute copies of this card provided the copyright notice and this permission notice are preserved on all copies. For copies of the GNU Emacs manual, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge MA 02139.