Properties and Traits

Size and Domains

Base.sizeFunction
size(A::AbstractOperator, [dom,])

Returns the size of an AbstractOperator. Type size(A,1) for the size of the codomain and size(A,2) for the size of the codomain.

Note that the size is always returned as a Tuple, so for a 2D operator the size of the codomain will be (m,) and the size of the domain will be (n,) for an m x n operator.

julia> size(FiniteDiff((10,20), 1))
((9, 20), (10, 20))

julia> size(FiniteDiff((10,20), 1),1)
(9, 20)

julia> size(FiniteDiff((10,20), 1),2)
(10, 20)
source
Base.ndimsFunction
ndims(A::AbstractOperator, [dom,])

Returns a Tuple with the number of dimensions of the codomain and domain of an AbstractOperator. Type ndims(A,1) for the number of dimensions of the codomain and ndims(A,2) for the number of dimensions of the codomain.

julia> V = Variation((2,3,4))
Ʋ  ℝ^(2, 3, 4) -> ℝ^(24, 3)

julia> ndims(V)
(2, 3)

julia> ndims(V,1)
2

julia> ndims(V,2)
3
source
AbstractOperators.ndomsFunction
ndoms(L::AbstractOperator, [dom::Int]) -> (number of codomains, number of domains)

Returns the number of codomains and domains of a AbstractOperator. Optionally you can specify the codomain (with dom = 1) or the domain (with dom = 2)

julia> ndoms(Eye(10,10))
(1, 1)

julia> ndoms(hcat(Eye(10,10),Eye(10,10)))
(1, 2)

julia> ndoms(hcat(Eye(10,10),Eye(10,10)),2)
2

julia> ndoms(DCAT(Eye(10,10),Eye(10,10)))
(2, 2)
source
AbstractOperators.domain_typeFunction
domain_type(A::AbstractOperator)

Returns the type of the domain.

julia> domain_type(DiagOp(rand(10)))
Float64

julia> domain_type(hcat(Eye(Complex{Float64},(10,)),DiagOp(rand(ComplexF64, 10))))
(ComplexF64, ComplexF64)
source
AbstractOperators.codomain_typeFunction
codomain_type(A::AbstractOperator)

Returns the type of the codomain.

julia> codomain_type(DiagOp(rand(ComplexF64, 10)))
ComplexF64 (alias for Complex{Float64})

julia> codomain_type(vcat(Eye(Complex{Float64},(10,)),DiagOp(rand(ComplexF64, 10))))
(ComplexF64, ComplexF64)
source
AbstractOperators.domain_storage_typeFunction
domain_storage_type(L::AbstractOperator)

Returns the type of the storage for the domain of the operator.

julia> domain_storage_type(DiagOp(rand(10)))
Array{Float64}

julia> domain_storage_type(hcat(Eye(Complex{Float64},(10,)),DiagOp(rand(ComplexF64, 10))))
RecursiveArrayTools.ArrayPartition{ComplexF64, Tuple{Array{ComplexF64}, Array{ComplexF64}}}
source
AbstractOperators.codomain_storage_typeFunction
codomain_storage_type(L::AbstractOperator)

Returns the type of the storage of for the codomain of the operator.

julia> codomain_storage_type(DiagOp(rand(ComplexF64,10)))
Array{ComplexF64}

julia> codomain_storage_type(vcat(Eye(Complex{Float64},(10,)),DiagOp(rand(ComplexF64,10))))
RecursiveArrayTools.ArrayPartition{ComplexF64, Tuple{Array{ComplexF64}, Array{ComplexF64}}}
source

Traits

The functions in this package allows querying properties of the operators to be used by other packages for optimization and trait-based custumized behavior.

LinearAlgebra traits

AbstractOperators.jl's operators is defined for following functions from standard library LinearAlgebra.

LinearAlgebra.diagFunction
LinearAlgebra.diag(A::AbstractOperator)

Returns the diagonal of A. If A is not diagonal, an error is thrown.

The diagonal is defined as the vector d such that A * x = d .* x for all x in the domain of A, where .* is the element-wise multiplication.

source
LinearAlgebra.opnormFunction
LinearAlgebra.opnorm(A::AbstractOperator)

Returns the operator norm of A. The operator norm is defined as the maximum singular value of A. It is computed using the power method by default, unless the operator has a fast implementation.

The operator norm is defined as: ‖A‖ = sup_{x != 0} ‖A*x‖ / ‖x‖.

Parameters of power iteration:

  • Maximum number of iterations: 100
  • Tolerance for convergence: 1e-6

These parameters can be adjusted in the estimate_opnorm function.

source

OperatorCore.jl traits

AbstractOperators.jl's operators satisfies the interface for matrix-like objects provided by OperatorCore.jl with the following functions:

OperatorCore.is_linearFunction
is_linear(A)

Returns true if A is a linear operator. Operator A is linear if A * (x+y) = A * x + A * y and A * (α * x) = α * A * x for all x and y in the domain of A and all scalars α.

source
OperatorCore.is_eyeFunction
is_eye(A)

Returns true if A is an identity operator. Operator A is an identity operator if A * x = x for all x in the domain of A.

source
OperatorCore.is_nullFunction
is_null(A)

Returns true if A is a null operator. Operator A is null if A * x = 0 for all x in the domain of A, where 0 is the zero element of the codomain of A (e.g. zero vector).

source
OperatorCore.is_symmetricFunction
is_symmetric(A)

Returns true if A is a symmetric operator. Operator A is symmetric if A * x = A' * x for all x in the domain of A, where A' is the adjoint of A. In other words, A is symmetric if it is equal to its adjoint.

source
OperatorCore.is_diagonalFunction
is_diagonal(A)

Returns true if A is a diagonal operator. Operator A is diagonal if (A * x)[i] = (A * eᵢ)[i] for all x in the domain of A and all i, where eᵢ is the i-th canonical basis vector. In other words, (A * x)[i] depends only on x[i].

source
OperatorCore.is_AcA_diagonalFunction
is_AcA_diagonal(A)

Returns true if A*A' is diagonal, where A' is the adjoint of A. Compounds A*A' is diagonal if ((A*A') * x)[i] = (A*A') * eᵢ)[i] for all x in the domain of A and all i, where eᵢ is the i-th canonical basis vector. In other words, ((A*A') * x)[i] depends only on x[i].

source
OperatorCore.diag_AcAFunction
diag_AcA(A)

Returns the diagonal of A*A', where A' is the adjoint of A. If A*A' is not diagonal, an error is thrown.

source
OperatorCore.is_AAc_diagonalFunction
is_AAc_diagonal(A)

Returns true if A'*A is diagonal, where A' is the adjoint of A. Compounds A'*A is diagonal if ((A'*A) * x)[i] = (A'*A) * eᵢ)[i] for all x in the domain of A and all i, where eᵢ is the i-th canonical basis vector. In other words, ((A'*A) * x)[i] depends only on x[i].

source
OperatorCore.diag_AAcFunction
diag_AAc(A)

Returns the diagonal of A'*A, where A' is the adjoint of A. If A'*A is not diagonal, an error is thrown.

source
OperatorCore.is_orthogonalFunction
is_orthogonal(A)

Returns true if A is an orthogonal operator. Operator A is orthogonal if A * A' = A' * A = I, where A' is the adjoint of A and I is the identity operator.

source
OperatorCore.is_invertibleFunction
is_invertible(A)

Returns true if A is an invertible operator. Operator A is invertible if there exists an operator B such that A * B = B * A = I, where I is the identity operator.

source
OperatorCore.is_full_row_rankFunction
is_full_row_rank(A)

Returns true if A has full row rank. Operator A has full row rank if the rows of A are linearly independent. In other words, the number of linearly independent rows of A is equal to the number of rows of A.

source
OperatorCore.is_full_column_rankFunction
is_full_row_rank(A)

Returns true if A has full column rank. Operator A has full column rank if the columns of A are linearly independent. In other words, the number of linearly independent columns of A is equal to the number of columns of A.

source

Additional traits

AbstractOperators.jl's operators also defines the following functions:

AbstractOperators.displacementFunction
displacement(A::AbstractOperator)

Returns the displacement of the operator.

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

julia> displacement(A)
4-element Vector{Float64}:
 1.0
 2.0
 3.0
 4.0
source
AbstractOperators.is_slicedFunction
is_sliced(A)

Returns true if A is a sliced operator. Operator A is sliced if it applies to only a subset of the input values.

julia> is_sliced(DiagOp(rand(10)))
false

julia> is_sliced(DiagOp(rand(10)) * GetIndex((20,), 1:10))
true
source
AbstractOperators.estimate_opnormFunction
estimate_opnorm(A::AbstractOperator)

Estimates the operator norm of A. The operator norm is defined as the maximum singular value of A. It is computed using the power method with reduced iterations unless the operator has a fast implementation.

The operator norm is defined as: ‖A‖ = sup_{x != 0} ‖A*x‖ / ‖x‖.

Parameters of power iteration:

  • Maximum number of iterations: 20
  • Tolerance for convergence: 0.01

These parameters can be adjusted by passing maxit and tol keyword arguments. E.g.:

julia> estimate_opnorm(A; maxit=50, tol=1e-6)
source