| 962 | } |
| 963 | } |
| 964 | int vtkPKdTree::Select(int dim, int L, int R) |
| 965 | { |
| 966 | int K = ((R + L) / 2) + 1; |
| 967 | |
| 968 | this->_select(L, R, K, dim); |
| 969 | |
| 970 | if (K == L) |
| 971 | return K; |
| 972 | |
| 973 | // The global array is now re-ordered, partitioned around X[K]. |
| 974 | // (In particular, for all i, i<K, X[i] <= X[K] and for all i, |
| 975 | // i > K, X[i] >= X[K].) |
| 976 | // However the value at X[K] may occur more than once, and by |
| 977 | // construction of the reordered array, there is a J <= K such that |
| 978 | // for all i < J, X[i] < X[K] and for all J <= i < K X[i] = X[K]. |
| 979 | // |
| 980 | // We want to roll K back to this value J, so that all points are |
| 981 | // unambiguously assigned to one region or the other. |
| 982 | |
| 983 | int hasK = this->WhoHas(K); |
| 984 | int hasKrank = this->SubGroup->getLocalRank(hasK); |
| 985 | |
| 986 | int hasKleft = this->WhoHas(K - 1); |
| 987 | int hasKleftrank = this->SubGroup->getLocalRank(hasKleft); |
| 988 | |
| 989 | float Kval; |
| 990 | float Kleftval; |
| 991 | float* pt; |
| 992 | |
| 993 | if (hasK == this->MyId) |
| 994 | { |
| 995 | pt = this->GetLocalVal(K) + dim; |
| 996 | Kval = *pt; |
| 997 | } |
| 998 | |
| 999 | this->SubGroup->Broadcast(&Kval, 1, hasKrank); |
| 1000 | |
| 1001 | if (hasKleft == this->MyId) |
| 1002 | { |
| 1003 | pt = this->GetLocalVal(K - 1) + dim; |
| 1004 | Kleftval = *pt; |
| 1005 | } |
| 1006 | |
| 1007 | this->SubGroup->Broadcast(&Kleftval, 1, hasKleftrank); |
| 1008 | |
| 1009 | if (Kleftval != Kval) |
| 1010 | return K; |
| 1011 | |
| 1012 | int firstKval = this->TotalNumCells; // greater than any valid index |
| 1013 | |
| 1014 | if ((this->MyId <= hasKleft) && (this->NumCells[this->MyId] > 0)) |
| 1015 | { |
| 1016 | int start = this->EndVal[this->MyId]; |
| 1017 | start = std::min(start, K - 1); |
| 1018 | |
| 1019 | pt = this->GetLocalVal(start) + dim; |
| 1020 | |
| 1021 | if (*pt == Kval) |
no test coverage detected