Skip to content

Commit

Permalink
move LuxurySparse.jl from Yao.jl.
Browse files Browse the repository at this point in the history
    license:  MIT
    authors:  Roger-luo
    years:    2018

fix travis deprecations

fix typo: statify->staticize

rename to staticize
  • Loading branch information
Roger-luo committed Aug 8, 2018
1 parent 11cd41f commit 588c0fc
Show file tree
Hide file tree
Showing 28 changed files with 1,323 additions and 0 deletions.
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
comment: false
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
*.jl.cov
*.jl.*.cov
*.jl.mem

docs/build/
docs/site/

*.ipynb_checkpoints
**/*.ipynb_checkpoints
**/**/*.ipynb_checkpoints

_*.dat
*.swp
__pycache__/

Manifest.toml
35 changes: 35 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
- osx
julia:
- 0.7
- nightly
notifications:
email: false
git:
depth: 99999999

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
#matrix:
# allow_failures:
# - julia: nightly

## uncomment and modify the following lines to manually install system packages
#addons:
# apt: # apt-get for linux
# packages:
# - gfortran
#before_script: # homebrew for mac
# - if [ $TRAVIS_OS_NAME = osx ]; then brew install gcc; fi

## uncomment the following lines to override the default test script
#script:
# - julia -e 'Pkg.clone(pwd()); Pkg.build("LuxurySparse"); Pkg.test("LuxurySparse"; coverage=true)'
after_success:
# push coverage results to Coveralls
- julia -e 'using Pkg; cd(Pkg.dir("LuxurySparse")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'
# push coverage results to Codecov
- julia -e 'using Pkg; cd(Pkg.dir("LuxurySparse")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
22 changes: 22 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
The LuxurySparse.jl package is licensed under the MIT "Expat" License:

> Copyright (c) 2018: Roger-luo.
>
> Permission is hereby granted, free of charge, to any person obtaining a copy
> of this software and associated documentation files (the "Software"), to deal
> in the Software without restriction, including without limitation the rights
> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> copies of the Software, and to permit persons to whom the Software is
> furnished to do so, subject to the following conditions:
>
> The above copyright notice and this permission notice shall be included in all
> copies or substantial portions of the Software.
>
> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> SOFTWARE.
>
17 changes: 17 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name = "LuxurySparse"
uuid = "72cad168-9621-11e8-1b1e-73228c0c6ca7"
authors = ["Roger-luo <hiroger@qq.com>"]
version = "0.0.0"

[deps]
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# LuxurySparse

[![Build Status](https://travis-ci.org/QuantumBFS/LuxurySparse.jl.svg?branch=master)](https://travis-ci.org/QuantumBFS/LuxurySparse.jl)

This package contains

* General Permutation Matrix,
* Identity Matrix,

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

`LuxurySparse.jl` is still a part of [Yao.jl](https://github.com/QuantumBFS/Yao.jl) (a quantum circuit simulation package).
Its document is maintained [here](https://quantumbfs.github.io/Yao.jl/latest/man/luxurysparse/).
It will be moved out of `Yao.jl` completely and start to accept PR soon.
3 changes: 3 additions & 0 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
julia 0.7
Compat
StaticArrays
47 changes: 47 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.7-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.7-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
#matrix:
# allow_failures:
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

branches:
only:
- master
- /release-.*/

notifications:
- provider: Email
on_build_success: false
on_build_failure: false
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# If there's a newer build queued for the same PR, cancel this one
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"LuxurySparse\"); Pkg.build(\"LuxurySparse\")"

test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"LuxurySparse\")"
1 change: 1 addition & 0 deletions benchmarks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Benchmark
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# LuxurySparse Documentation
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
using Documenter
3 changes: 3 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# LuxurySparse

A luxury sparse library for julia language.
69 changes: 69 additions & 0 deletions src/Core.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"""
swaprows!(v::VecOrMat, i::Int, j::Int[, f1, f2]) -> VecOrMat
swap row i and row j of v inplace, with f1, f2 factors applied on i and j (before swap).
"""
function swaprows! end

"""
swapcols!(v::VecOrMat, i::Int, j::Int[, f1, f2]) -> VecOrMat
swap col i and col j of v inplace, with f1, f2 factors applied on i and j (before swap).
"""
function swapcols! end

"""
u1rows!(state::VecOrMat, i::Int, j::Int, a, b, c, d) -> VecOrMat
apply u1 on row i and row j of state inplace.
"""
function u1rows! end

"""
mulcol!(v::Vector, i::Int, f) -> VecOrMat
multiply col i of v by f inplace.
"""
function mulcol! end

"""
mulrow!(v::Vector, i::Int, f) -> VecOrMat
multiply row i of v by f inplace.
"""
function mulrow! end


"""
matvec(x::VecOrMat) -> MatOrVec
Return vector if a matrix is a column vector, else untouched.
"""
function matvec end

"""
notdense(M) -> Bool
Return true if a matrix is not dense.
Note:
It is not exactly same as isparse, e.g. Diagonal, IMatrix and PermMatrix are both notdense but not isparse.
"""
function notdense end

notdense(M)::Bool = issparse(M)
@static if VERSION >= v"0.7-"
notdense(x::Transpose) = notdense(parent(x))
notdense(x::Adjoint) = notdense(parent(x))
end

"""faster invperm"""
function fast_invperm(order)
v = similar(order)
@inbounds @simd for i=1:length(order)
v[order[i]] = i
end
v
end

dropzeros!(A::Diagonal) = A
23 changes: 23 additions & 0 deletions src/IMatrix.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""
IMatrix{N, Tv}()
IMatrix{N}() where N = IMatrix{N, Int64}()
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.
"""
struct IMatrix{N, Tv} <: AbstractMatrix{Tv} end
IMatrix{N}() where N = IMatrix{N, Bool}()
IMatrix(N::Int) = IMatrix{N}()

size(A::IMatrix{N}, i::Int) where N = N
size(A::IMatrix{N}) where N = (N, N)
getindex(A::IMatrix{N, T}, i::Integer, j::Integer) where {N, T} = T(i==j)

####### sparse matrix ######
nnz(M::IMatrix{N}) where N = N
nonzeros(M::IMatrix{N, T}) where {N, T} = ones(T, N)
ishermitian(D::IMatrix) = true
notdense(::IMatrix) = true

similar(::IMatrix{N, Tv}, ::Type{T}) where {N, Tv, T} = IMatrix{N, T}()
copyto!(A::IMatrix{N}, B::IMatrix{N}) where N = A
25 changes: 25 additions & 0 deletions src/LuxurySparse.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module LuxurySparse

using LinearAlgebra, SparseArrays, Random
using StaticArrays: SVector, SMatrix

import Base: copyto!
import LinearAlgebra: ishermitian
import SparseArrays: SparseMatrixCSC, nnz, nonzeros, dropzeros!, findnz
import Base: getindex, size, similar, copy, show

export PermMatrix, pmrand, IMatrix, I, fast_invperm, notdense
export staticize, SSparseMatrixCSC, SDiagonal

include("Core.jl")
include("IMatrix.jl")
include("PermMatrix.jl")

include("conversions.jl")
include("promotions.jl")
include("staticize.jl")
include("arraymath.jl")
include("linalg.jl")
include("kronecker.jl")

end
76 changes: 76 additions & 0 deletions src/PermMatrix.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""
PermMatrix{Tv, Ti}(perm::Vector{Ti}, vals::Vector{Tv}) where {Tv, Ti<:Integer}
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`.
* `perm` is the permutation order,
* `vals` is the multiplication factor.
[Generalized Permutation Matrix](https://en.wikipedia.org/wiki/Generalized_permutation_matrix)
"""
struct PermMatrix{Tv, Ti<:Integer, Vv<:AbstractVector{Tv}, Vi<:AbstractVector{Ti}} <: AbstractMatrix{Tv}
perm::Vi # new orders
vals::Vv # multiplied values.

function PermMatrix{Tv, Ti, Vv, Vi}(perm::Vi, vals::Vv) where {Tv, Ti<:Integer, Vv<:AbstractVector{Tv}, Vi<:AbstractVector{Ti}}
if length(perm) != length(vals)
throw(DimensionMismatch("permutation ($(length(perm))) and multiply ($(length(vals))) length mismatch."))
end
new{Tv, Ti, Vv, Vi}(perm, vals)
end
end

function PermMatrix{Tv, Ti}(perm, vals) where {Tv, Ti<:Integer}
PermMatrix{Tv, Ti, Vector{Tv}, Vector{Ti}}(Vector{Ti}(perm), Vector{Tv}(vals))
end

function PermMatrix(perm::Vi, vals::Vv) where {Tv, Ti<:Integer, Vv<:AbstractVector{Tv}, Vi<:AbstractVector{Ti}}
PermMatrix{Tv,Ti, Vv, Vi}(perm, vals)
end

################# Array Functions ##################

size(M::PermMatrix) = (length(M.perm), length(M.perm))
function size(A::PermMatrix, d::Integer)
if d < 1
throw(ArgumentError("dimension must be ≥ 1, got $d"))
elseif d<=2
return length(A.perm)
else
return 1
end
end
getindex(M::PermMatrix, i::Integer, j::Integer) = M.perm[i] == j ? M.vals[i] : 0
copyto!(A::PermMatrix, B::PermMatrix) = (copyto!(A.perm, B.perm); copyto!(A.vals, B.vals); A)

"""
pmrand(T::Type, n::Int) -> PermMatrix
Return random PermMatrix.
"""
function pmrand end

pmrand(::Type{T}, n::Int) where T = PermMatrix(randperm(n), randn(T, n))
pmrand(n::Int) = pmrand(Float64, n)

similar(x::PermMatrix{Tv, Ti}) where {Tv, Ti} = PermMatrix{Tv, Ti}(similar(x.perm), similar(x.vals))
similar(x::PermMatrix{Tv, Ti}, ::Type{T}) where {Tv, Ti, T} = PermMatrix{T, Ti}(similar(x.perm), similar(x.vals, T))

# TODO: rewrite this
# function show(io::IO, M::PermMatrix)
# println("PermMatrix")
# for item in zip(M.perm, M.vals)
# i, p = item
# println("- ($i) * $p")
# end
# end

######### sparse array interfaces #########
nnz(M::PermMatrix) = length(M.vals)
nonzeros(M::PermMatrix) = M.vals
dropzeros!(M::PermMatrix) = M
notdense(::PermMatrix) = true
notdense(::Diagonal) = true
Loading

0 comments on commit 588c0fc

Please sign in to comment.