Skip to content
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
11 changes: 6 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- 1.0
- nightly
matrix:
allow_failures:
Expand All @@ -14,7 +15,7 @@ notifications:
# script:
# - julia -e 'Pkg.clone(pwd()); Pkg.build("AbstractOperators"); Pkg.test("AbstractOperators"; coverage=true)'
after_success:
- julia -e 'cd(Pkg.dir("AbstractOperators")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
- julia -e 'cd(Pkg.dir("AbstractOperators")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'Pkg.add("Documenter")'
- julia -e 'cd(Pkg.dir("AbstractOperators")); include(joinpath("docs", "make.jl"))'
- julia -e 'using Pkg; cd(Pkg.dir("AbstractOperators")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
- julia -e 'using Pkg; cd(Pkg.dir("AbstractOperators")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'using Pkg; Pkg.add("Documenter")'
- julia -e 'using Pkg; cd(Pkg.dir("AbstractOperators")); include(joinpath("docs", "make.jl"))'
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ This is particularly useful in iterative algorithms and in first order large-sca

## Installation

To install the package, use the following in the Julia command line
To install the package, hit `]` from the Julia command line to enter the package manager, then

```julia
Pkg.add("AbstractOperators")
pkg> add AbstractOperators
```

Remember to `Pkg.update()` to keep the package up to date.

## Usage

With `using AbstractOperators` the package imports several methods like multiplication `*` and transposition `'` (and their in-place methods `A_mul_B!`, `Ac_mul_B!`).
With `using AbstractOperators` the package imports several methods like multiplication `*` and adjoint transposition `'` (and their in-place methods `mul!`).

For example, one can create a 2-D Discrete Fourier Transform as follows:

Expand All @@ -45,13 +43,13 @@ julia> y = A*x
-0.905575+1.98446im 0.441199-0.913338im 0.315788+3.29666im 0.174273+0.318065im
-0.905575-1.98446im 0.174273-0.318065im 0.315788-3.29666im 0.441199+0.913338im

julia> A_mul_B!(y,A,x) == A*x #in-place evaluation
julia> mul!(y, A, x) == A*x #in-place evaluation
true

julia> all(A'*y - *(size(x)...)*x .< 1e-12)
true

julia> Ac_mul_B!(x,A,y) #in-place evaluation
julia> mul!(x, A',y) #in-place evaluation
3×4 Array{Float64,2}:
-2.99091 9.45611 -19.799 1.6327
-11.1841 11.2365 -26.3614 11.7261
Expand Down Expand Up @@ -97,6 +95,11 @@ julia> V*ones(3,3)

A list of the available `AbstractOperators` and calculus rules can be found in the [documentation](https://kul-forbes.github.io/AbstractOperators.jl/latest).

## Related packages

* [ProximalOperators.jl](https://github.com/kul-forbes/ProximalOperators.jl)
* [ProximalAlgorithms.jl](https://github.com/kul-forbes/ProximalAlgorithms.jl)
* [StructuredOptimization.jl](https://github.com/kul-forbes/StructuredOptimization.jl)

## Credits

Expand Down
5 changes: 4 additions & 1 deletion REQUIRE
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
julia 0.6
julia 0.7
AbstractFFTs v0.3.2
FFTW 0.2.4
DSP 0.5.1
37 changes: 23 additions & 14 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
# - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- julia_version: 0.7
- julia_version: 1
- julia_version: nightly

platform:
# - x86 # 32-bit
- x64 # 64-bit

matrix:
allow_failures:
- julia_version: 1
- julia_version: nightly

branches:
only:
Expand All @@ -15,19 +25,18 @@ notifications:
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# 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
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

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(), \"AbstractOperators\"); Pkg.build(\"AbstractOperators\")"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- C:\projects\julia\bin\julia --check-bounds=yes -e "Pkg.test(\"AbstractOperators\")"
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
17 changes: 10 additions & 7 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ This is particularly useful in iterative algorithms and in first order large-sca

## Installation

To install the package, use the following in the Julia command line
To install the package, hit `]` from the Julia command line to enter the package manager, then

```julia
Pkg.add("AbstractOperators")
pkg> add AbstractOperators
```

Remember to `Pkg.update()` to keep the package up to date.

## Usage

With `using AbstractOperators` the package imports several methods like multiplication `*` and transposition `'` (and their in-place methods `A_mul_B!`, `Ac_mul_B!`).
With `using AbstractOperators` the package imports several methods like multiplication `*` and adjoint transposition `'` (and their in-place methods `mul!`).

For example, one can create a 2-D Discrete Fourier Transform as follows:

Expand All @@ -38,13 +36,13 @@ julia> y = A*x
-0.905575+1.98446im 0.441199-0.913338im 0.315788+3.29666im 0.174273+0.318065im
-0.905575-1.98446im 0.174273-0.318065im 0.315788-3.29666im 0.441199+0.913338im

julia> A_mul_B!(y,A,x) == A*x #in-place evaluation
julia> mul!(y, A, x) == A*x #in-place evaluation
true

julia> all(A'*y - *(size(x)...)*x .< 1e-12)
true

julia> Ac_mul_B!(x,A,y) #in-place evaluation
julia> mul!(x, A',y) #in-place evaluation
3×4 Array{Float64,2}:
-2.99091 9.45611 -19.799 1.6327
-11.1841 11.2365 -26.3614 11.7261
Expand Down Expand Up @@ -90,6 +88,11 @@ julia> V*ones(3,3)

A list of the available `AbstractOperators` and calculus rules can be found in the [documentation](https://kul-forbes.github.io/AbstractOperators.jl/latest).

## Related packages

* [ProximalOperators.jl](https://github.com/kul-forbes/ProximalOperators.jl)
* [ProximalAlgorithms.jl](https://github.com/kul-forbes/ProximalAlgorithms.jl)
* [StructuredOptimization.jl](https://github.com/kul-forbes/StructuredOptimization.jl)

## Credits

Expand Down
11 changes: 7 additions & 4 deletions src/AbstractOperators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ __precompile__()

module AbstractOperators

using LinearAlgebra, AbstractFFTs, DSP, FFTW

# Block stuff
include("utilities/block.jl")
using AbstractOperators.BlockArrays
Expand All @@ -11,7 +13,7 @@ abstract type AbstractOperator end
abstract type LinearOperator <: AbstractOperator end
abstract type NonLinearOperator <: AbstractOperator end

import Base: A_mul_B!, Ac_mul_B!
import LinearAlgebra: mul!

export LinearOperator,
NonLinearOperator,
Expand All @@ -21,7 +23,9 @@ export LinearOperator,

include("properties.jl")

# Linear operators
include("calculus/AdjointOperator.jl")

## Linear operators

include("linearoperators/MyLinOp.jl")
include("linearoperators/Zeros.jl")
Expand All @@ -30,7 +34,7 @@ include("linearoperators/Eye.jl")
include("linearoperators/DiagOp.jl")
include("linearoperators/GetIndex.jl")
include("linearoperators/MatrixOp.jl")
include("linearoperators/MatrixMul.jl")
include("linearoperators/LMatrixOp.jl")
include("linearoperators/DFT.jl")
include("linearoperators/RDFT.jl")
include("linearoperators/IRDFT.jl")
Expand All @@ -53,7 +57,6 @@ include("calculus/Compose.jl")
include("calculus/Reshape.jl")
include("calculus/BroadCast.jl")
include("calculus/Sum.jl")
include("calculus/Transpose.jl")
include("calculus/AffineAdd.jl")
include("calculus/Jacobian.jl")
include("calculus/NonLinearCompose.jl")
Expand Down
54 changes: 54 additions & 0 deletions src/calculus/AdjointOperator.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export AdjointOperator

"""
`AdjointOperator(A::AbstractOperator)`

Shorthand constructor:

`'(A::AbstractOperator)`

Returns the adjoint operator of `A`.

```julia
julia> AdjointOperator(DFT(10))
ℱᵃ ℂ^10 -> ℝ^10

julia> [DFT(10); DCT(10)]'
[ℱ;ℱc]ᵃ ℂ^10 ℝ^10 -> ℝ^10
```
"""
struct AdjointOperator{T <: AbstractOperator} <: AbstractOperator
A::T
function AdjointOperator(A::T) where {T<:AbstractOperator}
is_linear(A) == false && error("Cannot transpose a nonlinear operator. You might use `jacobian`")
new{T}(A)
end
end

# Constructors

AdjointOperator(L::AdjointOperator) = L.A

# Properties

size(L::AdjointOperator) = size(L.A,2), size(L.A,1)

domainType(L::AdjointOperator) = codomainType(L.A)
codomainType(L::AdjointOperator) = domainType(L.A)

fun_name(L::AdjointOperator) = fun_name(L.A)*"ᵃ"

is_linear(L::AdjointOperator) = is_linear(L.A)
is_null(L::AdjointOperator) = is_null(L.A)
is_eye(L::AdjointOperator) = is_eye(L.A)
is_diagonal(L::AdjointOperator) = is_diagonal(L.A)
is_AcA_diagonal(L::AdjointOperator) = is_AAc_diagonal(L.A)
is_AAc_diagonal(L::AdjointOperator) = is_AcA_diagonal(L.A)
is_orthogonal(L::AdjointOperator) = is_orthogonal(L.A)
is_invertible(L::AdjointOperator) = is_invertible(L.A)
is_full_row_rank(L::AdjointOperator) = is_full_column_rank(L.A)
is_full_column_rank(L::AdjointOperator) = is_full_row_rank(L.A)

diag(L::AdjointOperator) = diag(L.A)
diag_AcA(L::AdjointOperator) = diag_AAc(L.A)
diag_AAc(L::AdjointOperator) = diag_AcA(L.A)
14 changes: 7 additions & 7 deletions src/calculus/AffineAdd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ end

# Mappings
# array
function A_mul_B!(y::DD, T::AffineAdd{L, D, true}, x) where {L <: AbstractOperator, DD, D}
A_mul_B!(y,T.A,x)
function mul!(y::DD, T::AffineAdd{L, D, true}, x) where {L <: AbstractOperator, DD, D}
mul!(y,T.A,x)
y .+= T.d
end

function A_mul_B!(y::DD, T::AffineAdd{L, D, false}, x) where {L <: AbstractOperator, DD, D}
A_mul_B!(y,T.A,x)
function mul!(y::DD, T::AffineAdd{L, D, false}, x) where {L <: AbstractOperator, DD, D}
mul!(y,T.A,x)
y .-= T.d
end

Ac_mul_B!(y, T::AffineAdd{L, D}, x) where {L <: AbstractOperator, D} = Ac_mul_B!(y,T.A,x)
mul!(y, T::AdjointOperator{AffineAdd{L, D, S}}, x) where {L <: AbstractOperator, D, S} = mul!(y,T.A.A',x)

# Properties

Expand Down Expand Up @@ -93,7 +93,7 @@ function permute(T::AffineAdd{L,D,S}, p::AbstractVector{Int}) where {L,D,S}
return AffineAdd(A,T.d,S)
end

displacement(A::AffineAdd{L,D,true}) where {L,D} = A.d+displacement(A.A)
displacement(A::AffineAdd{L,D,false}) where {L,D} = -A.d+displacement(A.A)
displacement(A::AffineAdd{L,D,true}) where {L,D} = A.d .+ displacement(A.A)
displacement(A::AffineAdd{L,D,false}) where {L,D} = -A.d .+ displacement(A.A)

remove_displacement(A::AffineAdd) = remove_displacement(A.A)
Loading