-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
RFC: Add norm(A, p; dims)
#43459
base: master
Are you sure you want to change the base?
RFC: Add norm(A, p; dims)
#43459
Conversation
I don't like this (because I don't like |
Do you think that checking for The existing one checks beforehand, but doing that on the N^2 matrix seems to take longer than the entire operation. Whereas checking the N results afterwards is usually quick. At least when not too many are 0/Inf. |
That is sufficient (and a much better idea). |
Can you separate out
into it's own PR? I think that that is an easy win, while the new method probably needs a triage. Alternatively, would you mind if I rewrote #43256 to use this? |
I wondered about using the same check-afterwards idea for the complete norm. I can have a go but if you beat me to it that's even better. (Did not see #43256.) But I don't think such a change need alter this PR. They would share the idea but not share code for it, I think. Unless you are proposing that |
norm0_dims!(B, A) = count!(!iszero, B, A) | ||
norm1_dims!(B, A) = Base.mapreducedim!(norm, +, B, A) | ||
normInf_dims!(B, A) = Base.mapreducedim!(norm, max, B, A) | ||
normMinusInf_dims!(B, A) = Base.mapreducedim!(norm, min, B, A) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW the reason these are all mutating B
is to work around #43461. With things like mapreduce(norm, max, A; dims)
instead, some were not type-stable. There's a PR to fix that, though.
triage would rather not add new dims arguments and instead use #32310 (or similar) to make |
What's slow isn't |
with the |
No, It would be possible to overload EDIT:
All of these have a bit of the problem that There's also a problem of return types. |
Today I discovered that 1.9 has Rebasing this PR & timing it on 1.10-, which includes the new julia> @btime mapslices(norm, $(rand(100, 100)), dims=2); # re-written for 1.9,# 40996
30.375 μs (15 allocations: 2.12 KiB)
julia> @btime map(norm, eachrow($(rand(100, 100)))); # with JuliaLang/julia#32310
22.000 μs (1 allocation: 896 bytes)
julia> @btime norm($(rand(100, 100)), 2, dims=2); # with PR
2.949 μs (5 allocations: 976 bytes) |
Closes JuliaLang/LinearAlgebra.jl#697. RFC, I guess?
One motivation is that this can be faster than making slices:
Here, "5 allocations" is sometimes 1 as you'd expect, I don't know why, seems to depend on load order? I think there was an issue about this which I can't find again.
The 0,1,Inf norm implementations are trivial.
For the 2-norm, I initially made it check whether values in
A
are in the goldilocks zone, asnorm(A)
does. But this check alone takes longer than the happy path ofsum(abs2, A; dims)
. Instead, the present PR does that and then checks the answer, and re-does any slices which are dangerous. I hope this is correct. I presume the typical case would not have many such zero/Inf answers, in which case this will be fast. It's a bit awkward thateachslice
doesn't do what is needed here, so instead I taped something together, trying to make the common cases fast. It is a bit ugly but is there a better way?The p-norm is much slower,
and for now it just slices. It could probably be done the same way, though.[Edit: now works like 2-norm]