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

Way to ustrip an array efficiently #717

Open
aplavin opened this issue Apr 30, 2024 · 3 comments
Open

Way to ustrip an array efficiently #717

aplavin opened this issue Apr 30, 2024 · 3 comments

Comments

@aplavin
Copy link
Contributor

aplavin commented Apr 30, 2024

Looks like there is no single way to "ustrip all values in an array, as efficiently as possible".

  • ustrip(x): efficient for Array (reinterprets), not efficient for range (materializes); also, deprecated
  • ustrip.(x): efficient for range of Quantities (keeps a range), not efficient for range of regular numbers or for Array (materializes/copies)

Would be great to have such a way!

@cstjean

This comment was marked as duplicate.

@sostock
Copy link
Collaborator

sostock commented Apr 30, 2024

  • ustrip(x): efficient for Array (reinterprets), not efficient for range (materializes)

The easiest would be to add efficient methods for ranges (they can just call the broadcasting methods). Then, ustrip(x) would always be the most efficient.

There is a proposal to apply the reinterpreting behavior to all StridedArray types, not just Array: #645 (#630 also has some related discussion).

In the discussion I also wondered whether it should be called ustrip!(x) or ustrip(reinterpret, x) to make it more obvious that it allows overwriting the original array. It is documented that ustrip(::Array) reinterprets, but people might overlook it or accidentally write ustrip(x) when they wanted ustrip.(x). I am fine with keeping the name ustrip(x) for the reinterpreting behavior, but I consider it a breaking change to extend it to other array types for which it reallocates right now.

  • ustrip.(x): efficient for range of Quantities (keeps a range), not efficient for range of regular numbers or for Array (materializes/copies)

This is what I would expect when broadcasting, so I would not change it.

@aplavin
Copy link
Contributor Author

aplavin commented May 5, 2024

I see, there are many different decisions and concerns that go into this issue!
My question was mostly from the user PoV, in that I regularly want to strip or add units in an array, just want it to be performant.

I also didn't find a straightforward builtin way to add units cheaply (that compiles to manual reinterpret for arrays + simple computation for ranges)... I guess will just go with FlexiMaps.mapview for now:

julia> using Unitful, FlexiMaps, Accessors

# for arrays – lazy map (view of the original), effectively similar to reinterpret:
julia> mapview((@o _ * u"km"), [1, 2, 3])
3-element FlexiMaps.MappedArray{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}, 1, Base.Fix2{typeof(*), Unitful.FreeUnits{(km,), 𝐋, nothing}}, Vector{Int64}}:
 1 km
 2 km
 3 km

julia> mapview(ustrip, [1,2,3]u"km")
3-element FlexiMaps.MappedArray{Int64, 1, typeof(ustrip), Vector{Quantity{Int64, 𝐋, Unitful.FreeUnits{(km,), 𝐋, nothing}}}}:
 1
 2
 3

# for ranges – performs straightforward arithmetics:
julia> mapview((@o _ * u"km"), 1:3)
1 km:1 km:3 km

julia> mapview(ustrip, 1:3)
1:1:3

but would be nice to have something builtin.

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

No branches or pull requests

3 participants