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

Add isValidVertex #420

Merged
merged 3 commits into from
Jan 15, 2021
Merged

Add isValidVertex #420

merged 3 commits into from
Jan 15, 2021

Conversation

nrabinowitz
Copy link
Collaborator

Adds the isValidVertex function, with tests.

@coveralls
Copy link

coveralls commented Jan 9, 2021

Coverage Status

Coverage decreased (-0.06%) to 99.183% when pulling 6690c22 on nrabinowitz:is-valid-vertex into 5988d7c on uber:master.

}

int vertexNum = H3_GET_RESERVED_BITS(vertex);
H3Index owner = vertex;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need the extra variable owner here? Could you just work with vertex and avoid the copy? If just for naming purposes, maybe change the input parameter name to index (which is maybe actually more correct, since it is perfectly valid to input a non-vertex index into this function)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That's a good question - I guess it should be fine to modify vertex, though I generally think it's confusing to modify arguments in-place. Will update.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm actually going to recommend the opposite tack. Getting the owner H3Index is vital because I think this function should confirm that it can reproduce the original vertex value in here.

That will make this function slower, but since you'd only be validating the vertex if you're not sure about it, and since there are non-canonical representations that could be reached through some bit manipulation, it feels like the only time you'd be calling isVertexValid would be when you aren't getting them generated by the H3 library itself.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh huh. I hadn't even thought of it, but yeah, the best way to check whether we have the canonical representation is to run this through cellToVertex again and compare output. Easier than what I was thinking, where I'd have to get neighbors again. Good idea.

* @param vertex H3 index possibly describing a vertex
* @return Whether the input is valid
*/
int H3_EXPORT(isValidVertex)(H3Index vertex) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Do vertices have a unique representation? That is, for a given vertex, is it only allowed a single cell "owner"?

It doesn't look like this code checks if the vertex has the correct owner.

Copy link
Collaborator

Choose a reason for hiding this comment

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

My assumption is this function will assure the vertex is in the canonical form, if we want to support non-canonical vertexes, perhaps we need canonicalizeVertex/isCanonicalVertex?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hm. That's a good point, though there's no way at present that you can create a non-canonical vertex, so I'm leery about adding public functions addressing a practically unreachable issue. If we wanted this check, I think I'd need to implement vertexToCells first, and then check that the owner had the lowest numerical index.

I don't have a clear picture for the validation functions on whether we should prioritize speed (because you might need to validate many indexes at once) or exhaustiveness, which in this case would mean an expensive check for an unlikely case.

So I guess this brings up two questions:

  • Is there a use for a non-canonical vertex (i.e. an index indicating a cell and vertex number)? This would be easy to produce, but I'm not sure it has any value, and it would muddy the waters about whether all vertexes are canonical.
  • If not, is it worth an expensive check in this function for a case that at present would need to be hand-crafted?

Copy link
Contributor

@ajfriend ajfriend Jan 12, 2021

Choose a reason for hiding this comment

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

I think we definitely want uniqueness for the indices (and thus not allow "non-canonical" vertices), and if we have a function called isValidVertex it probably should be exhaustive and strictly correct. I think speed is secondary to correctness, and is something we could potentially improve in the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated to check validity by recreating the valid vertex and comparing, plus added a test for the incorrect-owner case. Recreating the vertex also covers the invalid vertex number case, so this simplified things nicely.

@ajfriend
Copy link
Contributor

I probably should have figured this out with the previous PR, but how exactly do vertices work? Is it the case that some cells are allowed to "own" vertices, and some are not?

If so, would it be possible to provide a function is_allowed_to_own_vertices(H3Index cell)?

If that isn't the case, however, does that mean vertices are not uniquely represented? For example, for a given vertex, could be vertexNum=2 for one cell, but vertexNum=5 for a different incident cell?

@ajfriend
Copy link
Contributor

Adding this for consideration: #421

@@ -85,4 +85,35 @@ SUITE(Vertex) {
t_assert(directionForVertexNum(pentagon, 5) == INVALID_DIGIT,
"invalid pent vertex should return invalid direction");
}

TEST(isValidVertex_hex) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a test for a specific valid vertex, to validate the right mode number is being used.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do.

@nrabinowitz
Copy link
Collaborator Author

I probably should have figured this out with the previous PR, but how exactly do vertices work? Is it the case that some cells are allowed to "own" vertices, and some are not?

See https://github.com/uber/h3/blob/master/dev-docs/RFCs/v4.0.0/vertex-mode-rfc.md - the basic idea is, you take the three cells sharing the vertex, and assign the lowest numeric index as the canonical owner. Ownership is an implementation detail, and shouldn't be exposed in the public API I think.

If so, would it be possible to provide a function is_allowed_to_own_vertices(H3Index cell)?

Nope, because a) not possible (a cell could own some vertices and not others), and b) not public info.

If that isn't the case, however, does that mean vertices are not uniquely represented? For example, for a given vertex, could be vertexNum=2 for one cell, but vertexNum=5 for a different incident cell?

See above - we just pick one cell and say that's the owner. What you're describing here is a non-canonical vertex, which I haven't implemented and don't see much use for, though let me know if you think there's some value.

return 0;
}

return H3_EXPORT(h3IsValid)(owner);
Copy link
Collaborator

Choose a reason for hiding this comment

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

May want to check that the owner is valid first?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hm. I guess it depends whether h3IsValid is faster - but it also would avoid handing invalid indexes to cellToVertex, so I think that makes sense.

@nrabinowitz nrabinowitz merged commit dd0b1e5 into uber:master Jan 15, 2021
@nrabinowitz nrabinowitz deleted the is-valid-vertex branch January 15, 2021 01:16
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.

5 participants