Python and NumPy: Indexing a Magic Square

This guide is obsolete, it was written during the early stages when I was learning python. A more up to date guide is available here:

Other python guides including installation of python are available in:

Tutorial Video

Prequisites

We previously looked at indexing 1 dimension vectors. We can also index more complicated arrays such as matrices. In this example we will create a magic square, a magic square is a square array where the sum of every column, row, diagonal and anti-diagonal are equal.

To do this we'll need to use the third party library function magic_square. We'll import it as ms. If you haven't already installed this library use:

Python

Creating a Magic Square

Once we have this library we can import its prerequisite NumPy as np and the magic_square library as ms:

Python
[[17 24  1  8 15]
 [23  5  7 14 16]
 [ 4  6 13 20 22]
 [10 12 19 21  3]
 [11 18 25  2  9]]

\displaystyle \left[ {\begin{array}{*{20}{c}} {17} & {24} & 1 & 8 & {15} \\ {23} & 5 & 7 & {14} & {16} \\ 4 & 6 & {13} & {20} & {22} \\ {10} & {12} & {19} & {21} & 3 \\ {11} & {18} & {25} & 2 & 9 \end{array}} \right]

Lets first look up the dimensions of the matrix using the function shape:

Python
(5, 5)

This returns the number of rows and number of columns respectively. As it is a square, both have the same value of 5. Recall we are using 0 order indexing, which means we start from the 0th element and go up to but don't include this upper bound of 5, thus are maximum element is the 4th element. We can see this when we open up the variable s in variable explorer:

Indexing a Single Element

To select a single element for example the element of s at row 0 and col 0 we can use square brackets to index into s. A comma delimiter is used to separate the row element from the column element.

Python
17

We can try also for row 1 and column 3:

Python
14
Python
12

As we seen when indexing with vectors it is also possible to index using negative elements. For the the three values above they can also be specified as:

Python
17
Python
14
Python
12

Indexing Multiple Values

It is also possible to select multiple elements. For instance if we want the element in the 1st row and 2nd column and the element in the 3rd row and 4th column we would use. Note the elements of the rows are enclosed in square brackets using a comma as a delimiter. The element in the columns are also enclosed in square brackets using a comma as a delimiter. And these are both enclosed in an outside set of square brackets, once again with a delimiter between them:

Python
[7 3]

\displaystyle \left[ {\begin{array}{*{20}{c}} 7 & 3 \end{array}} \right]

It is also possible to make a selection using a colon. Say we want row 1 to 3 (recall with 0 order indexing we go to this upper bound of 3 but don't include it), so this is row 1 and row 2 and we want both to be in column 1 we can use

Python
[5 6]

The colon can also be used to select a full row or column. Lets take the 1st row for instance:

Python
[23  5  7 14 16]

\displaystyle \left[ {\begin{array}{*{20}{c}} {23} & 5 & 7 & {14} & {16} \end{array}} \right]

Indexing Rows, Columns and Diagonals

In a magic square, all rows, columns and diagonals sum to the same value. For the magic square s, check these using indexing of a row or column, the sum function, the diag function and the fliplr function. I advise you to try this one before reading below for practice.

Lets start with the five rows:

Python
[[17 24  1  8 15]]

65
Python
[[23  5  7 14 16]]

65
Python
[[ 4  6 13 20 22]]
65
Python
[[10 12 19 21  3]]
65
Python
[[11 18 25  2  9]]
65

So far so good, the 5 rows all have a sum of 65, now lets repeat with the 5 columns:

Python
[[17]
 [23]
 [ 4]
 [10]
 [11]]
65
Python
[[24]
 [ 5]
 [ 6]
 [12]
 [18]]
65
Python
[[ 1]
 [ 7]
 [13]
 [19]
 [25]]
65
Python
[[ 8]
 [14]
 [20]
 [21]
 [ 2]]
65
Python
[[15]
 [16]
 [22]
 [ 3]
 [ 9]]
65

So far, so good again, all columns also have a sum of 65.

For the diagonal we can use the function diag:

Python
[17  5 13 21  9]

65

Once again it equals 65. For the antidiagonal, we need to flip the matrix left right.

Python

Opening up sfliplr in variable explorer and comparing to the above:

We see that the new diagonal is what was previously the antidiagonal, so we can use the function diag

Python
[15 14 13 12 11]

65

We now see the sum of the anti-diagonal also equals 65 meaning that the magic square s created is indeed a magic square.

Full Script

For convenience I will put all the code for determining the lengths of this magic square in a single script file:

Python

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.