Skip to content

Commit

Permalink
docs(docs): update documentation landing page and manual
Browse files Browse the repository at this point in the history
  • Loading branch information
mfasi committed Oct 10, 2024
1 parent 065278d commit e40cd28
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 38 deletions.
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 approach in `TypedMatrices.jl` 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

0 comments on commit e40cd28

Please sign in to comment.