Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.1.0 #6

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
# TypedMatrices.jl Documentation
# TypedMatrices.jl

Welcome to the documentation for TypedMatrices.jl.
Welcome to the documentation of `TypedMatrices.jl`, an extensible matrix collection for Julia. The matrices in the library can be used to test algorithms or check (and potentially disprove) linear algebra conjectures numerically.

An extensible Julia matrix collection utilizing type system to enhance performance.
The package relies on the Julia type system to enhance performance by improving the matrix generation time and reducing storage requirements.

Check [Getting Started](@ref) for a quick start.
To get started, check out the [Getting Started](@ref) section.

## Features

- Matrix Types: Types representing special matrices that can be used for algorithm testing or other computations.
- Linear Algebra Operations: Operations are fine-tuned to enhance the performance of these matrix types.
- Matrix Properties (Tags): Users can add properties (tags) to matrices, which can be used for organization or computation.
- Matrix Grouping: Matrices can be grouped together depending on types or properties, with the flexibility for users to define their own types.
- Filtering by Properties/Groups: Matrices can be filtered by property or group for more targeted computations.
- Each special matrix has its own Julia type, and users can define new types compatible with the package using the interface provided.
- Many linear algebra operations are implemented using explicit formulas, when known, to enhance performance.
- The matrices in the collection can be filtered by property, to find examples that satisfy a set of properties of interest.
- Users can create matrix groups to retrieve and organize the types in the collection.
63 changes: 39 additions & 24 deletions docs/src/manual/1.getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,85 +2,100 @@

## Installation

TypedMatrices.jl is a registered package in the Julia package registry. Use Julia's package manager to install it:
`TypedMatrices.jl` is registered in the Julia package registry, and Julia's builtin package manager can be used to install it:

```julia-repl
pkg> add TypedMatrices
```

## Setup

Use the package:
The first step is, as usual, to load the package:

```@repl getting-started
using TypedMatrices
```

You can list all matrices available with [`list_matrices`](@ref):
The list of available matrices can be obtained with [`list_matrices`](@ref):

```@repl getting-started
list_matrices()
matrix_list = list_matrices()
```

The function returns a `Vector` of matrix types, which are subtypes of `AbstractMatrix`. The elements of this `Vector` can be used to generate matrices:

```@repl getting-started
matrix_list[1](5)
```

## Creating Matrices
## Generating Matrices

Each type of matrix has its own type and constructors. For example, to create a 5x5 [Hilbert](@ref) matrix:
Each type of special matrices has its own type and constructors. For example, a 5 × 5 [Hilbert](@ref) matrix can be generated with:

```@repl getting-started
h = Hilbert(5)
```

Most matrices can accept a type parameter to specify the element type. For example, to create a 5x5 Hilbert matrix with `Float64` elements:
Most matrices can accept a type parameter to specify the element type. For example, a 5 × 5 Hilbert matrix with `Float64` elements can be generated with:

```@repl getting-started
Hilbert{Float64}(5)
```

Please check [Builtin Matrices](@ref) for all available builtin matrices.
Please check the list of [Builtin Matrices](@ref) for an overview of all available types.

## Properties

Matrix has properties like `symmetric`, `illcond`, and `posdef`. Function [`properties`](@ref) can be used to get the properties of a matrix:
Matrices have properties such as "symmetric", "ill conditioned", or "positive definite".

The function [`list_properties`](@ref) can be used to show all properties currently defined in `TypedMatrices.jl`:

```@repl getting-started
properties(Hilbert)
list_matrices()
```

You can also check properties of a matrix instance for convinience:
The function [`properties`](@ref) can used to get the properties of a given matrix type:

```@repl getting-started
properties(h)
properties(Hilbert)
```

To view all available properties, use [`list_properties`](@ref):
For convenience, the same function can be used to list the properties of a matrix instance, rather than a type:

```@repl getting-started
list_properties()
properties(h)
```

## Grouping

This package has a grouping feature to group matrices. All builtin matrices are in the `builtin` group, we also create a `user` group for user-defined matrices. You can list all groups with:
Matrices can be organized by creating user-defined groups. All builtin matrices belong to the `:builtin` group, and the package comes with an empty `:user` group for user-defined matrices. All available groups can be listed with:

```@repl getting-started
list_groups()
```

To add a matrix to groups and enable it to be listed by [`list_matrices`](@ref), use [`add_to_groups`](@ref):

The function [`add_to_groups`](@ref) can be used to add a matrix to a group:
```@repl getting-started
add_to_groups(Matrix, :user, :test)
```

The function [`list_matrices`](@ref) can be used to list the matrices that belong to a chosen group:

```@repl getting-started
list_matrices(Group(:user))
```

We can also add builtin matrices to our own groups:
Builtin matrices can also be added to a group:

```@repl getting-started
add_to_groups(Hilbert, :test)
list_matrices(Group(:test))
```

To remove a matrix from a group or all groups, use [`remove_from_group`](@ref) or [`remove_from_all_groups`](@ref). The empty group will automatically be removed:
A matrix can be removed
- from a specific group, with [`remove_from_group`](@ref), or
- from all groups, with [`remove_from_all_groups`](@ref).
Matrices cannot be removed from the `:builtin` group, and user-defined groups are automatically removed when they become empty:

```@repl getting-started
remove_from_group(Hilbert, :test)
Expand All @@ -90,16 +105,16 @@ list_groups()

## Finding Matrices

[`list_matrices`](@ref) is very powerful to list matrices, and filter by groups and properties. All arguments are "and" relationship, i.e. listed matrices must satisfy all conditions.
[`list_matrices`](@ref) is a powerful function to search for matrices, and filter the results by groups or properties. All arguments are "and" relationship, meaning that only matrices that satisfy all conditions will be retained.

For example, to list all matrices in the `builtin` group, and all matrices with `symmetric` property:
For example, one can list all the matrices in the `:builtin` group, or all those that are satisfy the `:symmetric` property:

```@repl getting-started
list_matrices(Group(:builtin))
list_matrices(Property(:symmetric))
```

To list all matrices in the `builtin` group with `inverse`, `illcond`, and `eigen` properties:
One can also combine the two filters and show all matrices in the `:builtin` group that satisfy the `:inverse`, `:illcond`, and `:eigen` properties:

```@repl getting-started
list_matrices(
Expand All @@ -114,10 +129,10 @@ list_matrices(
)
```

To list all matrices with `symmetric`, `eigen`, and `posdef` properties:
A simpler syntax can be used to list all matrices that satisfy a list of properties. For example, all matrices with `:symmetric`, `:eigen`, and `:posdef` can be listed with:

```@repl getting-started
list_matrices(:symmetric, :eigen, :posdef)
```

There are many alternative interfaces using `list_matrices`, please check the [`list_matrices`](@ref) or use Julia help system for more information.
The `list_matrices` functions provides a number of alternative interfaces. Check the full documentation of [`list_matrices`](@ref) or use the Julia help system for a complete list.
10 changes: 5 additions & 5 deletions docs/src/manual/2.performance.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Performance

We will briefly discuss the performance in this page.
We will give a few examples the illustrate the performance of the collection.

## Linear Algebra Properties of Typed Matrices

`LinearAlgebra.jl` provides several linear algebra operations. By utilizing the Julia type system, we can improve the performance of some of these operations for special matrices. The default method for the `issymmetric` function, for example, checks that a matrix satisfies the definition of symmetry by accessing each matrix element. The matrix `Minij` is explicitly known to be symmetric, and `TypedMatrices.jl` defines a new method for `issymmetric` that simply returns `true`.
`LinearAlgebra.jl` provides several linear algebra operations. By utilizing the Julia type system, we can improve the performance of some of these operations for special matrices. The default method for the `issymmetric` function, for example, checks that a matrix satisfies the definition of symmetry by accessing each matrix element. The matrix `Minij` is known to be symmetric, and `TypedMatrices.jl` defines a new method for `issymmetric` that simply returns `true`.

On the `Minij` matrix of order 1000 this specialised method is over 80,000 times faster than the default implementations in the median case.

Expand Down Expand Up @@ -44,7 +44,7 @@ BenchmarkTools.Trial: 4883 samples with 1 evaluation.

## Known Algorithm Working on `Hilbert`

The following example shows a known algorithm that works on `Hilbert` matrices. The variable `a` is of type `Hilbert`, and `b` represents the same matrix but is a variable of type `Matrix`. Computing the determinant of `b` is 280 times slower and requires almost 1,000 times more memory than computing that of `a`.
The following example shows a known algorithm that works on `Hilbert` matrices. The variable `a` is of type `Hilbert`, whereas `b` is a variable of type `Matrix` representing the same matrix. Computing the determinant of `b` is 280 times slower and requires almost 1,000 times more memory than computing that of `a`.

```julia-repl
julia> a = Hilbert{BigFloat}(100)
Expand Down Expand Up @@ -82,7 +82,7 @@ BenchmarkTools.Trial: 32 samples with 1 evaluation.

## Trade-off between Performance and Memory

For algorithms not implemented in `TypedMatrices.jl`, this approach trades performance off for potentially substantial memory savings. For example, generating the variable `a`, of type `Cauchy` only requires **63.229 μs** and **114.16 KiB** of memory, while generating `b`, which is the same matrix but has type `Matrix`, requires **3.862 ms** and **7.74 MiB** of memory. And once generated, storing `b` requires 500,000 times more memory than storing `a`.
For algorithms not implemented in `TypedMatrices.jl`, the package trades performance off forpotentially substantialmemory savings. For example, generating the variable `a`, which is of type `Cauchy`, only requires **63.229 μs** and **114.16 KiB** of memory, while generating `b`, which is the same matrix but has type `Matrix`, requires **3.862 ms** and **7.74 MiB** of memory. And once generated, storing `b` requires 500,000 times more memory than storing `a`.

```julia-repl
julia> @benchmark a = Cauchy{Float64}(1000)
Expand Down Expand Up @@ -116,7 +116,7 @@ julia> Base.summarysize(b)
8000040
```

On the other hand, accessing an element of `a` requires computation, which is not the case for the elements of `b`, which are directly available in memory. This implies a performance penalty, which is not unexpected. In view of this trade-off, however, one can use extremely large matrices on machines with a moderate amount of memory, which allows users to tackle otherwise intractable problems. This is especially true for algorithms that only need to access a subset of the matrix elements.
On the other hand, accessing an element of `a` requires computation, whereas those of `b` have been pre-computed and are already available in memory. This implies a performance penalty, which is not unexpected. In view of this trade-off, however, one can use extremely large matrices on machines with a moderate amount of memory, which allows users to tackle otherwise intractably large problems. This is especially true for algorithms that only need to access a subset of the matrix elements.

```julia-repl
julia> @benchmark det(a)
Expand Down
58 changes: 29 additions & 29 deletions docs/src/references/3.properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,41 @@ Some documentation of the following properties are adapted from MatrixDepot.jl.

```@docs
TypedMatrices.PropertyTypes.AbstractProperty
TypedMatrices.PropertyTypes.Symmetric
TypedMatrices.PropertyTypes.Inverse
TypedMatrices.PropertyTypes.Involutory
TypedMatrices.PropertyTypes.Integer
TypedMatrices.PropertyTypes.IllCond
TypedMatrices.PropertyTypes.PosDef
TypedMatrices.PropertyTypes.Bidiagonal
TypedMatrices.PropertyTypes.Binary
TypedMatrices.PropertyTypes.Circulant
TypedMatrices.PropertyTypes.Complex
TypedMatrices.PropertyTypes.Correlation
TypedMatrices.PropertyTypes.Eigen
TypedMatrices.PropertyTypes.Sparse
TypedMatrices.PropertyTypes.Random
TypedMatrices.PropertyTypes.RegProb
TypedMatrices.PropertyTypes.Defective
TypedMatrices.PropertyTypes.DiagonallyDominant
TypedMatrices.PropertyTypes.Eigensystem
TypedMatrices.PropertyTypes.FixedSize
TypedMatrices.PropertyTypes.Graph
TypedMatrices.PropertyTypes.TotNonNeg
TypedMatrices.PropertyTypes.TotPos
TypedMatrices.PropertyTypes.InfDiv
TypedMatrices.PropertyTypes.Hankel
TypedMatrices.PropertyTypes.Hessenberg
TypedMatrices.PropertyTypes.IllConditioned
TypedMatrices.PropertyTypes.Indefinite
TypedMatrices.PropertyTypes.Defective
TypedMatrices.PropertyTypes.InfinitelyDivisible
TypedMatrices.PropertyTypes.Integer
TypedMatrices.PropertyTypes.Inverse
TypedMatrices.PropertyTypes.Involutory
TypedMatrices.PropertyTypes.Nilpotent
TypedMatrices.PropertyTypes.Hessenberg
TypedMatrices.PropertyTypes.Toeplitz
TypedMatrices.PropertyTypes.Binary
TypedMatrices.PropertyTypes.RankDef
TypedMatrices.PropertyTypes.Circulant
TypedMatrices.PropertyTypes.Nonnegative
TypedMatrices.PropertyTypes.Normal
TypedMatrices.PropertyTypes.Orthogonal
TypedMatrices.PropertyTypes.Bidiagonal
TypedMatrices.PropertyTypes.Tridiagonal
TypedMatrices.PropertyTypes.Triangular
TypedMatrices.PropertyTypes.SingVal
TypedMatrices.PropertyTypes.Positive
TypedMatrices.PropertyTypes.PositiveDefinite
TypedMatrices.PropertyTypes.Random
TypedMatrices.PropertyTypes.RankDeficient
TypedMatrices.PropertyTypes.Rectangular
TypedMatrices.PropertyTypes.Hankel
TypedMatrices.PropertyTypes.DiagDom
TypedMatrices.PropertyTypes.NonNeg
TypedMatrices.PropertyTypes.RegularisationProblem
TypedMatrices.PropertyTypes.SingularValues
TypedMatrices.PropertyTypes.Sparse
TypedMatrices.PropertyTypes.Symmetric
TypedMatrices.PropertyTypes.Triangular
TypedMatrices.PropertyTypes.Tridiagonal
TypedMatrices.PropertyTypes.Toeplitz
TypedMatrices.PropertyTypes.TotallyNonnegative
TypedMatrices.PropertyTypes.TotallyPositive
TypedMatrices.PropertyTypes.Unimodular
TypedMatrices.PropertyTypes.Positive
TypedMatrices.PropertyTypes.FixedSize
TypedMatrices.PropertyTypes.Complex
```
10 changes: 5 additions & 5 deletions src/matrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ list_groups() = collect(keys(MATRIX_GROUPS))
"""
add_to_groups(type, groups)

Add a matrix type to groups. If a group is not exists, it will be created.
Add a matrix type to groups. If a group does not exist, it will be created.

Groups `:builtin` and `:user` are special groups. It is suggested always to add matrices to the `:user` group.

Expand Down Expand Up @@ -93,12 +93,12 @@ function remove_from_group(type::Type{<:AbstractMatrix}, group::Group)

# check group exists
if group ∉ keys(MATRIX_GROUPS)
throw(ArgumentError("Group $group not exists"))
throw(ArgumentError("Group $group does not exist"))
end

# check type exists in group
if type ∉ MATRIX_GROUPS[group]
throw(ArgumentError("Matrix type $type not exists in group $group"))
throw(ArgumentError("Matrix type $type does not exist in group $group"))
end

# remove from group
Expand Down Expand Up @@ -171,13 +171,13 @@ julia> list_matrices([Group(:builtin), Group(:user)])
"""
function list_matrices(groups::Vector{Group}, props::Vector{Property})
# check properties
check_properties_exists(props...)
check_properties_exist(props...)

# groups
groups_results = union(values(MATRIX_GROUPS)...)
for group = groups
if group ∉ keys(MATRIX_GROUPS)
throw(ArgumentError("Group $group not exists"))
throw(ArgumentError("Group $group does not exist"))
else
intersect!(groups_results, MATRIX_GROUPS[group])
end
Expand Down
9 changes: 5 additions & 4 deletions src/matrices/binomial.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""
Binomial Matrix
===============
The matrix is a multiple of an involutory matrix.
The binomial matrix is a multiple of an involutory matrix.

# Input Options
- dim: the dimension of the matrix.

# References
**G. Boyd, C.A. Micchelli, G. Strang and D.X. Zhou**,
Binomial matrices, Adv. in Comput. Math., 14 (2001), pp 379-391.
**G. Boyd, C. A. Micchelli, G. Strang and D. X. Zhou**,
Binomial matrices, Adv. Comput. Math., 14 (2001), pp. 379-391,
https://doi.org/10.1023/A:1012207124894.
"""
struct Binomial{T<:Number} <: AbstractMatrix{T}
n::Integer
Expand All @@ -23,7 +24,7 @@ end
Binomial(n::Integer) = Binomial{Int}(n)

# metadata
@properties Binomial [:involutory, :integer]
@properties Binomial [:integer] # It is not :involutory, but a multiple thereof.

# properties
size(A::Binomial) = (A.n, A.n)
Expand Down
11 changes: 6 additions & 5 deletions src/matrices/cauchy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ Given two vectors `x` and `y`, the `(i,j)` entry of the Cauchy matrix is
`1/(x[i]+y[j])`.

# Input Options
- x: an integer, as vectors 1:x and 1:x.
- x, y: two integers, as vectors 1:x and 1:y.
- x: a vector. `y` defaults to `x`.
- x, y: two vectors.
- x, y: two integers, as vectors `1:x` and `1:y``.
- x: an integer, as vectors `1:x`` and `1:x``.
- x: a vector. `y` defaults to `x`.

# References
**N. J. Higham**, Accuracy and Stability of Numerical Algorithms,
second edition, Society for Industrial and Applied Mathematics, Philadelphia, PA, USA,
2002; sec. 28.1
second edition, Society for Industrial and Applied Mathematics,
Philadelphia, PA, USA, 2002, https://doi.org/10.1137/1.9780898718027.
See sect. 28.1.
"""
struct Cauchy{T<:Number,X<:AbstractVector,Y<:AbstractVector} <: AbstractMatrix{T}
x::X
Expand Down
Loading
Loading