Skip to content

Commit

Permalink
Merge pull request #10 from lopezm94/v0.1.0
Browse files Browse the repository at this point in the history
V0.1.0 Remove Combinatorics dependency and stop supporting Julia versions lower than 1.0
  • Loading branch information
lopezm94 authored Mar 31, 2019
2 parents 619e573 + fc744c2 commit ecc405b
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 76 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
*.jl.cov
*.jl.*.cov
*.jl.mem

*.swp

/Manifest.toml
16 changes: 8 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ language: julia
os:
- linux
julia:
- 0.5
- 0.6
- 1.0
- 1.1
- nightly
matrix:
allow_failures:
- julia: nightly
notifications:
email: false

script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.clone(pwd()); Pkg.build("SugarBLAS"); Pkg.test("SugarBLAS"; coverage=true)'
after_success:
- julia -e 'cd(Pkg.dir("SugarBLAS")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'cd(Pkg.dir("SugarBLAS")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
- julia --project=coverage/ -e 'using Pkg; Pkg.instantiate()'
- julia --project=coverage/ coverage/coverage.jl
- julia --project=coverage/ coverage/coveralls.jl
2 changes: 2 additions & 0 deletions .travis/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[deps]
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
7 changes: 7 additions & 0 deletions .travis/coverage.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
get(ENV, "TRAVIS_OS_NAME", "") == "linux" || exit()

using Coverage

cd(joinpath(dirname(@__FILE__), "..")) do
Codecov.submit(Codecov.process_folder())
end
7 changes: 7 additions & 0 deletions .travis/coveralls.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
get(ENV, "TRAVIS_OS_NAME", "") == "linux" || exit()

using Coverage

cd(joinpath(dirname(@__FILE__), "..")) do
Coveralls.submit(process_folder())
end
10 changes: 10 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name = "SugarBLAS"
uuid = "0999239e-cb9f-5507-94be-17f19fa7f34d"
authors = ["Juan Antonio López Mendoza <[email protected]>"]
version = "0.1.0"

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

[targets]
test = ["Test"]
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,70 +250,70 @@ julia> macroexpand(SugarBLAS, :(SugarBLAS.@ger! A += alpha*x*y'))

### *syr!*

Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*x.' + A`.
Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*(x)ᵀ + A`.
When left side has `A['U']` the upper triangle of `A` is updated (`'L'` for lower
triangle). Return `A`.

**Polynomials**

- `A[uplo] ±= alpha*x*x.'`
- `A[uplo] ±= alpha*x*(x)ᵀ`

**Example**

```julia
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syr! A['U'] -= alpha*x*x.'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syr! A['U'] -= alpha*x*(x)ᵀ))
:(Base.LinAlg.BLAS.syr!('U',-alpha,x,A))

julia> macroexpand(SugarBLAS, :(SugarBLAS.@syr! A['L'] += alpha*x*x.'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syr! A['L'] += alpha*x*(x)ᵀ))
:(Base.LinAlg.BLAS.syr!('L',alpha,x,A))
```


### *syrk*

Return either the upper triangle or the lower triangle, depending on
(`'U'` or `'L'`), of `alpha*A*A.'` or `alpha*A.'*A`.
(`'U'` or `'L'`), of `alpha*A*(A)ᵀ` or `alpha*(A)ᵀ*A`.

**Polynomials**

- `alpha*A*A.' uplo=ul`
- `alpha*A.'*A uplo=ul`
- `alpha*A*(A)ᵀ uplo=ul`
- `alpha*(A)ᵀ*A uplo=ul`

**Example**

```julia
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk alpha*A*A.' uplo='U'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk alpha*A*(A)ᵀ uplo='U'))
:(Base.LinAlg.BLAS.syrk('U','N',alpha,A))

julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk alpha*A.'*A uplo='L'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk alpha*(A)ᵀ*A uplo='L'))
:(Base.LinAlg.BLAS.syrk('L','T',alpha,A))
```


### *syrk!*

Rank-k update of the symmetric matrix `C` as `alpha*A*A.' + beta*C` or
`alpha*A.'*A + beta*C`. When the left hand side is`C['U']` the upper triangle of `C`
Rank-k update of the symmetric matrix `C` as `alpha*A*(A)ᵀ + beta*C` or
`alpha*(A)ᵀ*A + beta*C`. When the left hand side is`C['U']` the upper triangle of `C`
is updated (`'L'` for lower triangle). Return `C`.

**Polynomials**

- `C[uplo] ±= alpha*A*A.'`
- `C[uplo] = beta*C ± alpha*A.'*A`
- `C[uplo] ±= alpha*A*(A)ᵀ`
- `C[uplo] = beta*C ± alpha*(A)ᵀ*A`

**Example**

```julia
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['U'] -= alpha*A*A.'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['U'] -= alpha*A*(A)ᵀ))
:(Base.LinAlg.BLAS.syrk!('U','N',-alpha,A,1.0,C))

julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['L'] = beta*C - alpha*A.'*A))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['L'] = beta*C - alpha*(A)ᵀ*A))
:(Base.LinAlg.BLAS.syrk!('L','T',-alpha,A,beta,C))

julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['U'] += alpha*A*A.'))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['U'] += alpha*A*(A)ᵀ))
:(Base.LinAlg.BLAS.syrk!('U','N',alpha,A,1.0,C))

julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['L'] = alpha*A.'*A + beta*C))
julia> macroexpand(SugarBLAS, :(SugarBLAS.@syrk! C['L'] = alpha*(A)ᵀ*A + beta*C))
:(Base.LinAlg.BLAS.syrk!('L','T',alpha,A,beta,C))
```

Expand Down
4 changes: 1 addition & 3 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
julia 0.5

Combinatorics
julia 1.0
Binary file removed src/Match/.Match.jl.swp
Binary file not shown.
68 changes: 65 additions & 3 deletions src/Match/Match.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ Extract expression sub-trees.
"""
module Match

using Combinatorics

export @match
export unkeyword!

Expand All @@ -23,7 +21,7 @@ end
iscommutative(op::Symbol) = _iscommutative(Val{op})

_iscommutative(::Type{Val{:(+)}}) = true
_iscommutative{T<:Val}(::Type{T}) = false
_iscommutative(::Type{T}) where T<:Val = false

"""
Output true if dictionary 'd' has a key 's' with a different value than 'v'.
Expand Down Expand Up @@ -140,4 +138,68 @@ function unkeyword!(expr::Expr)
expr
end

struct Permutations{T}
a::T
t::Int
end

Base.eltype(::Type{Permutations{T}}) where {T} = Vector{eltype(T)}

Base.length(p::Permutations) = (0 <= p.t <= length(p.a)) ? factorial(length(p.a), length(p.a)-p.t) : 0

"""
permutations(a)
Generate all permutations of an indexable object `a` in lexicographic order. Because the number of permutations
can be very large, this function returns an iterator object.
Use `collect(permutations(a))` to get an array of all permutations.
"""
permutations(a) = Permutations(a, length(a))

"""
permutations(a, t)
Generate all size `t` permutations of an indexable object `a`.
"""
function permutations(a, t::Integer)
if t < 0
t = length(a) + 1
end
Permutations(a, t)
end

function Base.iterate(p::Permutations, s = collect(1:length(p.a)))
(!isempty(s) && max(s[1], p.t) > length(p.a) || (isempty(s) && p.t > 0)) && return
nextpermutation(p.a, p.t ,s)
end

function nextpermutation(m, t, state)
perm = [m[state[i]] for i in 1:t]
n = length(state)
if t <= 0
return(perm, [n+1])
end
s = copy(state)
if t < n
j = t + 1
while j <= n && s[t] >= s[j]; j+=1; end
end
if t < n && j <= n
s[t], s[j] = s[j], s[t]
else
if t < n
reverse!(s, t+1)
end
i = t - 1
while i>=1 && s[i] >= s[i+1]; i -= 1; end
if i > 0
j = n
while j>i && s[i] >= s[j]; j -= 1; end
s[i], s[j] = s[j], s[i]
reverse!(s, i+1)
else
s[1] = n+1
end
end
return (perm, s)
end

end
38 changes: 18 additions & 20 deletions src/SugarBLAS.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ Syntactic sugar for BLAS polynomials.
"""
module SugarBLAS

export
export @blas!

include("Match/Match.jl")
using .Match

structend

"""
Negate a number, symbol or expression
"""
Expand All @@ -28,11 +31,6 @@ Determine whether it is a substraction or not
substracts(expr) = false
substracts(expr::Expr) = (expr.head == :call) & (expr.args[1] == :-)

"""
Sugarcoat '.isnull'
"""
isempty(nl::Nullable) = nl.isnull

"""
Make dictionary containing the kwargs contents.
"""
Expand Down Expand Up @@ -244,21 +242,21 @@ end
"""
@syr!(expr)
Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*x.' + A`.
Rank-1 update of the symmetric matrix `A` with vector `x` as `alpha*x*xᵀ + A`.
When left side has `A['U']` the upper triangle of `A` is updated (`'L'` for lower
triangle). Return `A`.
**Polynomials**
- `A[uplo] ±= alpha*x*x.'`
- `A[uplo] ±= alpha*x*xᵀ`
"""
macro syr!(expr::Expr)
unkeyword!(expr)
expr = expand(expr)
@match(expr, A[uplo] = right) || error("No match found")
f = @case begin
@match(right, alpha*x*x.' + Y) => identity
@match(right, Y - alpha*x*x.') => neg
@match(right, alpha*x*xᵀ + Y) => identity
@match(right, Y - alpha*x*xᵀ) => neg
otherwise => error("No match found")
end
(@match(Y, Y[uplo]) && (Y == A)) || (Y == A) || error("No match found")
Expand All @@ -269,12 +267,12 @@ end
@syrk!(expr)
Return either the upper triangle or the lower triangle, depending on
(`'U'` or `'L'`), of `alpha*A*A.'` or `alpha*A.'*A`.
(`'U'` or `'L'`), of `alpha*A*(A)ᵀ` or `alpha*(A)ᵀ*A`.
**Polynomials**
- `alpha*A*A.' uplo=ul`
- `alpha*A.'*A uplo=ul`
- `alpha*A*(A)ᵀ uplo=ul`
- `alpha*(A)ᵀ*A uplo=ul`
"""
macro syrk(expr::Expr, kwargs...)
kwargs = kwargs_to_dict(kwargs)
Expand All @@ -284,8 +282,8 @@ macro syrk(expr::Expr, kwargs...)
otherwise => error("No match found")
end
trans = @case begin
@match(X, A.') && (Y == A) => 'T'
@match(Y, A.') && (X == A) => 'N'
@match(X, (A)ᵀ) && (Y == A) => 'T'
@match(Y, (A)ᵀ) && (X == A) => 'N'
otherwise => error("No match found")
end
@call Base.LinAlg.BLAS.syrk(uplo,trans,f(alpha),A)
Expand All @@ -294,14 +292,14 @@ end
"""
@syrk!(expr)
Rank-k update of the symmetric matrix `C` as `alpha*A*A.' + beta*C` or
`alpha*A.'*A + beta*C`. When the left hand side is`C['U']` the upper triangle of `C`
Rank-k update of the symmetric matrix `C` as `alpha*A*(A)ᵀ + beta*C` or
`alpha*(A)ᵀ*A + beta*C`. When the left hand side is`C['U']` the upper triangle of `C`
is updated (`'L'` for lower triangle). Return `C`.
**Polynomials**
- `C[uplo] ±= alpha*A*A.'`
- `C[uplo] = beta*C ± alpha*A.'*A`
- `C[uplo] ±= alpha*A*(A)ᵀ`
- `C[uplo] = beta*C ± alpha*(A)ᵀ*A`
"""
macro syrk!(expr::Expr)
unkeyword!(expr)
Expand All @@ -313,8 +311,8 @@ macro syrk!(expr::Expr)
otherwise => error("No match found")
end
trans = @case begin
@match(X, A.') && (Y == A) => 'T'
@match(Y, A.') && (X == A) => 'N'
@match(X, (A)ᵀ) && (Y == A) => 'T'
@match(Y, (A)ᵀ) && (X == A) => 'N'
otherwise => error("No match found")
end
@match(D, beta*D) || (beta = 1.0)
Expand Down
Loading

0 comments on commit ecc405b

Please sign in to comment.