Adding New Matrix Generators¶
Matrix Depot provides a diverse collection of test matrices, including parametrized matrices and real-life matrices. But occasionally, you may want to define your own matrix generators and be able to use them from Matrix Depot.
Declaring Generators¶
Users may use the include_generator
function to declare new
generators. Note that include_generator
must be called at runtime, so
users creating packages which define custom matrix test suites should place
their calls to include_generator
in the __init__
function of their
module to avoid
precompilation issues.
A complete working example of how to create a Julia package with custom matrices is provided as a
`template https://github.com/KlausC/MatrixDepotTemplate.jl`_.
- include_generator(Stuff_To_Be_Included, Stuff, f)¶
Includes a piece of information of the function
f
to Matrix Depot, whereStuff_To_Be_Included
is one of the following:FunctionName
: the function name off
. In this case,Stuff
is a string representingf
.Group
: the group wheref
belongs. In this case,Stuff
is the group name.
Examples¶
To get a feel of how it works, let’s see an example. Suppose we have defined two
matrix generators randsym
and randorth
in our own module outside of MatrixDepot:
"""
random symmetric matrix
=======================
*Input options:*
+ n: the dimension of the matrix
"""
function randsym(n)
A = zeros(n, n)
for j = 1:n
for i = j:n
A[i,j] = randn()
if i != j; A[j,i] = A[i,j] end
end
end
return A
end
"""
random Orthogonal matrix
========================
*Input options:*
+ n: the dimension of the matrix
"""
randorth(n) = Matrix(qr(randn(n,n)).Q)
We can then write:
MatrixDepot.include_generator(MatrixDepot.FunctionName, "randsym", randsym)
MatrixDepot.include_generator(MatrixDepot.FunctionName, "randorth", randorth)
and when we are done including generators, we need to update the database:
MatrixDepot.publish_user_generators()
This is it. We can now use them from Matrix Depot:
julia> mdinfo()
Currently loaded Matrices
–––––––––––––––––––––––––––
builtin(#)
––––––––––– ––––––––––– ––––––––––– –––––––––––– ––––––––––– ––––––––––––– ––––––––––––
1 baart 10 deriv2 19 gravity 28 kms 37 parter 46 rohess 55 ursell
2 binomial 11 dingdong 20 grcar 29 lehmer 38 pascal 47 rosser 56 vand
3 blur 12 erdrey 21 hadamard 30 lotkin 39 pei 48 sampling 57 wathen
4 cauchy 13 fiedler 22 hankel 31 magic 40 phillips 49 shaw 58 wilkinson
5 chebspec 14 forsythe 23 heat 32 minij 41 poisson 50 smallworld 59 wing
6 chow 15 foxgood 24 hilb 33 moler 42 prolate 51 spikes
7 circul 16 frank 25 invhilb 34 neumann 43 randcorr 52 toeplitz
8 clement 17 gilbert 26 invol 35 oscillate 44 rando 53 tridiag
9 companion 18 golub 27 kahan 36 parallax 45 randsvd 54 triw
user(#)
–––––––––– –––––––––
1 randorth 2 randsym
Groups
––––––– ––––– ––––– ––––––– –––––– ––––––– –––––––––––––––
all local eigen illcond posdef regprob symmetric
builtin user graph inverse random sparse test_for_paper2
Suite Sparse of
–––––––––––– ––––
2773 2833
MatrixMarket of
–––––––––––– –––
488 498
julia> mdinfo("randsym")
random symmetric matrix
≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
Input options:
• n: the dimension of the matrix
julia> matrixdepot("randsym", 5)
5x5 Array{Float64,2}:
1.57579 0.474591 0.0261732 -0.536217 -0.0900839
0.474591 0.388406 0.77178 0.239696 0.302637
0.0261732 0.77178 1.7336 1.72549 0.127008
-0.536217 0.239696 1.72549 0.304016 1.5854
-0.0900839 0.302637 0.127008 1.5854 -0.656608
julia> A = matrixdepot("randorth", 5)
5x5 Array{Float64,2}:
-0.359134 0.401435 0.491005 -0.310518 0.610218
-0.524132 -0.474053 -0.53949 -0.390514 0.238764
0.627656 0.223519 -0.483424 -0.104706 0.558054
-0.171077 0.686038 -0.356957 -0.394757 -0.465654
0.416039 -0.305802 0.326723 -0.764383 -0.205834
julia> A'*A
5x5 Array{Float64,2}:
1.0 8.32667e-17 1.11022e-16 5.55112e-17 -6.93889e-17
8.32667e-17 1.0 -1.80411e-16 -2.77556e-17 -5.55112e-17
1.11022e-16 -1.80411e-16 1.0 1.94289e-16 -1.66533e-16
5.55112e-17 -2.77556e-17 1.94289e-16 1.0 1.38778e-16
-6.93889e-17 -5.55112e-17 -1.66533e-16 1.38778e-16 1.0
We can also add group information with:
MatrixDepot.include_generator(MatrixDepot.Group, :random, randsym)
MatrixDepot.include_generator(MatrixDepot.Group, :symmetric, randsym)
MatrixDepot.include_generator(MatrixDepot.Group, :random, randorth)
MatrixDepot.publish_user_generators()
For example:
julia> mdlist(:symmetric)
22-element Array{String,1}:
"cauchy"
"circul"
"clement"
"dingdong"
"fiedler"
"hankel"
"hilb"
"invhilb"
"kms"
"lehmer"
"minij"
"moler"
"oscillate"
"pascal"
"pei"
"poisson"
"prolate"
"randcorr"
"randsym"
"tridiag"
"wathen"
"wilkinson"
julia> listnames(:random)
list(13)
–––––––– ––––––––– –––––––– –––––––– ––––––– –––––––––– ––––––
erdrey golub randcorr randorth randsym rosser wathen
gilbert oscillate rando randsvd rohess smallworld
the function randsym
will be part of the groups :symmetric
and :random
while randorth
is in group :random
.
If we put our code in a package called MatrixDepotTemplate and our calls to include_generator and publish_user_generators inside the __init__ function, we could use our new generators by simply importing the package.:
julia> import MatrixDepot
julia> import MatrixDepotTemplate
julia> listnames(:random)
list(13)
–––––––– ––––––––– –––––––– –––––––– ––––––– –––––––––– ––––––
erdrey golub randcorr randorth randsym rosser wathen
gilbert oscillate rando randsvd rohess smallworld