| 832 | } // End anonymous namespace. |
| 833 | |
| 834 | VTK_ABI_NAMESPACE_BEGIN |
| 835 | //------------------------------------------------------------------------------ |
| 836 | void vtkAbstractArray::UpdateDiscreteValueSet(double uncertainty, double minimumProminence) |
| 837 | { |
| 838 | // For an array with T tuples and given uncertainty U and mininumum |
| 839 | // prominence P, we sample N blocks of M tuples each, with |
| 840 | // M*N = f(T; P, U) and f some sublinear function of T. |
| 841 | // If every component plus all components taken together each have more than |
| 842 | // MaxDiscreteValues distinct values, then we exit early. |
| 843 | // M is chosen based on the number of bytes per tuple to maximize use of a |
| 844 | // cache line (assuming a 64-byte cache line until kwsys::SystemInformation |
| 845 | // or the like can provide a platform-independent way to query it). |
| 846 | // |
| 847 | // N is chosen to satisfy the requested uncertainty and prominence criteria |
| 848 | // specified. |
| 849 | constexpr int cacheLineSize = 64; |
| 850 | constexpr int sampleFactor = 5; |
| 851 | |
| 852 | // I. Determine the granularity at which the array should be sampled. |
| 853 | int nc = this->NumberOfComponents; |
| 854 | int blockSize = cacheLineSize / (this->GetDataTypeSize() * nc); |
| 855 | if (!blockSize) |
| 856 | { |
| 857 | blockSize = 4; |
| 858 | } |
| 859 | double logfac = 1.; |
| 860 | vtkIdType nt = this->GetNumberOfTuples(); |
| 861 | vtkIdType numberOfSampleTuples = nt; |
| 862 | if (this->MaxId > 0 && minimumProminence > 0.0) |
| 863 | { |
| 864 | logfac = -log(uncertainty * minimumProminence) / minimumProminence; |
| 865 | if (logfac < 0) |
| 866 | { |
| 867 | logfac = -logfac; |
| 868 | } |
| 869 | if (!vtkMath::IsInf(logfac)) |
| 870 | { |
| 871 | numberOfSampleTuples = static_cast<vtkIdType>(sampleFactor * logfac); |
| 872 | } |
| 873 | } |
| 874 | /* |
| 875 | // Theoretically, we should discard values or tuples that recur fewer |
| 876 | // than minFreq times in our sample, but in practice this involves |
| 877 | // counting and communication that slow us down. |
| 878 | vtkIdType minFreq = static_cast<vtkIdType>( |
| 879 | numberOfSampleTuples * minimumProminence / 2); |
| 880 | */ |
| 881 | vtkIdType numberOfBlocks = |
| 882 | numberOfSampleTuples / blockSize + (numberOfSampleTuples % blockSize ? 1 : 0); |
| 883 | if (static_cast<unsigned int>(numberOfBlocks * blockSize) < 2 * this->MaxDiscreteValues) |
| 884 | { |
| 885 | numberOfBlocks = |
| 886 | 2 * this->MaxDiscreteValues / blockSize + (2 * this->MaxDiscreteValues % blockSize ? 1 : 0); |
| 887 | } |
| 888 | // II. Sample the array. |
| 889 | std::vector<std::vector<vtkVariant>> uniques(nc > 1 ? nc + 1 : nc); |
| 890 | switch (this->GetDataType()) |
| 891 | { |
no test coverage detected