Matrix Depot

A test matrix collection for Julia.

  1. Install
  2. Usage
  3. Examples
  4. User Defined Properties
  5. More Examples

1. Install

To install the package, type


In [ ]:
Pkg.add("MatrixDepot")

2. Usage

First load the package:


In [1]:
using MatrixDepot

The only function will be exported is matrixdepot.


In [2]:
? matrixdepot


INFO: Loading help data...
matrixdepot (generic function with 17 methods)

Every matrix in the collection is represented by a string matrix_name, for example, the Cauchy matrix is represented by "cauchy" and the Hilbert matrix is represented by "hilb".

The properties of the matrices in the collection are also symbolized by strings property_name. For example, the class of the symmetric matrices is symbolized by "symmetric".

  • matrixdepot() returns a list of all the matrices in the collection.

  • matrixdepot(matrix_name, p1, p2, ...) returns a matrix specified by the query string matrix_name. p1, p2, ... are input parameters depending on matrix_name.

  • matrixdepot(matrix_name) returns the parameter options and the properties of matrix_name.

  • matrixdepot(property_name) returns a list of matrices with the property property_name.

  • matrixdepot(prop1, prop2, prop3,...) returns a list of matrices with properties prop1, prop2, prop3 etc.

We can define our own properties using the macro @addproperty

  • @addproperty property_name = ["matrix1", "matrix2", "matrix3"]

and remove a defined property using the macro @rmproperty

  • @rmproperty property_name

See below for examples.

3. Examples

To see all the matrices in the collection, type


In [3]:
matrixdepot()


          | symmetric |  inverse  | ill-cond  |  pos-def  |  eigen    |
      vand|           |     *     |     *     |           |           |
     frank|           |           |     *     |           |     *     |
     minij|     *     |     *     |           |     *     |     *     |
   clement|     *     |     *     |           |           |     *     |
   tridiag|     *     |     *     |     *     |     *     |     *     |
    circul|     *     |           |           |     *     |     *     |
  dingdong|     *     |           |           |           |     *     |
  hadamard|           |     *     |           |           |     *     |
     moler|     *     |     *     |     *     |     *     |           |
     invol|           |     *     |     *     |           |     *     |
   fiedler|     *     |     *     |           |           |     *     |
  binomial|           |           |           |           |           |
    lehmer|     *     |     *     |           |     *     |           |
   invhilb|     *     |     *     |     *     |     *     |           |
    lotkin|           |     *     |     *     |           |     *     |
      triw|           |     *     |     *     |           |           |
     magic|           |     *     |           |           |           |
     kahan|           |     *     |     *     |           |           |
    pascal|     *     |     *     |     *     |     *     |     *     |
  chebspec|           |           |           |           |     *     |
      hilb|     *     |     *     |     *     |     *     |           |
    cauchy|     *     |     *     |     *     |     *     |           |
       pei|     *     |     *     |     *     |     *     |           |
    parter|           |           |           |           |     *     |
  forsythe|           |     *     |     *     |           |     *     |
     grcar|           |           |           |           |     *     |

The meanings of the column heading is as follows:

  • "symmetric": the matrix is symmetric for some parameter values.

  • "inverse": the inverse of the matrix is known explicitly.

  • "ill-cond": the matrix is ill-conditioned for some parameter values.

  • "pos-def": the matrix is symmetric positive definite for some parameter values.

  • "eigen": the eigensystem of the matrix has some known results (explicit formulas for eigenvalues, eigenvectors, bounds of eigenvalues, etc).

We can generate a Hilbert matrix of size 4 by typing


In [4]:
matrixdepot("hilb", 4)


Out[4]:
4x4 Array{Float64,2}:
 1.0       0.5       0.333333  0.25    
 0.5       0.333333  0.25      0.2     
 0.333333  0.25      0.2       0.166667
 0.25      0.2       0.166667  0.142857

and generate a circul matrix of size 5 by


In [5]:
matrixdepot("circul", 5)


Out[5]:
5x5 Array{Float64,2}:
 1.0  2.0  3.0  4.0  5.0
 5.0  1.0  2.0  3.0  4.0
 4.0  5.0  1.0  2.0  3.0
 3.0  4.0  5.0  1.0  2.0
 2.0  3.0  4.0  5.0  1.0

We can type the matrix name to see the parameter options or matrix properties.


In [6]:
matrixdepot("hilb")


Hilbert matrix: 
             
 Input options: 
             
 (type), dim: the dimension of the matrix
             
 (type), row_dim, col_dim: the row and column dimension 
             
 ['inverse', 'ill-cond', 'symmetric', 'pos-def']

In [7]:
matrixdepot("hadamard")


Hadamard matrix: 
             
 Input options: 
             
 (type), dim: the dimension of the matrix, n is a power of 2 
             
 ['inverse', 'orthogonal', 'eigen']

From the information given, we notice that we can create a 4-by-6 rectangular Hilbert matrix by


In [8]:
matrixdepot("hilb", 4, 6)


Out[8]:
4x6 Array{Float64,2}:
 1.0       0.5       0.333333  0.25      0.2       0.166667
 0.5       0.333333  0.25      0.2       0.166667  0.142857
 0.333333  0.25      0.2       0.166667  0.142857  0.125   
 0.25      0.2       0.166667  0.142857  0.125     0.111111

We can also specify the data type


In [9]:
matrixdepot("hilb", Float16, 5, 3)


Out[9]:
5x3 Array{Float16,2}:
 1.0      0.5      0.33325
 0.5      0.33325  0.25   
 0.33325  0.25     0.19995
 0.25     0.19995  0.16663
 0.19995  0.16663  0.14282

By inputting a matrix name, we can see what properties that matrix have. Conversely, if we input a property (or properties), we can see all the matrices (in the collection) having that property (or properties).


In [8]:
matrixdepot("symmetric")


Out[8]:
12-element Array{ASCIIString,1}:
 "hilb"    
 "cauchy"  
 "circul"  
 "dingdong"
 "invhilb" 
 "moler"   
 "pascal"  
 "pei"     
 "clement" 
 "fiedler" 
 "minij"   
 "tridiag" 

In [11]:
matrixdepot("symmetric", "ill-cond")


Out[11]:
7-element Array{ASCIIString,1}:
 "hilb"   
 "cauchy" 
 "invhilb"
 "moler"  
 "pascal" 
 "pei"    
 "tridiag"

In [10]:
matrixdepot("inverse", "ill-cond", "symmetric")


Out[10]:
7-element Array{ASCIIString,1}:
 "hilb"   
 "cauchy" 
 "invhilb"
 "moler"  
 "pascal" 
 "pei"    
 "tridiag"

Given a property, we can loop through all the matrices having this property


In [15]:
# Multiply all matrices of the class "symmetric" and "ill-cond" and "inverse"
A = eye(4)
print("Identity matrix")
for mat in intersect(matrixdepot("symmetric"), matrixdepot("ill-cond"), matrixdepot("inverse")) 
    print(" x $mat matrix")
    A = A * full(matrixdepot(mat, 4))    
end
println(" =")
A


Identity matrix x hilb matrix x cauchy matrix x invhilb matrix x moler matrix x pascal matrix x pei matrix x tridiag matrix =
Out[15]:
4x4 Array{Float64,2}:
 153.12    -11.919    -15.4345   296.937
 109.896    -8.91857  -11.5976   214.433
  86.7524   -7.15714   -9.32857  169.702
  71.9139   -5.98707   -7.81497  140.876

The loop above can also be written as


In [16]:
A = eye(4)
print("Identity matrix")
for mat in matrixdepot("symmetric", "ill-cond", "inverse")
    print(" x $mat matrix")
    A = A * full(matrixdepot(mat, 4))
end
println(" =")
A


Identity matrix x hilb matrix x cauchy matrix x invhilb matrix x moler matrix x pascal matrix x pei matrix x tridiag matrix =
Out[16]:
4x4 Array{Float64,2}:
 153.12    -11.919    -15.4345   296.937
 109.896    -8.91857  -11.5976   214.433
  86.7524   -7.15714   -9.32857  169.702
  71.9139   -5.98707   -7.81497  140.876

4. User Defined Properties

We can define properties in MatrixDepot. Since each property in Matrix Depot is a list of strings, you can simply do, for example,


In [2]:
spd = matrixdepot("symmetric", "pos-def")


Out[2]:
10-element Array{ASCIIString,1}:
 "hilb"   
 "cauchy" 
 "circul" 
 "invhilb"
 "moler"  
 "pascal" 
 "pei"    
 "minij"  
 "tridiag"
 "lehmer" 

In [5]:
myprop = ["lehmer", "cauchy", "hilb"]


Out[5]:
3-element Array{ASCIIString,1}:
 "lehmer"
 "cauchy"
 "hilb"  

Then use it in your tests like


In [8]:
for matrix in myprop
    A = matrixdepot(matrix, 6)
    L, U, p = lu(A) #LU factorization
    err = norm(A[p,:] - L*U, 1) # 1-norm error
    println("1-norm error for $matrix matrix is ", err)
end


1-norm error for lehmer matrix is 1.1102230246251565e-16
1-norm error for cauchy matrix is 5.551115123125783e-17
1-norm error for hilb matrix is 2.7755575615628914e-17

To add a property permanently for future use, we put the macro @addproperty at the beginning.


In [2]:
@addproperty myfav = ["lehmer", "cauchy", "hilb"]


Out[2]:
87

In [4]:
@addproperty spd = matrixdepot("symmetric", "pos-def")


Out[4]:
195

We need to restart Julia to see the changes. Type


In [2]:
matrixdepot()


          | symmetric |  inverse  | ill-cond  |  pos-def  |  eigen    |
      vand|           |     *     |     *     |           |           |
     frank|           |           |     *     |           |     *     |
     minij|     *     |     *     |           |     *     |     *     |
   clement|     *     |     *     |           |           |     *     |
   tridiag|     *     |     *     |     *     |     *     |     *     |
    circul|     *     |           |           |     *     |     *     |
  dingdong|     *     |           |           |           |     *     |
  hadamard|           |     *     |           |           |     *     |
     moler|     *     |     *     |     *     |     *     |           |
     invol|           |     *     |     *     |           |     *     |
   fiedler|     *     |     *     |           |           |     *     |
  binomial|           |           |           |           |           |
    lehmer|     *     |     *     |           |     *     |           |
   invhilb|     *     |     *     |     *     |     *     |           |
    lotkin|           |     *     |     *     |           |     *     |
      triw|           |     *     |     *     |           |           |
     magic|           |     *     |           |           |           |
     kahan|           |     *     |     *     |           |           |
    pascal|     *     |     *     |     *     |     *     |     *     |
  chebspec|           |           |           |           |     *     |
      hilb|     *     |     *     |     *     |     *     |           |
    cauchy|     *     |     *     |     *     |     *     |           |
       pei|     *     |     *     |     *     |     *     |           |
  forsythe|           |     *     |     *     |           |     *     |
     grcar|           |           |           |           |     *     |

New Properties:

spd = [ hilb, cauchy, circul, invhilb, moler, pascal, pei, minij, tridiag, lehmer, ] 

myfav = [ lehmer, cauchy, hilb, ] 

Notice new defined properties have been included. We can use them as


In [3]:
matrixdepot("myfav")


Out[3]:
3-element Array{ASCIIString,1}:
 "lehmer"
 "cauchy"
 "hilb"  

We can remove a property using the macro @rmproperty. As before, we need to restart Julia to see the changes.


In [4]:
@rmproperty myfav


Out[4]:
153

In [3]:
matrixdepot()


          | symmetric |  inverse  | ill-cond  |  pos-def  |  eigen    |
      vand|           |     *     |     *     |           |           |
     frank|           |           |     *     |           |     *     |
     minij|     *     |     *     |           |     *     |     *     |
   clement|     *     |     *     |           |           |     *     |
   tridiag|     *     |     *     |     *     |     *     |     *     |
    circul|     *     |           |           |     *     |     *     |
  dingdong|     *     |           |           |           |     *     |
  hadamard|           |     *     |           |           |     *     |
     moler|     *     |     *     |     *     |     *     |           |
     invol|           |     *     |     *     |           |     *     |
   fiedler|     *     |     *     |           |           |     *     |
  binomial|           |           |           |           |           |
    lehmer|     *     |     *     |           |     *     |           |
   invhilb|     *     |     *     |     *     |     *     |           |
    lotkin|           |     *     |     *     |           |     *     |
      triw|           |     *     |     *     |           |           |
     magic|           |     *     |           |           |           |
     kahan|           |     *     |     *     |           |           |
    pascal|     *     |     *     |     *     |     *     |     *     |
  chebspec|           |           |           |           |     *     |
      hilb|     *     |     *     |     *     |     *     |           |
    cauchy|     *     |     *     |     *     |     *     |           |
       pei|     *     |     *     |     *     |     *     |           |
  forsythe|           |     *     |     *     |           |     *     |
     grcar|           |           |           |           |     *     |

New Properties:

spd = [ hilb, cauchy, circul, invhilb, moler, pascal, pei, minij, tridiag, lehmer, ] 

5. More Examples

An interesting test matrix is magic square. It can be generated as


In [16]:
M = matrixdepot("magic", 5)


Out[16]:
5x5 Array{Int64,2}:
 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

In [17]:
sum(M,1)


Out[17]:
1x5 Array{Int64,2}:
 65  65  65  65  65

In [18]:
sum(M,2)


Out[18]:
5x1 Array{Int64,2}:
 65
 65
 65
 65
 65

In [19]:
sum(diag(M))


Out[19]:
65

In [20]:
p = [5:-1:1]
sum(diag(M[:,p]))


Out[20]:
65

Pascal Matrix can be generated as


In [21]:
P = matrixdepot("pascal", 6)


Out[21]:
6x6 Array{Int64,2}:
 1  1   1   1    1    1
 1  2   3   4    5    6
 1  3   6  10   15   21
 1  4  10  20   35   56
 1  5  15  35   70  126
 1  6  21  56  126  252

Notice the Cholesky factor of the Pascal matrix has Pascal's triangle rows.


In [22]:
chol(P)


Out[22]:
6x6 Array{Float64,2}:
 1.0  1.0  1.0  1.0  1.0   1.0
 0.0  1.0  2.0  3.0  4.0   5.0
 0.0  0.0  1.0  3.0  6.0  10.0
 0.0  0.0  0.0  1.0  4.0  10.0
 0.0  0.0  0.0  0.0  1.0   5.0
 0.0  0.0  0.0  0.0  0.0   1.0