Skip to content

Fixes to norm and friends (closes #915) #929

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

Merged
merged 7 commits into from
Jul 27, 2021

Conversation

thchr
Copy link
Collaborator

@thchr thchr commented Jun 20, 2021

This closes the issue noted in #915, i.e. the following now works:

a  = SA[SA[1, 2], SA[3, 4]]
norm(a)

which threw before. It also fixes a similar issue for the "p"-norm.

This also fixes a few other issues with norm and friends:

  • Previously, the implementation of both the norm and "p"-norm were susceptible to integer overflow because they didn't convert to float early. They do now. This reduces performance a slight bit for ::SVector{Int} but that seems preferable to quietly overflowing.
  • Previously, the "p"-norm implementation was type-unstable for SVector{Int} inputs (sometimes returning Float64 sometimes Int, depending on p). It now always returns a floating point value, consistently with Base.

@thchr
Copy link
Collaborator Author

thchr commented Jun 20, 2021

Regarding test failures:

  • Failure in test/broadcast.jl: this one was genuine - I needed to widen the type of a few methods to not just allow (Static)Vectors but StaticArrays or AbstractArrays. Fixed.
  • Failure in test/ambiguities.jl: seems to just be broken generally on higher versions of Julia - I see this in other PRs and in local testing.
    I see 61 ambiguities on the v1.2.3 of StaticArrays.jl on Julia 1.6.0; it's 49 with this PR, so actually seems better?
  • Failures in test/arraymath.jl: throws on testing that @allocated(arithmetic_closure(T0)) == 0 for T0 in Int64, Float32, Float64. Also did that before this PR afaict though (tested locally) - so seems unrelated.
  • Failure in test/svd.jl: an inference failure that also happens on v1.2.3 of StaticArrays.jl on Julia v1.6. Unrelated to this PR. Seems to be due to a failure to constant propagate a keyword from svd(A; full::Bool) to a Val in _svd(A, ::Val{<:Bool}).

I tested that the remaining tests pass locally (on Julia v1.6.0).

@thchr thchr force-pushed the norm-fix branch 2 times, most recently from 59619ca to 736df94 Compare July 8, 2021 17:02
@thchr
Copy link
Collaborator Author

thchr commented Jul 8, 2021

CI is green on this - anyone up for reviewing this? (could I bother you perhaps @mateuszbaran?)

(I know caring about norm on nested arrays might seem low priority - but it would be nice to have this so that approximate comparisons of nested SVectors would work).

@mateuszbaran
Copy link
Collaborator

I'll take a look at this soon. There has recently been some trouble with reshape so I don't want to merge more things too quickly.

@thchr
Copy link
Collaborator Author

thchr commented Jul 8, 2021

Thanks!
(For what it's worth: this is rebased on top of your recent reshape fix (and I don't think it should interact with reshape in any way))

@thchr
Copy link
Collaborator Author

thchr commented Jul 9, 2021

Thanks for review and comments @mateuszbaran. There's one issue remaining (in inner_eltype, a conflict between desires for abstractly typed arrays and empty arrays) - let me know if you have ideas for how to fix that.

@mateuszbaran
Copy link
Collaborator

Having _init_zero and _inner_eltype defined only for StaticArrays and Numbers would make me more comfortable with this change. Currently it's trying to do things that I don't know how exactly should work. I think all other parts are good so I'd like to see this PR merged in a slightly limited version.

@thchr
Copy link
Collaborator Author

thchr commented Jul 12, 2021

Hmm, having _init_zero and _inner_eltype only defined for StaticArray and Number has some downsides though: e.g., if it doesn't include AbstractArrays, we'd then throw on this:

norm(SA[[0,0],[1,1]], 0)

since we need to infer the element type in _norm_p0 (which would call _inner_eltype on [0,0], hitting a MethodError).

To fix that, we can just use T = isempty(x) ? eltype(x) : float(norm(zero(first(x)))) in the first line of _norm_p0 instead of T = _inner_eltype(x) but then it's basically just code duplication.
I did that for now since that seemed the most consistent with your request to limit the method signatures.

It seems cleaner to me just to let the signature of _inner_eltype be maximally broad? Basically, I'm not sure I see what the downside to defining _inner_eltype is? It's [edit: not] a Base function and is only used very locally here. In any case, either approach works, so whichever is good for me.

@mateuszbaran
Copy link
Collaborator

Well, I think _norm_p0 should use _inner_eltype, and maybe it's actually fine to keep _inner_eltype defined for AbstractArrays -- I'll take another look at this later.

@thchr
Copy link
Collaborator Author

thchr commented Jul 26, 2021

@matbesancon gentle bump: would be good to wrap this one up while we both remember it :)

@mateuszbaran
Copy link
Collaborator

I've looked at it again, would you be OK with _norm_p0 calling _inner_eltype and _inner_eltype being restricted to AbstractArray? It should be fine enough then 🙂 .

@mateuszbaran
Copy link
Collaborator

Thanks! One last thing, could you bump the patch version?

@thchr
Copy link
Collaborator Author

thchr commented Jul 26, 2021

Sure: rebased and bumped patch version in latest commit 👍

@mateuszbaran mateuszbaran merged commit 1d5524c into JuliaArrays:master Jul 27, 2021
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.

2 participants