File: morton_utils.pyx

package info (click to toggle)
python-ewah-bool-utils 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 448 kB
  • sloc: cpp: 1,709; ansic: 926; python: 249; makefile: 16
file content (150 lines) | stat: -rw-r--r-- 6,037 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import numpy as np

cimport cython
cimport numpy as np


@cython.cdivision(True)
@cython.boundscheck(False)
@cython.wraparound(False)
cdef np.uint32_t morton_neighbors_coarse(np.uint64_t mi1, np.uint64_t max_index1,
                                         bint periodicity[3], np.uint32_t nn,
                                         np.uint32_t[:,:] index,
                                         np.uint64_t[:,:] ind1_n,
                                         np.uint64_t[:] neighbors):
    cdef np.uint32_t ntot = 0
    cdef np.uint64_t ind1[3]
    cdef np.uint32_t count[3]
    cdef np.uint32_t origin[3]
    cdef np.int64_t adv
    cdef int i, j, k, ii, ij, ik
    for i in range(3):
        count[i] = 0
        origin[i] = 0
    # Get indices
    decode_morton_64bit(mi1,ind1)
    # Determine which directions are valid
    for j,i in enumerate(range(-nn,(nn+1))):
        if i == 0:
            for k in range(3):
                ind1_n[j,k] = ind1[k]
                index[count[k],k] = j
                origin[k] = count[k]
                count[k] += 1
        else:
            for k in range(3):
                adv = <np.int64_t>((<np.int64_t>ind1[k]) + i)
                if (adv < 0):
                    if periodicity[k]:
                        while adv < 0:
                            adv += max_index1
                        ind1_n[j,k] = <np.uint64_t>(adv % max_index1)
                    else:
                        continue
                elif (adv >= max_index1):
                    if periodicity[k]:
                        ind1_n[j,k] = <np.uint64_t>(adv % max_index1)
                    else:
                        continue
                else:
                    ind1_n[j,k] = <np.uint64_t>(adv)
                # print(i,k,adv,max_index1,ind1_n[j,k],adv % max_index1)
                index[count[k],k] = j
                count[k] += 1
    # Iterate over ever combinations
    for ii in range(count[0]):
        i = index[ii,0]
        for ij in range(count[1]):
            j = index[ij,1]
            for ik in range(count[2]):
                k = index[ik,2]
                if (ii != origin[0]) or (ij != origin[1]) or (ik != origin[2]):
                    neighbors[ntot] = encode_morton_64bit(ind1_n[i,0],
                                                          ind1_n[j,1],
                                                          ind1_n[k,2])
                    ntot += 1
    return ntot

@cython.cdivision(True)
@cython.boundscheck(False)
@cython.wraparound(False)
cdef np.uint32_t morton_neighbors_refined(np.uint64_t mi1, np.uint64_t mi2,
                                          np.uint64_t max_index1, np.uint64_t max_index2,
                                          bint periodicity[3], np.uint32_t nn,
                                          np.uint32_t[:,:] index,
                                          np.uint64_t[:,:] ind1_n,
                                          np.uint64_t[:,:] ind2_n,
                                          np.uint64_t[:] neighbors1,
                                          np.uint64_t[:] neighbors2):
    cdef np.uint32_t ntot = 0
    cdef np.uint64_t ind1[3]
    cdef np.uint64_t ind2[3]
    cdef np.uint32_t count[3]
    cdef np.uint32_t origin[3]
    cdef np.int64_t adv, maj, rem, adv1
    cdef int i, j, k, ii, ij, ik
    for i in range(3):
        count[i] = 0
        origin[i] = 0
    # Get indices
    decode_morton_64bit(mi1,ind1)
    decode_morton_64bit(mi2,ind2)
    # Determine which directions are valid
    for j,i in enumerate(range(-nn,(nn+1))):
        if i == 0:
            for k in range(3):
                ind1_n[j,k] = ind1[k]
                ind2_n[j,k] = ind2[k]
                index[count[k],k] = j
                origin[k] = count[k]
                count[k] += 1
        else:
            for k in range(3):
                adv = <np.int64_t>(ind2[k] + i)
                maj = adv // (<np.int64_t>max_index2)
                rem = adv % (<np.int64_t>max_index2)
                if adv < 0:
                    adv1 = <np.int64_t>(ind1[k] + (maj-1))
                    if adv1 < 0:
                        if periodicity[k]:
                            while adv1 < 0:
                                adv1 += max_index1
                            ind1_n[j,k] = <np.uint64_t>adv1
                        else:
                            continue
                    else:
                        ind1_n[j,k] = <np.uint64_t>adv1
                    while adv < 0:
                        adv += max_index2
                    ind2_n[j,k] = <np.uint64_t>adv
                elif adv >= max_index2:
                    adv1 = <np.int64_t>(ind1[k] + maj)
                    if adv1 >= max_index1:
                        if periodicity[k]:
                            ind1_n[j,k] = <np.uint64_t>(adv1 % <np.int64_t>max_index1)
                        else:
                            continue
                    else:
                        ind1_n[j,k] = <np.uint64_t>adv1
                    ind2_n[j,k] = <np.uint64_t>rem
                else:
                    ind1_n[j,k] = ind1[k]
                    ind2_n[j,k] = <np.uint64_t>(adv)
                index[count[k],k] = j
                count[k] += 1
    # Iterate over ever combinations
    for ii in range(count[0]):
        i = index[ii,0]
        for ij in range(count[1]):
            j = index[ij,1]
            for ik in range(count[2]):
                k = index[ik,2]
                if (ii != origin[0]) or (ij != origin[1]) or (ik != origin[2]):
                    neighbors1[ntot] = encode_morton_64bit(ind1_n[i,0],
                                                           ind1_n[j,1],
                                                           ind1_n[k,2])
                    neighbors2[ntot] = encode_morton_64bit(ind2_n[i,0],
                                                           ind2_n[j,1],
                                                           ind2_n[k,2])
                    ntot += 1
    return ntot