Giter Club home page Giter Club logo

luxurysparse.jl's Introduction

LuxurySparse.jl

Build Status Codecov

High performance extension for sparse matrices.

Contents

  • General Permutation Matrix PermMatrix,
  • Identity Matrix IMatrix,
  • Coordinate Format Matrix SparseMatrixCOO,
  • Static Matrices SSparseMatrixCSC, SPermMatrix et. al.

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

Installation

Install with the package manager, pkg> add LuxurySparse.

Usage

using SparseArrays
using LuxurySparse
using BenchmarkTools

pm = pmrand(7)  # a random permutation matrix
id = IMatrix(3) # an identity matrix
@benchmark kron(pm, id) # kronecker product

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

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 Documentation.

Planned features

  • Change PermMatrix to column major
  • Better support of conversion to static matrices

luxurysparse.jl's People

Contributors

chenzhao44 avatar giggleliu avatar github-actions[bot] avatar johnzl-777 avatar juliatagbot avatar kristofferc avatar mortenpi avatar roger-luo avatar weinbe58 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

luxurysparse.jl's Issues

rm type piracy

This package contains a lot workarounds which contains type piracy, need to check if they are in Base already or PR to upstream.

overload 3-arg and 5-arg mul!

the 3-arg and 5-arg mul! is quite useful for ODE solvers, e.g the 5-arg mul! can be used in ODE solver directly and has no allocation comparing to apply! in YaoArrayRegister will require a copy of the state

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

IMatrix cause error in linop2dense

# Intrinsics/Math.jl: 146
linop2dense(applyfunc!::Function, num_bit::Int) = applyfunc!(Matrix{ComplexF64}(I, 1<<num_bit, 1<<num_bit))

The result is incorrect when you use IMatrix, however IMatrix should act exactly like a dense identity, except it does not allocate memory.

show fails for SSparseMatrixCSC

The following example lightly adapted from the README

using SparseArrays
using LuxurySparse

pm = pmrand(7)

Spm = pm |> SparseMatrixCSC

spm = Spm |> staticize

@show spm

fails with a MethodError: no method matching _checkbuffers(::SSparseMatrixCSC{Float64, Int64, 7, 8}). The _checkbuffers method is called from Base.array_summary .

Add a type for scaled matrix?

Currently, things like sqrt(im * X) etc. is actually unitary, it can be constructed in this form

1/sqrt(2) * [1 -i;-i 1]

This will actually make some results incorrect without caution (e.g testing Clifford group), but it reduces readability if we directly normalize them instead of printing the definition above. Thus defining a Unitary would help, it will store the original matrix and its normalization factor:

struct ScaledMatrix{T, MT <: AbstractMatrix}
    factor::T
    parent::MT
end

Sparse Kronecker sums

Right now, I'm working on in-place, CPU versions of kronsum(A,B) = kron(A, oneunit(B)) + kron(oneunit(A), B)

So far, this works for dense arrays:

function kronsum!(C::AbstractMatrix, A::AbstractMatrix, B::AbstractMatrix)
    Base.require_one_based_indexing(A, B)
    (mA, nA) = size(A); (mB, nB) = size(B); (mC, nC) = size(C);
    @boundscheck (mC, nC) == (mA * mB, nA * nB) ||
        throw(DimensionMismatch("expect C to be a $(mA * mB)x$(nA * nB) matrix, got size $(mC)x$(nC)"))

    C .= 0
    m = 1
    @inbounds for j = 1:nA
        for l = 1:mB
            for k = 1:mA
                C[m] = A[k,j]
                m += nB
            end
            m += 1
        end
        m -= nB
    end

    m = 1
    @inbounds for j = 1:nA
        for k = 1:nB
            for l = 1:mB
                C[m] += B[l,k]
                m += 1
            end
            m += (nA - 1) * mB
        end
        m += mB
    end

    return C
end
A = rand(3,3); B = rand(2,2); C = zeros(6,6);
C == kron(A, oneunit(B)) + kron(oneunit(A), B) # true

I'm having trouble doing something similar with SparseMatrixCSC, since parts of A and B only overlap on the diagonal of C.

Using Diagonal Format (from DIA.jl) could work, but I think converting to CSC would take too much time (especially if either A or B are sparse) and there's the risk of storing too many zeroes for the diagonal storage Vectors.

Currently, I'm inspired by the sparse kron! in JuliaLang/julia#31069. It works for either kron(A,oneunit(B)) or kron(oneunit(A), B), but not the sum.

  • Could I use two loops like I did for the dense arrays? (One nested loop for A, the other for B)
  • Can I somehow efficiently check if an index points to a diagonal term of C where C isa SparseMatrixCSC?

SparseMatrixCOO with duplicated keys

julia> coo1 = SparseMatrixCOO(
           [1, 4, 2, 3, 3, 3],
           [1, 1, 2, 4, 3, 4],
           [0.1, 0.2, 0.4im, 0.5, 0.3, 0.5im],
           4,
           4,
       )
4×4 SparseMatrixCOO{Complex{Float64},Int64}:
 0.1+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.4im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  0.3+0.0im  0.5+0.5im
 0.2+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im

julia> coo1[3,3] = 3.0
3.0

julia> coo1
4×4 SparseMatrixCOO{Complex{Float64},Int64}:
 0.1+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.4im  0.0+0.0im  0.0+0.0im
 0.0+0.0im  0.0+0.0im  3.3+0.0im  0.5+0.5im
 0.2+0.0im  0.0+0.0im  0.0+0.0im  0.0+0.0im

code Polish tracking issue

  • some place like this only need one @inbounds, not a big problem though
  • benchmark

@inbounds @simd for j = 1:nV

  • Use view or use view when this is larger than a threshold.
  • benchmark

source = A[:,j]

  • LLVM could have bad performance here, for nested loop.
  • benchmark

@inbounds for j in 1:Na

  • this could cause failure on SIMD
  • benchmark

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.