2

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?

8
  • 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. Commented Mar 6, 2017 at 2:46
  • You can use std::fill from the algorithm header to initalize a vector or array Commented Mar 6, 2017 at 3:32
  • @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? Commented Mar 6, 2017 at 4:34
  • @DanMašek More generally, how can I initialize an std vector or array of length x with values -INFINITY Commented Mar 6, 2017 at 6:24
  • 1
    @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. Commented Mar 6, 2017 at 16:50

1 Answer 1

2

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]
Sign up to request clarification or add additional context in comments.

1 Comment

Nice. One comment -- since you're setting all the elements of the list to the same value, you can just use the * operator, as you would in Python.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.