Skip to content

Commit

Permalink
Final piece for v3.0 (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
dkarrasch authored Dec 10, 2020
1 parent 867aa43 commit 580cc97
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 75 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/custom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
142 changes: 86 additions & 56 deletions docs/src/history.md
Original file line number Diff line number Diff line change
@@ -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.
32 changes: 15 additions & 17 deletions src/blockmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down

2 comments on commit 580cc97

@dkarrasch
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/26172

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v3.0.0 -m "<description of version>" 580cc974a1238eb998e8e8ca21c753f87b53d465
git push origin v3.0.0

Please sign in to comment.