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

Improve Documentation #75

Merged
merged 1 commit into from
Jun 19, 2023
Merged
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
19 changes: 9 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ High performance extension for sparse matrices.
* Coordinate Format Matrix `SparseMatrixCOO`,
* Static Matrices `SSparseMatrixCSC`, `SPermMatrix` et. al.

with high performance `type convertion`, `kron` and `multiplication` operations.
with high performance type conversion, `kron`, and multiplication operations.

## Installation
Install with the package manager, `pkg> add LuxurySparse`.

## How to use
Here is a simple example
## Usage

```julia
using SparseArrays
Expand All @@ -28,17 +27,17 @@ pm = pmrand(7) # a random permutation matrix
id = IMatrix(3) # an identity matrix
@benchmark kron(pm, id) # kronecker product

Spm = pm |> SparseMatrixCSC # convertion to SparseMatrixCSC
Spm = pm |> SparseMatrixCSC # convert to SparseMatrixCSC
Sid = id |> SparseMatrixCSC
@benchmark kron(Spm, Sid) # compare the performance.
@benchmark kron(Spm, Sid) # compare the performance to the previous operation.

spm = pm |> staticize # convertion to static matrices, notice `id` is already static.
@benchmark kron(spm, spm) # compare the performance.
@benchmark kron(pm, pm) # compare the performance.
spm = pm |> staticize # convert to static matrix, notice that `id` is already static.
@benchmark kron(spm, spm) # compare performance
@benchmark kron(pm, pm)
```

For more information, please refer the latest [document](https://quantumbfs.github.io/LuxurySparse.jl/latest/).
For more information, please refer the latest [Documentation](https://quantumbfs.github.io/LuxurySparse.jl/latest/).

## Planned features
* Change `PermMatrix` to column major
* Better support to static matrices.
* Better support of conversion to static matrices
6 changes: 3 additions & 3 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ CurrentModule = LuxurySparse

*A "Luxury" sparse matrix library for julia language.*

[LuxurySparse](https://github.com/QuantumBFS/LuxurySparse.jl) is a Julia package from [QuantumBFS](https://github.com/QuantumBFS). It aims to provide powerful sparse matrix types for Julia, which is initially motivated by [quantum simulation](https://quantumbfs.github.io/Yao.jl/latest/).
[LuxurySparse](https://github.com/QuantumBFS/LuxurySparse.jl) is a Julia package from [QuantumBFS](https://github.com/QuantumBFS). It aims to provide powerful sparse matrix types for Julia, initially motivated by [Quantum Simulation](https://quantumbfs.github.io/Yao.jl/latest/).

It contains
* more sparse matrix types like `IMatrix`, `PermMatrix` and `SparseMatrixCOO`,
* high performance `type convertion`, `kron` and `multiplication` operations.
* more sparse matrix types like `IMatrix`, `PermMatrix` and `SparseMatrixCOO`
* high performance type conversion, `kron`, and multiplication operations.

## Manual

Expand Down
1 change: 1 addition & 0 deletions docs/src/luxurysparse.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ operations related to quantum gates.

```@autodocs
Modules = [LuxurySparse]
Private = false
Order = [:module, :constant, :type, :macro, :function]
```
65 changes: 44 additions & 21 deletions docs/src/tutorial.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Tutorial

## Generalized permutation matrix
## Generalized Permutation Matrix

### Example: Control-Y Gate in Quantum simulation
[Generalized permutation matrices](https://en.wikipedia.org/wiki/Generalized_permutation_matrix) are frequently used in fields such as quantum computation, group thoery. Here we see an example of Control-Y Gate
[Generalized permutation matrices](https://en.wikipedia.org/wiki/Generalized_permutation_matrix) are frequently used in fields such as quantum computation and group theory. Here we see an example of Control-Y Gate in matrix form:
```math
\left(\begin{matrix}
1 & 0 & 0 & 0\\
Expand All @@ -13,9 +13,10 @@
\end{matrix}\right)
```

This data structure can be represented in the form of `PermMatrix`
* perm: [1, 2, 4, 3]
* vals: [1, 1, -i, i]
We can represent the matrix using a `PermMatrix` type with the following fields:

* `perm`: [1, 2, 4, 3]
* `vals`: [1, 1, -i, i]

Now let's do a benchmark to feel the speed up

Expand All @@ -25,8 +26,9 @@ pm = PermMatrix([1,2,4,3], [1,1,-im,im])
```

```julia
using BenchmarkTools
v = randn(4)
@benchmark $pm*$v
@benchmark $pm*$v samples=100000 evals=1000
```
```
BenchmarkTools.Trial:
Expand All @@ -45,7 +47,7 @@ BenchmarkTools.Trial:
As a comparison
```julia
sp = SparseMatrixCSC(pm)
@benchmark $sp*$v
@benchmark $sp*$v samples=100000 evals=1000
```
```
BenchmarkTools.Trial:
Expand All @@ -62,7 +64,7 @@ BenchmarkTools.Trial:
```

## Identity Matrix
Identity matrix is static, which is defined as
The identity matrix is static and is defined as:
```
struct IMatrix{Tv} <: AbstractMatrix{Tv} end
```
Expand All @@ -76,19 +78,40 @@ B = randn(7,7);
```

```julia
@benchmark kron($Id, $B)
using BenchmarkTools
@benchmark kron($Id, $B) samples=100000 evals=1000
```
```
BenchmarkTools.Trial:
memory estimate: 0 bytes
allocs estimate: 0
--------------
minimum time: 1.642 ns (0.00% GC)
median time: 1.651 ns (0.00% GC)
mean time: 1.658 ns (0.00% GC)
maximum time: 32.101 ns (0.00% GC)
--------------
samples: 10000
evals/sample: 1000
BenchmarkTools.Trial: 100000 samples with 1000 evaluations.
Range (min … max): 3.333 ns … 22.667 ns ┊ GC (min … max): 0.00% … 0.00%
Time (median): 3.417 ns ┊ GC (median): 0.00%
Time (mean ± σ): 3.457 ns ± 0.343 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

▄ █ ▆ ▄ ▅ ▄ ▃ ▃ ▃
▆▁▁▁▁▁█▁▁▁▁▁█▁▁▁▁▁▁█▁▁▁▁▁█▁▁▁▁▁▁█▁▁▁▁▁█▁▁▁▁▁▁█▁▁▁▁▁█▁▁▁▁▁▇ █
3.33 ns Histogram: log(frequency) by time 3.71 ns <

Memory estimate: 0 bytes, allocs estimate: 0.
```
As a comparison
```julia
using LinearAlgebra, SparseArrays
spI = sparse(I, 7, 7)
@benchmark kron($spI, $B) samples=100000 evals=1000 seconds=3600
```
```
julia> @benchmark kron($spI, $B) samples=100000 evals=1000 seconds=3600
BenchmarkTools.Trial: 100000 samples with 1000 evaluations.
Range (min … max): 694.417 ns … 23.188 μs ┊ GC (min … max): 0.00% … 0.00%
Time (median): 1.117 μs ┊ GC (median): 0.00%
Time (mean ± σ): 1.499 μs ± 977.508 ns ┊ GC (mean ± σ): 28.57% ± 26.68%

▃██▃
▃▃▃▄▅████▆▄▃▂▂▂▂▂▂▂▂▂▂▂▂▁▂▁▁▁▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▃▃▃▃▃▃▃▃▃▃▃▃▂▂▂▂ ▃
694 ns Histogram: frequency by time 4.23 μs <

Memory estimate: 7.11 KiB, allocs estimate: 8.

```
With the help of Julia's multiple dispatch, the above trivil `kron` operation can be avoided.

With the help of Julia's multiple dispatch, a more performant `kron` operation can be implemented with LuxurySparse's `IMatrix` type versus the standard sparse identity matrix.
21 changes: 20 additions & 1 deletion src/IMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,26 @@
IMatrix(n) -> IMatrix
IMatrix(A::AbstractMatrix{T}) where T -> IMatrix

IMatrix matrix, with size N as label, use `Int64` as its default type, both `*` and `kron` are optimized.
Represents the Identity matrix with size `n`. `Int64` is its default type. Both `*` and `kron` are optimized.

# Example

```julia-repl
julia> IMatrix(4)
4×4 IMatrix{Bool}:
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

julia> IMatrix(rand(4,4))
4×4 IMatrix{Float64}:
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0

```
"""
struct IMatrix{Tv} <: AbstractMatrix{Tv}
n::Int
Expand Down
30 changes: 27 additions & 3 deletions src/PermMatrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,25 @@
PermMatrix(perm::Vector{Ti}, vals::Vector{Tv}) where {Tv, Ti}
PermMatrix(ds::AbstractMatrix)

PermMatrix represents a special kind linear operator: Permute and Multiply, which means `M * v = v[perm] * val`
Optimizations are used to make it much faster than `SparseMatrixCSC`.
PermMatrix represents a special kind of linear operator: Permute and Multiply, which means `M * v = v[perm] * val`
Optimized implementations of `inv` and `*` make it much faster than `SparseMatrixCSC`.

* `perm` is the permutation order,
* `vals` is the multiplication factor.

[Generalized Permutation Matrix](https://en.wikipedia.org/wiki/Generalized_permutation_matrix)

# Example

```julia-repl
julia> PermMatrix([2,1,4,3], rand(4))
4×4 SDPermMatrix{Float64, Int64, Vector{Float64}, Vector{Int64}}:
0.0 0.182251 0.0 0.0
0.887485 0.0 0.0 0.0
0.0 0.0 0.0 0.182831
0.0 0.0 0.22895 0.0

```
"""
struct PermMatrix{Tv,Ti<:Integer,Vv<:AbstractVector{Tv},Vi<:AbstractVector{Ti}} <:
AbstractMatrix{Tv}
Expand Down Expand Up @@ -74,7 +86,19 @@ Base.copyto!(A::PermMatrix, B::PermMatrix) =
"""
pmrand(T::Type, n::Int) -> PermMatrix

Return random PermMatrix.
Return a random [`PermMatrix`](@ref) with type `T`, `n` rows and `n` columns.

# Example

```julia-repl
julia> pmrand(ComplexF64, 4)
4×4 SDPermMatrix{ComplexF64, Int64, Vector{ComplexF64}, Vector{Int64}}:
0.0+0.0im 0.112104+0.0179632im 0.0+0.0im 0.0+0.0im
-0.0625997+1.00664im 0.0+0.0im 0.0+0.0im 0.0+0.0im
0.0+0.0im 0.0+0.0im 0.0+0.0im -0.0981836-0.839471im
0.0+0.0im 0.0+0.0im 0.735853-0.747084im 0.0+0.0im

```
"""
function pmrand end

Expand Down
17 changes: 16 additions & 1 deletion src/SparseMatrixCOO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

A sparse matrix in COOrdinate format.

Values `vs` are added to the matrix at rows `is` and columns `js` in a matrix with `m` rows and `n` columns.

Also known as the ‘ijv’ or ‘triplet’ format.

# Notes
Expand All @@ -24,6 +26,19 @@ does not directly support:
* COO is a fast format for constructing sparse matrices
* Once a matrix has been constructed, convert to CSR or CSC format for fast arithmetic and matrix vector operations
* By default when converting to CSR or CSC format, duplicate (i,j) entries will be summed together. This facilitates efficient construction of finite element matrices and the like. (see example)

# Example

```julia-repl
julia> SparseMatrixCOO([4,3,1,2,2], [2,3,1,4,4], [1,2,3,4,5], 4,4) # duplicate entries at (2,4) summed together
4×4 SparseMatrixCOO{Int64, Int64}:
3 0 0 0
0 0 0 9
0 0 2 0
0 1 0 0

```

"""
mutable struct SparseMatrixCOO{Tv,Ti} <: AbstractSparseMatrix{Tv,Ti}
is::Vector{Ti}
Expand Down Expand Up @@ -78,7 +93,7 @@ end
"""
allocated_coo(::Type, M::Int, N::Int, nnz::Int) -> SparseMatrixCOO

Construct a preallocated `SparseMatrixCOO` instance.
Construct a preallocated [`SparseMatrixCOO`](@ref) instance that holds values of `::Type` with `M` rows, `N` columns, and `nnz` nonzero elements.
"""
function allocated_coo(::Type{T}, M::Int, N::Int, nnz::Int) where {T}
SparseMatrixCOO{T}(undef, M, N, nnz)
Expand Down
5 changes: 3 additions & 2 deletions src/staticize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const SDSparseMatrixCSC{Tv,Ti} = Union{SparseMatrixCSC{Tv,Ti},SSparseMatrixCSC{T
"""
staticize(A::AbstractMatrix) -> AbastractMatrix

transform a matrix to a static form.
Transform a matrix to a static form by converting its representation to types from StaticArrays.jl.
Enables faster linear algebra operations.
"""
function staticize end
staticize(x) = x # do nothing if it is not defined
Expand Down Expand Up @@ -39,7 +40,7 @@ end
"""
dynamicize(A::AbstractMatrix) -> AbastractMatrix

transform a matrix to a dynamic form.
Converts matrices dependent on StaticArrays.jl types to Julia-standard ones.
"""
function dynamicize end
dynamicize(x) = x # do nothing if it is not defined
Expand Down
1 change: 0 additions & 1 deletion src/utils.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
"""faster invperm"""
function fast_invperm(order)
v = similar(order)
@inbounds @simd for i = 1:length(order)
Expand Down