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

Should we avoid Vec constructor for AbstractVector? #398

Closed
ErickChacon opened this issue Apr 27, 2023 · 15 comments · Fixed by #400
Closed

Should we avoid Vec constructor for AbstractVector? #398

ErickChacon opened this issue Apr 27, 2023 · 15 comments · Fixed by #400
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@ErickChacon
Copy link
Member

ErickChacon commented Apr 27, 2023

This is related to JuliaEarth/GeoTables.jl#13, but in general it seems that is not a good idea to have non typestable contructor like the one defined for Vec over AbstracVector:

Vec(coords::AbstractVector{T}) where {T} = Vec{length(coords),T}(coords)
.

For example, StaticArrays.jl avoids it (https://github.com/JuliaArrays/StaticArrays.jl/blob/ed92217f94e2d70847bcf2b7716f47a410d52d25/docs/src/pages/api.md?plain=1#L237-L239).

We have avoided adding SVector(v::AbstractVector) as a valid constructor to
help users avoid the type instability (and potential performance disaster, if
used without care) of this innocuous looking expression.

@juliohm Should we avoid using the constructor for AbstractVector or limit it for few dimensions?

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

@ErickChacon thank you for sharing this information. I think it makes sense to follow the suggestion in StaticArrays.jl, mind submitting a PR?

@juliohm juliohm added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers labels Apr 28, 2023
@ErickChacon
Copy link
Member Author

@juliohm, happy to submit a PR. If we remove the constructor for AbstractVector, the way to solve JuliaEarth/GeoTables.jl#13 would be using Point(coords...) like the following? It works, are you OK with that?

import ArchGDAL as AG
import GeoInterface as GI
using Meshes

mypoint = AG.createpoint(1.0, 5.0)

function topoint(geom)
    coords = GI.coordinates(geom)
    Meshes.Point(coords...)
end

topoint(mypoint)

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

I understood that the idea was not to remove the constructor with AbstractVector, but to use the length function inside the function body with D=1,2,3, right? That doesn't solve the problem?

@ErickChacon
Copy link
Member Author

Yes, limiting to 1d, 2d, 3d solves the problem. However, I thought it would be good idea to follow StaticArrays.jl approach and avoid the constructor over AbstractVector. For now, I will make the PR limiting the function to few dimensions.

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

Oh I got it now. Can you remove the constructor with AbstractVector then to see if the test suite passes? I think we should follow StaticArrays.jl suggestion.

@ErickChacon
Copy link
Member Author

I am removing the AbstractVector constructor, but I also will need to change some some tests. Is that ok?

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

It sounds correct to me. Let's see what is the impact of removing this constructor in the PR and then we can figure out what is the best way forward. It should probably be fine to eliminate this constructor everywhere.

@ErickChacon
Copy link
Member Author

ErickChacon commented Apr 28, 2023

Great, I will remove it everywhere. There are also several tests that fails in Intersections when removing this constructor, but it is mainly because the AbstractVector constructor is used in few lines.

@ErickChacon
Copy link
Member Author

For collections we have this constructor

PointSet(coords::AbstractMatrix) = PointSet(Point.(eachcol(coords)))

that needs Vec for AbstractVector. Any suggestion?

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023 via email

@ErickChacon
Copy link
Member Author

Maybe something like the following?

PointSet(coords::AbstractMatrix) = PointSet(Point.(Tuple.(eachcol(coords))))

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

I would just do:

PointSet(coords::AbstractMatrix) = PointSet(Tuple.(eachcol(coords)))

given that there is another constructor for it already. Try to reduce to one of the previous constructors.

@ErickChacon
Copy link
Member Author

The following operation does not work.

Where A is an SMatrix and y is a Vec. The reason for this is that StaticArrays.jl tries to convert them to the same type before making the operation. Previously, it worked because converted A to Vec and later make the a operation.

It can be solved by using

λ = A \ SVector(y.coords)

Is there a beteer approach?

@juliohm
Copy link
Member

juliohm commented Apr 28, 2023

Maybe we should convert A and y in the very beginning of the algorithm to make them vanilla StaticVector and StaticMatrix? That way the entire code will work and we won't hit weird performance bugs.

@ErickChacon
Copy link
Member Author

Yes, that would be better. I am almost done, so I will start the pull request and move the discussion there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants