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

Create… disorder. #2

Merged
merged 1 commit into from
Mar 28, 2021
Merged

Create… disorder. #2

merged 1 commit into from
Mar 28, 2021

Conversation

DoubleHyphen
Copy link
Contributor

There is a compiler intrinsic (and, I believe, also machine instruction) that counts how many zeros there are in the beginning of a given number. Using this, we can get rid of the order parametre, as follows:

  1. Examine how many leading zeros x and y have
  2. Select the smaller of those two (which is equivalent to (x|y).leading_zeros())
  3. Round it down to an even number if it is odd (equivalent to a & !1 interpreted as the amount of useless bits)
  4. Subtract it from the total amount of bits of each coordinate (32 in this case, interpreted as the amount of useful bits)
    and tada! you have the ideal number for the order parametre. No panics, no asserts, no nothing.

All that remains to be seen is whether this causes a slow-down, but given that the asserts are gone I'd wager that its speed has at worst remained the same.

@becheran
Copy link
Owner

This is very awesome. Thanks for opening the PR. Indeed the performance did not drop in a first quick check and I do like the extra magic in order to remove the error prone and mostly useless order flag. It does draw the curve a bit differently for odd orders (e.g. 3) compared to for example hilbert_2d. Do not think that this is a big issue though I would like to think about it a bit more before I pull this in.

@DoubleHyphen
Copy link
Contributor Author

The two ways that the curve is drawn should only differ by a 90° rotation. I tried making one myself, but the image appears to come out totally black?

@becheran
Copy link
Owner

@DoubleHyphen yea right. The draw function in my code is outdated/broken. I need to fix it.

I do love the idea of not having the order parameter, but I guess for "real" hilbert curve there is no way around it. Looking at hilbert curve images the mapping of coordinates rotates every 2nd iteration and without at least an odd/even bool there is no way of knowing were to go from 1D hilbert space back to the input space.

Though, the curve created with your pull request might even be more interesting for me. It is way cooler to not have this order/mapping issue as we have with the hilbert curve. Do you know if the curve already has a name or is a know variation of the hilbert curve?

@DoubleHyphen
Copy link
Contributor Author

DoubleHyphen commented Mar 27, 2021

OK so, on the one hand, I didn't read this trick anywhere. It's solely mine, if that's what you were asking.
On the other hand, uh… it's not a matter of “real” Hilbert curve vs “variation” thereof. If you rotate a shape 90° it still remains the same. The fact that the algorithms available so far were rotating it for no reason doesn't mean anything, in my point of view. If you'd like a name for it, might I suggest “orientation-stable encoding” or something to that extent?

BTW in your case it doesn't ever matter, but in lindel I noticed the following oddity:

use lindel::*;
let sample_1: [ u8; 3] = [3, 7, 2];
let sample_2: [u16; 3] = [3, 7, 2];
assert_eq!(sample_1.hilbert_index(), 456);
assert_eq!(sample_2.hilbert_index(), 110);
assert_ne!(sample_1.hilbert_index() as u64, sample_2.hilbert_index());

When the dimension is not a power of 2, promoting the coordinates to bigger data-types inserts leading zeros that end up changing the result! This can never be fully solved for all possible cases (edit: or can it?), but if I end up making LUTs for three or more dimensions I'd like to address this for those cases at least.

@becheran
Copy link
Owner

becheran commented Mar 28, 2021

Version 1.0 of fast hilbert will include your new curve computation. For me (and I guess for most people) it is just way more practical if you don't have to think about the order anymore. As soon as I find the time I will fix my image generate code and update the docs including you changes. Many thanks again!

@becheran becheran merged commit d812573 into becheran:main Mar 28, 2021
@DoubleHyphen
Copy link
Contributor Author

Booyah! On to the rest of the refactoring.
(Oh yeah, there's more where that came from…)

@becheran
Copy link
Owner

becheran commented Mar 31, 2021

@DoubleHyphen published version 1.0 which includes all your changes: https://crates.io/crates/fast_hilbert

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