1
votes

In Python I can initialize an x-length numpy array of negative inf with

import numpy as np
...
foo = np.array([np.NINF] * x)

where x is an int e.g. 42. I'd like to do the same in C++ with Boost.Python. The following obviously won't work:

namespace bnp = boost::python::numpy;
...
bnp::ndarray foo = bnp::array({-INFINITY} * x);

What are some good ways to do this?

Yes I'm aware of the Boost.Numpy docs and tutorial -- they're not great.

More generally, how can I initialize an std vector or array of length x with values -INFINITY?

UPDATE:

I'm trying to validate approaches (using an initial loop as suggested in the comments) by then printing to the console with

for (auto i=0; i<x; ++i) {
    std::cout << foo[i] << '\n';
}

but get the following error: error: use of overloaded operator '<<' is ambiguous (with operand types 'ostream' (aka 'basic_ostream<char>') and 'object_item' (aka 'proxy<boost::python::api::item_policies>')). Why won't this work? Is it an issue with trying to access a boost numpy array by index?

1
According to the docs, you can construct an array from a python list. Did you try something along the lines of: bp::list l; l.append(-INFINITY); l *= x; bnp::ndarray foo = bnp::array(l)? Unfortunately I don't have a build of boost python with numpy support at hand to test it. - Dan Mašek
You can use std::fill from the algorithm header to initalize a vector or array - Kochoba
@Kochoba Could you, please, elaborate on how that applies to the question? From what I found, the most straightforward way to get a boost::python::list from say a std::vector was an append in a loop. Using boost::python::numpy::from_data doesn't seem any more terse than the 4 statements above. In any case, we would be creating a new vector, so we can fill it directly in the constructor. Or did you have something else in mind? What specifically? - Dan Mašek
@DanMašek More generally, how can I initialize an std vector or array of length x with values -INFINITY - Kochoba
@DanMašek thanks for the suggestion. I'm trying bpy::list temp_list;, for (auto i=0; i<x; ++i) {temp_list.append(-INFINITY);}, bnp::ndarray foo = bnp::array(temp_list);. I'm unsure if this works as expected thought, and have updated the question accordingly. - BoltzmannBrain

1 Answers

1
votes

Here's a solution (thank you to @DanMašek for the initial idea) and how to validate by printing to the console:

bpy::list temp_list;
temp_list.append(-INFINITY);
temp_list *= x;
bnp::ndarray foo = bnp::array(temp_list);

where I have x=9. Validate w/

std::cout << std::endl << "Python ndarray : " << bpy::extract<char const *>(bpy::str(foo)) << std::endl;

You can also use the same temp_list to init another Python ndarray:

// after initializing bar the same as foo w/ temp_list
bar[0] = 0;
std::cout << std::endl << "Python ndarray : " << bpy::extract<char const *>(bpy::str(bar)) << std::endl;

And the resulting print out:

Python ndarray : [-inf -inf -inf -inf -inf -inf -inf -inf -inf]

Python ndarray : [  0. -inf -inf -inf -inf -inf -inf -inf -inf]