diff --git a/Project.toml b/Project.toml index c72bfe8b..a12d3c75 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "LinearMaps" uuid = "7a12625a-238d-50fd-b39a-03d52299707e" -version = "2.7.0" +version = "3.0" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" diff --git a/docs/src/custom.jl b/docs/src/custom.jl index 897a6891..92a09588 100644 --- a/docs/src/custom.jl +++ b/docs/src/custom.jl @@ -200,7 +200,7 @@ mul!(similar(x)', x', A) # ## Application to matrices # By default, applying a `LinearMap` `A` to a matrix `X` via `A*X` does -# *not* aplly `A` to each column of `X` viewed as a vector, but interprets +# *not* apply `A` to each column of `X` viewed as a vector, but interprets # `X` as a linear map, wraps it as such and returns `(A*X)::CompositeMap`. # Calling the in-place multiplication function `mul!(Y, A, X)` for matrices, # however, does compute the columnwise action of `A` on `X` and stores the diff --git a/docs/src/history.md b/docs/src/history.md index d6ae729f..7ed2c1a8 100644 --- a/docs/src/history.md +++ b/docs/src/history.md @@ -1,56 +1,86 @@ -# What's new? - -### What's new in v2.7 -* Potential reduction of memory allocations in multiplication of - `LinearCombination`s, `BlockMap`s, and real- or complex-scaled `LinearMap`s. - For the latter, a new internal type `ScaledMap` has been introduced. -* Multiplication code for `CompositeMap`s has been refactored to facilitate to - provide memory for storage of intermediate results by directly calling helper - functions. - -### What's new in v2.6 -* New feature: "lazy" Kronecker product, Kronecker sums, and powers thereof - for `LinearMap`s. `AbstractMatrix` objects are promoted to `LinearMap`s if - one of the first 8 Kronecker factors is a `LinearMap` object. -* Compatibility with the generic multiply-and-add interface (a.k.a. 5-arg - `mul!`) introduced in julia v1.3 - -### What's new in v2.5 -* New feature: concatenation of `LinearMap`s objects with `UniformScaling`s, - consistent with (h-, v-, and hc-)concatenation of matrices. Note, matrices - `A` must be wrapped as `LinearMap(A)`, `UniformScaling`s are promoted to - `LinearMap`s automatically. - -### What's new in v2.4 -* Support restricted to Julia v1.0+. - -### What's new in v2.3 -* Fully Julia v0.7/v1.0/v1.1 compatible. -* Full support of noncommutative number types such as quaternions. - -### What's new in v2.2 -* Fully Julia v0.7/v1.0 compatible. -* A `convert(SparseMatrixCSC, A::LinearMap)` function, that calls the `sparse` - matrix generating function. - -### What's new in v2.1 -* Fully Julia v0.7 compatible; dropped compatibility for previous versions of - Julia from LinearMaps.jl v2.0.0 on. -* A 5-argument version for `mul!(y, A::LinearMap, x, α=1, β=0)`, which - computes `y := α * A * x + β * y` and implements the usual 3-argument - `mul!(y, A, x)` for the default `α` and `β`. -* Synonymous `convert(Matrix, A::LinearMap)` and `convert(Array, A::LinearMap)` - functions, that call the `Matrix` constructor and return the matrix - representation of `A`. -* Multiplication with matrices, interpreted as a block row vector of vectors: - * `mul!(Y::AbstractArray, A::LinearMap, X::AbstractArray, α=1, β=0)`: - applies `A` to each column of `X` and stores the result in-place in the - corresponding column of `Y`; - * for the out-of-place multiplication, the approach is to compute - `convert(Matrix, A * X)`; this is equivalent to applying `A` to each - column of `X`. In generic code which handles both `A::AbstractMatrix` and - `A::LinearMap`, the additional call to `convert` is a noop when `A` is a - matrix. -* Full compatibility with [Arpack.jl](https://github.com/JuliaLinearAlgebra/Arpack.jl)'s - `eigs` and `svds`; previously only `eigs` was working. For more, nicely - collaborating packages see the [Example](#example) section. +# Version history + +## What's new in v3.0 + +* BREAKING change: Internally, any dependence on former `A*_mul_B!` methods is abandonned. + For custom `LinearMap` subtypes, there are now two options: + 1. In case your type is invariant under adjoint/transposition (i.e., + `adjoint(L::MyLinearMap)::MyLinearMap` similar to, for instance, + `LinearCombination`s or `CompositeMap`s, `At_mul_B!` and `Ac_mul_B!` do + not require any replacement! Rather, multiplication by `L'` is, in this case, + handled by `mul!(y, L::MyLinearMap, x[, α, β])`. + 2. Otherwise, you will need to define `mul!` methods with the signature + `mul!(y, L::TransposeMap{<:Any,MyLinearMap}, x[, α, β])` and + `mul!(y, L::AdjointMap{<:Any,MyLinearMap}, x[, α, β])`. +* Left multiplying by a transpose or adjoint vector (e.g., `y'*A`) + produces a transpose or adjoint vector output, rather than a composite `LinearMap`. +* Block concatenation now handles matrices and vectors directly by internal promotion + to `LinearMap`s. For `[h/v/hc]cat` it suffices to have a `LinearMap` object anywhere + in the list of arguments. For the block-diagonal concatenation via + `SparseArrays.blockdiag`, a `LinearMap` object has to appear among the first 8 arguments. + This restriction, however, does not apply to block-diagonal concatenation via + `Base.cat(As...; dims=(1,2))`. +* Introduction of more expressive and visually appealing `show` methods, replacing + the fallback to the generic `show`. + +## What's new in v2.7 + +* Potential reduction of memory allocations in multiplication of + `LinearCombination`s, `BlockMap`s, and real- or complex-scaled `LinearMap`s. + For the latter, a new internal type `ScaledMap` has been introduced. +* Multiplication code for `CompositeMap`s has been refactored to facilitate to + provide memory for storage of intermediate results by directly calling helper + functions. + +## What's new in v2.6 + +* New feature: "lazy" Kronecker product, Kronecker sums, and powers thereof + for `LinearMap`s. `AbstractMatrix` objects are promoted to `LinearMap`s if + one of the first 8 Kronecker factors is a `LinearMap` object. +* Compatibility with the generic multiply-and-add interface (a.k.a. 5-arg + `mul!`) introduced in julia v1.3 + +## What's new in v2.5 + +* New feature: concatenation of `LinearMap`s objects with `UniformScaling`s, + consistent with (h-, v-, and hc-)concatenation of matrices. Note, matrices + `A` must be wrapped as `LinearMap(A)`, `UniformScaling`s are promoted to + `LinearMap`s automatically. + +## What's new in v2.4 + +* Support restricted to Julia v1.0+. + +## What's new in v2.3 + +* Fully Julia v0.7/v1.0/v1.1 compatible. +* Full support of noncommutative number types such as quaternions. + +## What's new in v2.2 + +* Fully Julia v0.7/v1.0 compatible. +* A `convert(SparseMatrixCSC, A::LinearMap)` function, that calls the `sparse` + matrix generating function. + +## What's new in v2.1 + +* Fully Julia v0.7 compatible; dropped compatibility for previous versions of + Julia from LinearMaps.jl v2.0.0 on. +* A 5-argument version for `mul!(y, A::LinearMap, x, α=1, β=0)`, which + computes `y := α * A * x + β * y` and implements the usual 3-argument + `mul!(y, A, x)` for the default `α` and `β`. +* Synonymous `convert(Matrix, A::LinearMap)` and `convert(Array, A::LinearMap)` + functions, that call the `Matrix` constructor and return the matrix + representation of `A`. +* Multiplication with matrices, interpreted as a block row vector of vectors: + * `mul!(Y::AbstractArray, A::LinearMap, X::AbstractArray, α=1, β=0)`: + applies `A` to each column of `X` and stores the result in-place in the + corresponding column of `Y`; + * for the out-of-place multiplication, the approach is to compute + `convert(Matrix, A * X)`; this is equivalent to applying `A` to each + column of `X`. In generic code which handles both `A::AbstractMatrix` and + `A::LinearMap`, the additional call to `convert` is a noop when `A` is a + matrix. +* Full compatibility with [Arpack.jl](https://github.com/JuliaLinearAlgebra/Arpack.jl)'s + `eigs` and `svds`; previously only `eigs` was working. For more, nicely + collaborating packages see the [Example](#example) section. diff --git a/src/blockmap.jl b/src/blockmap.jl index 1e5b5a88..0902a483 100644 --- a/src/blockmap.jl +++ b/src/blockmap.jl @@ -442,22 +442,20 @@ for k in 1:8 # is 8 sufficient? mapargs = ntuple(n ->:($(Symbol(:A, n))), Val(k-1)) # yields (:LinearMap(A1), :LinearMap(A2), ..., :LinearMap(A(k-1))) - @eval begin - function SparseArrays.blockdiag($(Is...), $L, As::MapOrVecOrMat...) - return BlockDiagonalMap(convert_to_lmaps($(mapargs...))..., - $(Symbol(:A, k)), - convert_to_lmaps(As...)...) - end + @eval function SparseArrays.blockdiag($(Is...), $L, As::MapOrVecOrMat...) + return BlockDiagonalMap(convert_to_lmaps($(mapargs...))..., + $(Symbol(:A, k)), + convert_to_lmaps(As...)...) + end +end - function Base.cat($(Is...), $L, As::MapOrVecOrMat...; dims::Dims{2}) - if dims == (1,2) - return BlockDiagonalMap(convert_to_lmaps($(mapargs...))..., - $(Symbol(:A, k)), - convert_to_lmaps(As...)...) - else - throw(ArgumentError("dims keyword in cat of LinearMaps must be (1,2)")) - end - end +# This method is more generic than Base._cat(catdims, A::AbstractArray...), and +# therefore does not override Base/StdLib behavior +function Base._cat(dims, As::MapOrVecOrMat...) + if dims::Dims{2} == (1, 2) + return BlockDiagonalMap(convert_to_lmaps(As...)...) + else + throw(ArgumentError("dims keyword in cat of LinearMaps must be (1,2)")) end end @@ -474,8 +472,8 @@ SparseArrays.blockdiag cat(As::Union{LinearMap,AbstractVecOrMat}...; dims=(1,2))::BlockDiagonalMap Construct a (lazy) representation of the diagonal concatenation of the arguments. -To avoid fallback to the generic `Base.cat`, there must be a `LinearMap` -object among the first 8 arguments. +To avoid fallback to the generic `Base.cat`, there must be a `LinearMap` object +among the arguments, without any restriction on its position. """ Base.cat