11module LinearMaps
22
33export LinearMap
4+ export ⊗ , kronsum, ⊕
45
56using LinearAlgebra
67using SparseArrays
1415
1516abstract type LinearMap{T} end
1617
18+ const MapOrMatrix{T} = Union{LinearMap{T},AbstractMatrix{T}}
19+
1720Base. eltype (:: LinearMap{T} ) where {T} = T
1821
1922Base. isreal (A:: LinearMap ) = eltype (A) <: Real
@@ -26,6 +29,26 @@ Base.ndims(::LinearMap) = 2
2629Base. size (A:: LinearMap , n) = (n== 1 || n== 2 ? size (A)[n] : error (" LinearMap objects have only 2 dimensions" ))
2730Base. length (A:: LinearMap ) = size (A)[1 ] * size (A)[2 ]
2831
32+ # check dimension consistency for y = A*x and Y = A*X
33+ function check_dim_mul (y:: AbstractVector , A:: LinearMap , x:: AbstractVector )
34+ m, n = size (A)
35+ (m == length (y) && n == length (x)) || throw (DimensionMismatch (" mul!" ))
36+ return nothing
37+ end
38+ function check_dim_mul (Y:: AbstractMatrix , A:: LinearMap , X:: AbstractMatrix )
39+ m, n = size (A)
40+ (m == size (Y, 1 ) && n == size (X, 1 ) && size (Y, 2 ) == size (X, 2 )) || throw (DimensionMismatch (" mul!" ))
41+ return nothing
42+ end
43+
44+ # conversion of AbstractMatrix to LinearMap
45+ convert_to_lmaps_ (A:: AbstractMatrix ) = LinearMap (A)
46+ convert_to_lmaps_ (A:: LinearMap ) = A
47+ convert_to_lmaps () = ()
48+ convert_to_lmaps (A) = (convert_to_lmaps_ (A),)
49+ @inline convert_to_lmaps (A, B, Cs... ) =
50+ (convert_to_lmaps_ (A), convert_to_lmaps_ (B), convert_to_lmaps (Cs... )... )
51+
2952Base.:(* )(A:: LinearMap , x:: AbstractVector ) = mul! (similar (x, promote_type (eltype (A), eltype (x)), size (A, 1 )), A, x)
3053function LinearAlgebra. mul! (y:: AbstractVector , A:: LinearMap , x:: AbstractVector , α:: Number = true , β:: Number = false )
3154 length (y) == size (A, 1 ) || throw (DimensionMismatch (" mul!" ))
@@ -68,64 +91,24 @@ A_mul_B!(y::AbstractVector, A::AbstractMatrix, x::AbstractVector) = mul!(y, A,
6891At_mul_B! (y:: AbstractVector , A:: AbstractMatrix , x:: AbstractVector ) = mul! (y, transpose (A), x)
6992Ac_mul_B! (y:: AbstractVector , A:: AbstractMatrix , x:: AbstractVector ) = mul! (y, adjoint (A), x)
7093
71- # Matrix: create matrix representation of LinearMap
72- function Base. Matrix (A:: LinearMap )
73- M, N = size (A)
74- T = eltype (A)
75- mat = Matrix {T} (undef, (M, N))
76- v = fill (zero (T), N)
77- @inbounds for i = 1 : N
78- v[i] = one (T)
79- mul! (view (mat, :, i), A, v)
80- v[i] = zero (T)
81- end
82- return mat
83- end
84-
85- Base. Array (A:: LinearMap ) = Matrix (A)
86- Base. convert (:: Type{Matrix} , A:: LinearMap ) = Matrix (A)
87- Base. convert (:: Type{Array} , A:: LinearMap ) = Matrix (A)
88- Base. convert (:: Type{SparseMatrixCSC} , A:: LinearMap ) = sparse (A)
89-
90- # sparse: create sparse matrix representation of LinearMap
91- function SparseArrays. sparse (A:: LinearMap{T} ) where {T}
92- M, N = size (A)
93- rowind = Int[]
94- nzval = T[]
95- colptr = Vector {Int} (undef, N+ 1 )
96- v = fill (zero (T), N)
97- Av = Vector {T} (undef, M)
98-
99- for i = 1 : N
100- v[i] = one (T)
101- mul! (Av, A, v)
102- js = findall (! iszero, Av)
103- colptr[i] = length (nzval) + 1
104- if length (js) > 0
105- append! (rowind, js)
106- append! (nzval, Av[js])
107- end
108- v[i] = zero (T)
109- end
110- colptr[N+ 1 ] = length (nzval) + 1
111-
112- return SparseMatrixCSC (M, N, colptr, rowind, nzval)
113- end
114-
11594include (" wrappedmap.jl" ) # wrap a matrix of linear map in a new type, thereby allowing to alter its properties
11695include (" uniformscalingmap.jl" ) # the uniform scaling map, to be able to make linear combinations of LinearMap objects and multiples of I
11796include (" transpose.jl" ) # transposing linear maps
11897include (" linearcombination.jl" ) # defining linear combinations of linear maps
11998include (" composition.jl" ) # composition of linear maps
12099include (" functionmap.jl" ) # using a function as linear map
121100include (" blockmap.jl" ) # block linear maps
101+ include (" kronecker.jl" ) # Kronecker product of linear maps
102+ include (" conversion.jl" ) # conversion of linear maps to matrices
122103
123104"""
124105 LinearMap(A; kwargs...)
106+ LinearMap(J, M::Int)
125107 LinearMap{T=Float64}(f, [fc,], M::Int, N::Int = M; kwargs...)
126108
127109Construct a linear map object, either from an existing `LinearMap` or `AbstractMatrix` `A`,
128- with the purpose of redefining its properties via the keyword arguments `kwargs`, or
110+ with the purpose of redefining its properties via the keyword arguments `kwargs`;
111+ a `UniformScaling` object `J` with specified (square) dimension `M`; or
129112from a function or callable object `f`. In the latter case, one also needs to specify
130113the size of the equivalent matrix representation `(M, N)`, i.e. for functions `f` acting
131114on length `N` vectors and producing length `M` vectors (with default value `N=M`). Preferably,
@@ -141,20 +124,21 @@ The keyword arguments and their default values for functions `f` are
141124For existing linear maps or matrices `A`, the default values will be taken by calling
142125`issymmetric`, `ishermitian` and `isposdef` on the existing object `A`.
143126
144- For functions `f`, there is one more keyword arguments
127+ For functions `f`, there is one more keyword argument
145128* ismutating::Bool : flags whether the function acts as a mutating matrix multiplication
146129 `f(y,x)` where the result vector `y` is the first argument (in case of `true`),
147130 or as a normal matrix multiplication that is called as `y=f(x)` (in case of `false`).
148131 The default value is guessed by looking at the number of arguments of the first occurence
149132 of `f` in the method table.
150133"""
151- LinearMap (A:: Union{AbstractMatrix, LinearMap} ; kwargs... ) = WrappedMap (A; kwargs... )
134+ LinearMap (A:: MapOrMatrix ; kwargs... ) = WrappedMap (A; kwargs... )
135+ LinearMap (J:: UniformScaling , M:: Int ) = UniformScalingMap (J. λ, M)
152136LinearMap (f, M:: Int ; kwargs... ) = LinearMap {Float64} (f, M; kwargs... )
153137LinearMap (f, M:: Int , N:: Int ; kwargs... ) = LinearMap {Float64} (f, M, N; kwargs... )
154138LinearMap (f, fc, M:: Int ; kwargs... ) = LinearMap {Float64} (f, fc, M; kwargs... )
155139LinearMap (f, fc, M:: Int , N:: Int ; kwargs... ) = LinearMap {Float64} (f, fc, M, N; kwargs... )
156140
157- LinearMap {T} (A:: Union{AbstractMatrix, LinearMap} ; kwargs... ) where {T} = WrappedMap {T} (A; kwargs... )
141+ LinearMap {T} (A:: MapOrMatrix ; kwargs... ) where {T} = WrappedMap {T} (A; kwargs... )
158142LinearMap {T} (f, args... ; kwargs... ) where {T} = FunctionMap {T} (f, args... ; kwargs... )
159143
160144end # module
0 commit comments