N
nbigaouette
I need to sort a list of objects based on their position into a Z-oder
[1]. Everywhere I look, z-order is used by interleaving bit
representation of integers]. In my case, the objects have a double
precision[2] position in three dimension.
Somebody told me it would not work with double precision because the
mantissa has a different meaning then the exponent. But I was not
convinced and tried anyway. Actually, since the exponent is stored in
higher significant bits then the mantissa, I think I could interleave
the bits from the exponents, and then interleave the mantissa. So I
implemented that. Hell, I even did it manually (with 32 bits floats,
not 64 bits doubles).
But I cannot make it work reliably. I'd like to get some comments on
that...
My procedure was as follow. Place 16 particles on a 4x4 grid. The
positions in x and y dimensions are 1, 2, 3 and 4 bohrs[3] but
expressed in meters. The initial ordering (as found in memory) is:
13 14 15 16
9 10 11 12
5 6 7 8
1 2 3 4
The 16 [x,y] positions are, in meters:
[5.29177240552557e-11 , 5.29177240552557e-11]
[1.05835448110511e-10 , 5.29177240552557e-11]
[1.58753172165767e-10 , 5.29177240552557e-11]
[2.11670896221023e-10 , 5.29177240552557e-11]
[5.29177240552557e-11 , 1.05835448110511e-10]
[1.05835448110511e-10 , 1.05835448110511e-10]
[1.58753172165767e-10 , 1.05835448110511e-10]
[2.11670896221023e-10 , 1.05835448110511e-10]
[5.29177240552557e-11 , 1.58753172165767e-10]
[1.05835448110511e-10 , 1.58753172165767e-10]
[1.58753172165767e-10 , 1.58753172165767e-10]
[2.11670896221023e-10 , 1.58753172165767e-10]
[5.29177240552557e-11 , 2.11670896221023e-10]
[1.05835448110511e-10 , 2.11670896221023e-10]
[1.58753172165767e-10 , 2.11670896221023e-10]
[2.11670896221023e-10 , 2.11670896221023e-10]
As you might "see", the x dimension is incremented first, then y.
I then converted these decimals to binary representation[4]:
[00101110011010001011110000010000 , 00101110011010001011110000010000]
[00101110111010001011110000010000 , 00101110011010001011110000010000]
[00101111001011101000110100001100 , 00101110011010001011110000010000]
[00101111011010001011110000010000 , 00101110011010001011110000010000]
[00101110011010001011110000010000 , 00101110111010001011110000010000]
[00101110111010001011110000010000 , 00101110111010001011110000010000]
[00101111001011101000110100001100 , 00101110111010001011110000010000]
[00101111011010001011110000010000 , 00101110111010001011110000010000]
[00101110011010001011110000010000 , 00101111001011101000110100001100]
[00101110111010001011110000010000 , 00101111001011101000110100001100]
[00101111001011101000110100001100 , 00101111001011101000110100001100]
[00101111011010001011110000010000 , 00101111001011101000110100001100]
[00101110011010001011110000010000 , 00101111011010001011110000010000]
[00101110111010001011110000010000 , 00101111011010001011110000010000]
[00101111001011101000110100001100 , 00101111011010001011110000010000]
[00101111011010001011110000010000 , 00101111011010001011110000010000]
Then, I manually interleaved the x and y bits. For example, for the
first position [1,1] bohr, I first put the two binary numbers one
after the other. Secondly, I add a space between each digit, and third
shift the lower one by adding another space at the front of it. The
bit interleaving just then appears with the bits aligned:
1)
00101110011010001011110000010000
00101110011010001011110000010000
2)
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
3)
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
4)
0000110011111100001111001100000011001111111100000000001100000000
Doing this manual procedure for all the combinations, I get the
following:
0000110011111100001111001100000011001111111100000000001100000000 r1
0000110011111100101111001100000011001111111100000000001100000000 r2
0000110011111110000111001110100011000101111100100000000110100000 r3
0000110011111110001111001100000011001111111100000000001100000000 r4
0000110011111100011111001100000011001111111100000000001100000000 r5
0000110011111100111111001100000011001111111100000000001100000000 r6
0000110011111110010111001110101011000101111100100000000110100000 r7
0000110011111110011111001100000011001111111100000000001100000000 r8
0000110011111101001011001101010011001010111100010000001001010000 r9
0000110011111101101011001101010011001010111100010000001001010000
r10
0000110011111111000011001111110011000000111100110000000011110000
r11
0000110011111111001011001101010011001010111100010000001001010000
r12
0000110011111101001111001100000011001111111100000000001100000000
r13
0000110011111101101111001100000011001111111100000000001100000000
r14
0000110011111111000111001110100011000101111100100000000110100000
r15
0000110011111111001111001100000011001111111100000000001100000000
r16
Note that I added a name at the end to keep track of which line
represent which positions. I saved that to a file, cat'ed it, and
piped to "sort":
$ cat to_sort.txt | sort
0000110011111100001111001100000011001111111100000000001100000000 r1
0000110011111100011111001100000011001111111100000000001100000000 r5
0000110011111100101111001100000011001111111100000000001100000000 r2
0000110011111100111111001100000011001111111100000000001100000000 r6
0000110011111101001011001101010011001010111100010000001001010000 r9
0000110011111101001111001100000011001111111100000000001100000000
r13
0000110011111101101011001101010011001010111100010000001001010000
r10
0000110011111101101111001100000011001111111100000000001100000000
r14
0000110011111110000111001110100011000101111100100000000110100000 r3
0000110011111110001111001100000011001111111100000000001100000000 r4
0000110011111110010111001110101011000101111100100000000110100000 r7
0000110011111110011111001100000011001111111100000000001100000000 r8
0000110011111111000011001111110011000000111100110000000011110000
r11
0000110011111111000111001110100011000101111100100000000110100000
r15
0000110011111111001011001101010011001010111100010000001001010000
r12
0000110011111111001111001100000011001111111100000000001100000000
r16
I now have an (almost) Z-order list. Here is a what it produces:
13 14 15 16
| \ | \ | \ |
| \ | \ | \ |
9 10 | 11 12
\ | \
\ | \
5 6 | 7 ----- 8
| \ | | \
| \ | \ \
1 2 3 ----- 4
As you see, the 7 and 4 are inverted from what it should give (an "N"
ordering, instead of "Z", but that is equivalent and irrelevant). Now
if I automate all this, I get similar weird results. It is even worse
when the system is big. As examples, I have ploted the ordering for a
small grid (the previous example)[5], a bigger grid[6] and a big disk
[7]
Now I cannot belive that Z-ordering does not work with double
precision data since I almost got it. But then, I cannot correctly get
what I want... Did anybody worked with that before? Does anyone can
comment on the procedure? If you spot a mistake?
I absolutely need to make this working...
Thanx a lot.
[1] http://en.wikipedia.org/wiki/Z-order_(curve)
[2] http://en.wikipedia.org/wiki/Double_precision
[3] http://en.wikipedia.org/wiki/Bohr_radius
[4] http://www.binaryconvert.com/convert_float.html
[5] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_grid_small.png
[6] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_grid_big.png
[7] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_disk.png
[1]. Everywhere I look, z-order is used by interleaving bit
representation of integers]. In my case, the objects have a double
precision[2] position in three dimension.
Somebody told me it would not work with double precision because the
mantissa has a different meaning then the exponent. But I was not
convinced and tried anyway. Actually, since the exponent is stored in
higher significant bits then the mantissa, I think I could interleave
the bits from the exponents, and then interleave the mantissa. So I
implemented that. Hell, I even did it manually (with 32 bits floats,
not 64 bits doubles).
But I cannot make it work reliably. I'd like to get some comments on
that...
My procedure was as follow. Place 16 particles on a 4x4 grid. The
positions in x and y dimensions are 1, 2, 3 and 4 bohrs[3] but
expressed in meters. The initial ordering (as found in memory) is:
13 14 15 16
9 10 11 12
5 6 7 8
1 2 3 4
The 16 [x,y] positions are, in meters:
[5.29177240552557e-11 , 5.29177240552557e-11]
[1.05835448110511e-10 , 5.29177240552557e-11]
[1.58753172165767e-10 , 5.29177240552557e-11]
[2.11670896221023e-10 , 5.29177240552557e-11]
[5.29177240552557e-11 , 1.05835448110511e-10]
[1.05835448110511e-10 , 1.05835448110511e-10]
[1.58753172165767e-10 , 1.05835448110511e-10]
[2.11670896221023e-10 , 1.05835448110511e-10]
[5.29177240552557e-11 , 1.58753172165767e-10]
[1.05835448110511e-10 , 1.58753172165767e-10]
[1.58753172165767e-10 , 1.58753172165767e-10]
[2.11670896221023e-10 , 1.58753172165767e-10]
[5.29177240552557e-11 , 2.11670896221023e-10]
[1.05835448110511e-10 , 2.11670896221023e-10]
[1.58753172165767e-10 , 2.11670896221023e-10]
[2.11670896221023e-10 , 2.11670896221023e-10]
As you might "see", the x dimension is incremented first, then y.
I then converted these decimals to binary representation[4]:
[00101110011010001011110000010000 , 00101110011010001011110000010000]
[00101110111010001011110000010000 , 00101110011010001011110000010000]
[00101111001011101000110100001100 , 00101110011010001011110000010000]
[00101111011010001011110000010000 , 00101110011010001011110000010000]
[00101110011010001011110000010000 , 00101110111010001011110000010000]
[00101110111010001011110000010000 , 00101110111010001011110000010000]
[00101111001011101000110100001100 , 00101110111010001011110000010000]
[00101111011010001011110000010000 , 00101110111010001011110000010000]
[00101110011010001011110000010000 , 00101111001011101000110100001100]
[00101110111010001011110000010000 , 00101111001011101000110100001100]
[00101111001011101000110100001100 , 00101111001011101000110100001100]
[00101111011010001011110000010000 , 00101111001011101000110100001100]
[00101110011010001011110000010000 , 00101111011010001011110000010000]
[00101110111010001011110000010000 , 00101111011010001011110000010000]
[00101111001011101000110100001100 , 00101111011010001011110000010000]
[00101111011010001011110000010000 , 00101111011010001011110000010000]
Then, I manually interleaved the x and y bits. For example, for the
first position [1,1] bohr, I first put the two binary numbers one
after the other. Secondly, I add a space between each digit, and third
shift the lower one by adding another space at the front of it. The
bit interleaving just then appears with the bits aligned:
1)
00101110011010001011110000010000
00101110011010001011110000010000
2)
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
3)
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
0 0 1 0 1 1 1 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 0 0 0
4)
0000110011111100001111001100000011001111111100000000001100000000
Doing this manual procedure for all the combinations, I get the
following:
0000110011111100001111001100000011001111111100000000001100000000 r1
0000110011111100101111001100000011001111111100000000001100000000 r2
0000110011111110000111001110100011000101111100100000000110100000 r3
0000110011111110001111001100000011001111111100000000001100000000 r4
0000110011111100011111001100000011001111111100000000001100000000 r5
0000110011111100111111001100000011001111111100000000001100000000 r6
0000110011111110010111001110101011000101111100100000000110100000 r7
0000110011111110011111001100000011001111111100000000001100000000 r8
0000110011111101001011001101010011001010111100010000001001010000 r9
0000110011111101101011001101010011001010111100010000001001010000
r10
0000110011111111000011001111110011000000111100110000000011110000
r11
0000110011111111001011001101010011001010111100010000001001010000
r12
0000110011111101001111001100000011001111111100000000001100000000
r13
0000110011111101101111001100000011001111111100000000001100000000
r14
0000110011111111000111001110100011000101111100100000000110100000
r15
0000110011111111001111001100000011001111111100000000001100000000
r16
Note that I added a name at the end to keep track of which line
represent which positions. I saved that to a file, cat'ed it, and
piped to "sort":
$ cat to_sort.txt | sort
0000110011111100001111001100000011001111111100000000001100000000 r1
0000110011111100011111001100000011001111111100000000001100000000 r5
0000110011111100101111001100000011001111111100000000001100000000 r2
0000110011111100111111001100000011001111111100000000001100000000 r6
0000110011111101001011001101010011001010111100010000001001010000 r9
0000110011111101001111001100000011001111111100000000001100000000
r13
0000110011111101101011001101010011001010111100010000001001010000
r10
0000110011111101101111001100000011001111111100000000001100000000
r14
0000110011111110000111001110100011000101111100100000000110100000 r3
0000110011111110001111001100000011001111111100000000001100000000 r4
0000110011111110010111001110101011000101111100100000000110100000 r7
0000110011111110011111001100000011001111111100000000001100000000 r8
0000110011111111000011001111110011000000111100110000000011110000
r11
0000110011111111000111001110100011000101111100100000000110100000
r15
0000110011111111001011001101010011001010111100010000001001010000
r12
0000110011111111001111001100000011001111111100000000001100000000
r16
I now have an (almost) Z-order list. Here is a what it produces:
13 14 15 16
| \ | \ | \ |
| \ | \ | \ |
9 10 | 11 12
\ | \
\ | \
5 6 | 7 ----- 8
| \ | | \
| \ | \ \
1 2 3 ----- 4
As you see, the 7 and 4 are inverted from what it should give (an "N"
ordering, instead of "Z", but that is equivalent and irrelevant). Now
if I automate all this, I get similar weird results. It is even worse
when the system is big. As examples, I have ploted the ordering for a
small grid (the previous example)[5], a bigger grid[6] and a big disk
[7]
Now I cannot belive that Z-ordering does not work with double
precision data since I almost got it. But then, I cannot correctly get
what I want... Did anybody worked with that before? Does anyone can
comment on the procedure? If you spot a mistake?
I absolutely need to make this working...
Thanx a lot.
[1] http://en.wikipedia.org/wiki/Z-order_(curve)
[2] http://en.wikipedia.org/wiki/Double_precision
[3] http://en.wikipedia.org/wiki/Bohr_radius
[4] http://www.binaryconvert.com/convert_float.html
[5] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_grid_small.png
[6] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_grid_big.png
[7] http://nbigaouette.inrs-emt.homelinux.net/perso/zorder/Zorder_disk.png