Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support (un)whiten and (inv)quad with static arrays #183

Merged
merged 9 commits into from
Oct 13, 2023

Conversation

devmotion
Copy link
Member

Based on #181, this PR also adds support for whiten, unwhiten, quad, and invquad with static arrays.

The PR grew a bit larger, hence I kept it separate from #181 for now.

Main points:

  • Do not use mutation in non-mutating methods (in a few cases, allocations could be reduced by specializing on Array, see my comment in Support StaticArrays in X(t)_(inv)A_X(t) with ScalMat #181 - should we do this?)
  • Improve composability by forwarding calls with generic matrices to f(..., AbstractPDMat(x), ...) (as a nice side effect, this means that more efficient implementations are called automatically whenever AbstractPDMat(x) is specialized; this is the case, e.g., for Diagonal matrices).
  • Check dimensions.

Comment on lines +116 to +118
# map(Base.Fix1(invquad, a), eachcol(x)) or similar alternatives
# do NOT return a `SVector` for inputs `x::SMatrix`.
return vec(sum(abs2.(x) .* a.diag; dims = 1))
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a bit unsatisfying - is there any way we could avoid unnecessary allocations but still make StaticArray return the expected types?

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a version with reduced allocations specialized for Array arguments.

invquad(a::PDiagMat, x::AbstractVector) = invwsumsq(a.diag, x)
function quad(a::PDiagMat, x::AbstractVecOrMat)
@check_argdims a.dim == size(x, 1)
if x isa AbstractVector
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure if it is helpful/desirable here, but generally I tried to reduce the number of methods to lower the probability for method ambiguity errors. Maybe it's mostly useful for the generic code path in src/generics.jl.

src/pdsparsemat.jl Outdated Show resolved Hide resolved
Comment on lines +106 to +111
# map(Base.Fix1(quad, a), eachcol(x)) or similar alternatives
# do NOT return a `SVector` for inputs `x::SMatrix`.
wsq = let w = a.value
x -> w * abs2(x)
end
return vec(sum(wsq, x; dims=1))
Copy link
Member Author

Choose a reason for hiding this comment

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

Any less ugly way to implement this?

@codecov-commenter
Copy link

codecov-commenter commented Sep 26, 2023

Codecov Report

Attention: 64 lines in your changes are missing coverage. Please review.

Files Coverage Δ
src/pdiagmat.jl 99.19% <100.00%> (+1.71%) ⬆️
src/utils.jl 60.00% <100.00%> (-31.67%) ⬇️
src/generics.jl 76.47% <75.00%> (-10.71%) ⬇️
src/scalmat.jl 90.09% <75.00%> (-7.24%) ⬇️
src/pdsparsemat.jl 71.96% <48.83%> (-23.93%) ⬇️
src/pdmat.jl 74.38% <48.27%> (-24.04%) ⬇️

📢 Thoughts on this report? Let us know!.

Base automatically changed from dw/scalmat_staticarrays to master October 2, 2023 20:36
Copy link
Member

@andreasnoack andreasnoack left a comment

Choose a reason for hiding this comment

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

Mostly looks good to me. Just curious about the type parameter restriction.

Comment on lines +70 to +71
whiten(a::AbstractMatrix{<:Real}, x::AbstractVecOrMat) = whiten(AbstractPDMat(a), x)
unwhiten(a::AbstractMatrix{<:Real}, x::AbstractVecOrMat) = unwhiten(AbstractPDMat(a), x)
Copy link
Member

Choose a reason for hiding this comment

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

Why the restriction on the type parameter?

Copy link
Member Author

Choose a reason for hiding this comment

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

Currently, AbstractPDMats are Real matrices:

abstract type AbstractPDMat{T<:Real} <: AbstractMatrix{T} end

@devmotion devmotion merged commit 0c0f04c into master Oct 13, 2023
11 checks passed
@devmotion devmotion deleted the dw/better_staticarray branch October 13, 2023 11:23
sethaxen added a commit to mlcolab/Pathfinder.jl that referenced this pull request Nov 30, 2023
sethaxen added a commit to mlcolab/Pathfinder.jl that referenced this pull request Nov 30, 2023
* Add missing convert methods

Now necessary because of JuliaStats/PDMats.jl#179

* Generalize (inv)quad and (un)whiten methods

Now necessary because of JuliaStats/PDMats.jl#183

* Increment patch number with `-DEV` suffix

* Bump required PDMats version

* Add codecov token

* Fix definition of whiten

* Add definition of `whiten!`

* Add more whiten/unwhiten tests

* Add more conversion tests

* Add tests for (inv)quad!

* Fix variable names

* Add missing tests

* Add correct size tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants