pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

python conversion of std::pair and std::array

Open liuzqt opened this issue 7 years ago • 1 comments

I have C++ functions, one accept std::vector<std::pair<double,double>> and the other accept std::vector<std::array<double, 2>> as param.
I tried to call with numpy array, the first one will success while the second one will fail.

I look into the param type, there are some difference:

The first one has param type List[Tuple[float, float]]

The second one has param type List[List[float[2]]]

I'm wondering how this will affect the compatibility of numpy? And if I do want std::vector<std::array<double, 2>> to accept numpy input, how should I do that ?

liuzqt avatar Aug 22 '18 18:08 liuzqt


#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <vector>
#include <array>

namespace py = pybind11;

void function_with_pair_param(const std::vector<std::pair<double, double>>& vec) {
    // This function accepts a vector of pairs
    for (const auto& p : vec) {
        std::cout << "pair: (" << p.first << ", " << p.second << ")\n";
    }
}

void function_with_array_param(const std::vector<std::array<double, 2>>& vec) {
    // This function accepts a vector of arrays
    for (const auto& a : vec) {
        std::cout << "array: (" << a[0] << ", " << a[1] << ")\n";
    }
}

std::vector<std::array<double, 2>> numpy_to_array_vector(py::array_t<double> arr) {
    // This function converts a NumPy array to std::vector<std::array<double, 2>>
    py::buffer_info buf_info = arr.request();
    if (buf_info.ndim != 2 || buf_info.shape[1] != 2) {
        throw std::runtime_error("Expected a 2D array with 2 columns.");
    }

    std::vector<std::array<double, 2>> result;
    auto ptr = static_cast<double*>(buf_info.ptr);
    for (ssize_t i = 0; i < buf_info.shape[0]; ++i) {
        std::array<double, 2> arr = {ptr[i * 2], ptr[i * 2 + 1]};
        result.push_back(arr);
    }

    return result;
}

PYBIND11_MODULE(example, m) {
    m.def("function_with_pair_param", &function_with_pair_param, "Function accepting std::vector<std::pair<double, double>>");
    m.def("function_with_array_param", &function_with_array_param, "Function accepting std::vector<std::array<double, 2>>");

    m.def("numpy_to_array_vector", &numpy_to_array_vector, "Convert NumPy array to std::vector<std::array<double, 2>>");
}

ljluestc avatar Nov 23 '24 20:11 ljluestc