Properties and Traits

Size and Domains

Base.size — Function
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.ndims — Function
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.ndoms — Function
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_type — Function
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_type — Function
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_array_type — Function
domain_array_type(L::AbstractOperator)

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

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

julia> domain_array_type(hcat(Eye(Complex{Float64},(10,)),DiagOp(rand(ComplexF64, 10))))
RecursiveArrayTools.ArrayPartition{ComplexF64, Tuple{Array{ComplexF64}, Array{ComplexF64}}}
source
AbstractOperators.codomain_array_type — Function
codomain_array_type(L::AbstractOperator)

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

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

julia> codomain_array_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.diag — Function
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.opnorm — Function
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_linear — Function
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_eye — Function
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_null — Function
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_symmetric — Function
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_diagonal — Function
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_diagonal — Function
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_AcA — Function
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_diagonal — Function
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_AAc — Function
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_orthogonal — Function
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_invertible — Function
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_rank — Function
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_rank — Function
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.displacement — Function
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_sliced — Function
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_opnorm — Function
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

Operator Copying

AbstractOperators.copy_operator — Function
copy_operator(op::AbstractOperator; storage_type=nothing, threaded=nothing)

Create a copy of op suitable for parallel use.

  • Immutable fields (operator arrays, type params) are shared (no copy).
  • Mutable buffer fields are deep-copied.
  • storage_type: if provided (e.g., CuArray), convert buffer arrays to that storage.
  • threaded: if provided (true/false), toggle threading for operators that support it.

When storage_type is nothing and threaded is nothing, equivalent to the old copy_op but more efficient (shares immutable data).

source