// Copyright 2024 DeepMind Technologies Limited // // AlphaFold 3 source code is licensed under CC BY-NC-SA 4.0. To view a copy of // this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/ // // To request access to the AlphaFold 3 model parameters, follow the process set // out at https://github.com/google-deepmind/alphafold3. You may only use these // if received directly from Google. Use is subject to terms of use available at // https://github.com/google-deepmind/alphafold3/blob/main/WEIGHTS_TERMS_OF_USE.md #include #include #include #include #include "absl/container/flat_hash_set.h" #include "pybind11/cast.h" #include "pybind11/numpy.h" #include "pybind11/pybind11.h" #include "pybind11_abseil/absl_casters.h" namespace { namespace py = pybind11; py::array_t IsIn(const py::array_t& array, const absl::flat_hash_set& test_elements, bool invert) { const size_t num_elements = array.size(); py::array_t output(num_elements); std::fill(output.mutable_data(), output.mutable_data() + output.size(), invert); // Shortcut: The output will be trivially always false if test_elements empty. if (test_elements.empty()) { return output; } for (size_t i = 0; i < num_elements; ++i) { if (test_elements.contains(array.data()[i])) { output.mutable_data()[i] = !invert; } } if (array.ndim() > 1) { auto shape = std::vector(array.shape(), array.shape() + array.ndim()); return output.reshape(shape); } return output; } constexpr char kIsInDoc[] = R"( Computes whether each element is in test_elements. Same use as np.isin, but much faster. If len(array) = n, len(test_elements) = m: * This function has complexity O(n). * np.isin with kind='sort' has complexity O(m*log(m) + n * log(m)). Args: array: Input NumPy array with dtype=np.int64. test_elements: The values against which to test each value of array. invert: If True, the values in the returned array are inverted, as if calculating `element not in test_elements`. Default is False. `isin(a, b, invert=True)` is equivalent to but faster than `~isin(a, b)`. Returns A boolean array of the same shape as the input array. Each value `val` is: * `val in test_elements` if `invert=False`, * `val not in test_elements` if `invert=True`. )"; } // namespace namespace alphafold3 { void RegisterModuleMembership(pybind11::module m) { m.def("isin", &IsIn, py::arg("array"), py::arg("test_elements"), py::kw_only(), py::arg("invert") = false, py::doc(kIsInDoc + 1)); } } // namespace alphafold3