Calculus rules

Concatenation

AbstractOperators.VCATType
VCAT(A::AbstractOperator...)

Shorthand constructors:

[A1; A2 ...]
vcat(A...)

Vertically concatenate AbstractOperators. Notice that all the operators must share the same domain dimensions and type, e.g. size(A1,2) == size(A2,2) and domain_type(A1) == domain_type(A2).

julia> VCAT(FiniteDiff((4,4)),Variation((4,4)))
[δx;Ʋ]  ℝ^(4, 4) -> ℝ^(3, 4)  ℝ^(16, 2)

julia> V = [Eye(3); DiagOp(2*ones(3))]
[I;╲]  ℝ^3 -> ℝ^3  ℝ^3

julia> vcat(V,FiniteDiff((3,)))
VCAT  ℝ^3 -> ℝ^3  ℝ^3  ℝ^2

julia> # When multiplying a `VCAT` with an array of the proper size, the result will be a `Tuple` containing arrays with the `VCAT`'s codomain type and size.

julia> V*ones(3)
([1.0, 1.0, 1.0], [2.0, 2.0, 2.0])
	
source
AbstractOperators.HCATType
HCAT(A::AbstractOperator...)

Shorthand constructors:

[A1 A2 ...]
hcat(A...)

Horizontally concatenate AbstractOperators. Notice that all the operators must share the same codomain dimensions and type, e.g. size(A1,1) == size(A2,1) and codomain_type(A1) == codomain_type(A2).

julia> HCAT(Eye(10),FiniteDiff((20,))[1:10])
[I,↓*δx]  ℝ^10  ℝ^20 -> ℝ^10

julia> H = [Eye(10) DiagOp(2*ones(10))]
[I,╲]  ℝ^10  ℝ^10 -> ℝ^10

julia> hcat(H,FiniteDiff((11,)))
HCAT  ℝ^10  ℝ^10  ℝ^11 -> ℝ^10

julia> # To evaluate `HCAT` operators multiply them with a `Tuple` of `AbstractArray` of the correct dimensions and type.

julia> using RecursiveArrayTools

julia> H*ArrayPartition(ones(10),ones(10))
10-element Vector{Float64}:
 3.0
 3.0
 3.0
 3.0
 3.0
 3.0
 3.0
 3.0
 3.0
 3.0
	
source
AbstractOperators.DCATType
DCAT(A::AbstractOperator...)

Block-diagonally concatenate AbstractOperators.

julia> D = DCAT(HCAT(Eye(2),Eye(2)),FiniteDiff((3,)))
[[I,I],0;0,δx]  ℝ^2  ℝ^2  ℝ^3 -> ℝ^2  ℝ^2

julia> DCAT(Eye(10),Eye(10),FiniteDiff((4,4)))
DCAT  ℝ^10  ℝ^10  ℝ^(4, 4) -> ℝ^10  ℝ^10  ℝ^(3, 4)

julia> #To evaluate `DCAT` operators multiply them with a `Tuple` of `AbstractArray` of the correct domain size and type. The output will consist as well of a `Tuple` with the codomain type and size of the `DCAT`.

julia> using RecursiveArrayTools

julia> D*ArrayPartition(ones(2),ones(2),ones(3))
([2.0, 2.0], [0.0, 0.0])
	
source

Composition

AbstractOperators.SumType
Sum(A::AbstractOperator...)

Shorthand constructor:

+(A::AbstractOperator...)

Sum of operators.

julia> Sum(DiagOp(rand(10)), Eye(10))
╲+I  ℝ^10 -> ℝ^10

julia> MatrixOp(randn(5,5)) + Eye(5)
▒+I  ℝ^5 -> ℝ^5
	
source
AbstractOperators.ComposeType
Compose(A::AbstractOperator,B::AbstractOperator)

Shorthand constructor:

A*B

Compose different AbstractOperators. Notice that the domain and codomain of the operators A and B must match, i.e. size(A,2) == size(B,1) and domain_type(A) == codomain_type(B).

julia> Compose(Variation((4,4)), FiniteDiff((5,4),1))
Ʋ*δx  ℝ^(5, 4) -> ℝ^(16, 2)

julia> MatrixOp(randn(20,10))*FiniteDiff((11,))
▒*δx  ℝ^11 -> ℝ^20
source
AbstractOperators.HadamardProdType
HadamardProd(A::AbstractOperator,B::AbstractOperator)

Create an operator P such that:

P*x == (Ax).*(Bx)

Example

julia> A,B = Sin(3), Cos(3);

julia> P = HadamardProd(A,B)
sin.*cos  ℝ^3 -> ℝ^3

julia> x = randn(3);

julia> P*x == (sin.(x).*cos.(x))
true
	
source
AbstractOperators.Ax_mul_BxType
Ax_mul_Bx(A::AbstractOperator,B::AbstractOperator)

Create an operator P such that:

P*x == (A*x)*(B*x)

Example

julia> A,B = randn(4,4),randn(4,4);

julia> P = Ax_mul_Bx(MatrixOp(A,4),MatrixOp(B,4))
▒*▒  ℝ^(4, 4) -> ℝ^(4, 4)

julia> X = randn(4,4);

julia> P*X == (A*X)*(B*X)
true
	
source
AbstractOperators.Axt_mul_BxType
Axt_mul_Bx(A::AbstractOperator,B::AbstractOperator)

Create an operator P such that:

P*x == (A*x)'*(B*x)

Example

julia> A,B = randn(4,4),randn(4,4);

julia> P = Axt_mul_Bx(MatrixOp(A),MatrixOp(B))
▒*▒  ℝ^4 -> ℝ^1

julia> x = randn(4);

julia> P*x == [(A*x)'*(B*x)]
true
	
source
AbstractOperators.Ax_mul_BxtType
Ax_mul_Bxt(A::AbstractOperator,B::AbstractOperator)

Create an operator P such that:

P == (A*x)*(B*x)'

Example: Matrix multiplication

julia> A,B = randn(4,4),randn(4,4);

julia> P = Ax_mul_Bxt(MatrixOp(A),MatrixOp(B))
▒*▒  ℝ^4 -> ℝ^(4, 4)

julia> x = randn(4);

julia> P*x == (A*x)*(B*x)'
true
	
source

Transformations

AbstractOperators.ScaleType
Scale(α::Number,A::AbstractOperator)

Shorthand constructor:

*(α::Number,A::AbstractOperator)

Scale an AbstractOperator by a factor of α.

julia> A = FiniteDiff((10,2))
δx  ℝ^(10, 2) -> ℝ^(9, 2)

julia> S = Scale(10,A)
αδx  ℝ^(10, 2) -> ℝ^(9, 2)

julia> 10*A         #shorthand
αδx  ℝ^(10, 2) -> ℝ^(9, 2)
	
source
AbstractOperators.AdjointOperatorType
AdjointOperator(A::AbstractOperator)

Shorthand constructor:

'(A::AbstractOperator)

Returns the adjoint operator of A.

julia> AdjointOperator(ZeroPad((2,2),(0,2)))
[I;0]ᵃ  ℝ^(2, 4) -> ℝ^(2, 2)

julia> [Eye(10); FiniteDiff((10,))]'
[I;δx]ᵃ  ℝ^10  ℝ^9 -> ℝ^10
	
source
AbstractOperators.AffineAddType
AffineAdd(A::AbstractOperator, d, [sign = true])

Affine addition to AbstractOperator with an array or scalar d.

Use sign = false to perform subtraction.

julia> A = AffineAdd(Sin(3),[1.;2.;3.])
sin+d  ℝ^3 -> ℝ^3

julia> A*[3.;4.;5.] == sin.([3.;4.;5.]).+[1.;2.;3.]
true

julia> A = AffineAdd(Exp(3),[1.;2.;3.],false)
e-d  ℝ^3 -> ℝ^3

julia> A*[3.;4.;5.] == exp.([3.;4.;5.]).-[1.;2.;3.]
true
	
source
AbstractOperators.BroadCastFunction
BroadCast(A::AbstractOperator, dim_out...)

BroadCast the codomain dimensions of an AbstractOperator.

julia> A = Eye(2)
I  ℝ^2 -> ℝ^2

julia> B = BroadCast(A,(2,3))
.I  ℝ^2 -> ℝ^(2, 3)

julia> B*[1.;2.]
2×3 Matrix{Float64}:
 1.0  1.0  1.0
 2.0  2.0  2.0
	
source
AbstractOperators.ReshapeType
Reshape(A::AbstractOperator, dim_out...)

Shorthand constructor:

reshape(A, idx...)

Reshape the codomain dimensions of an AbstractOperator.

julia> A = Reshape(Eye(10),2,5)
¶I  ℝ^10 -> ℝ^(2, 5)

julia> R = reshape(Variation(rand(10,10)), (10,10,2))
¶Ʋ  ℝ^(10, 10) -> ℝ^(10, 10, 2)
	
source
AbstractOperators.JacobianType
Jacobian(A::AbstractOperator,x)

Shorthand constructor:

jacobian(A::AbstractOperator,x)

Returns the jacobian of A evaluated at x (which in the case of a LinearOperator is A itself).

julia> Jacobian(DiagOp(rand(ComplexF64, 10)),randn(10))
╲  ℂ^10 -> ℂ^10

julia> Jacobian(Sigmoid((10,)),randn(10))
J(σ)  ℝ^10 -> ℝ^10
	
source