File: array_like.hpp

package info (click to toggle)
python-boost-histogram 1.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,232 kB
  • sloc: python: 7,745; cpp: 3,243; makefile: 22; sh: 1
file content (35 lines) | stat: -rw-r--r-- 1,301 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Copyright 2018-2019 Hans Dembinski and Henry Schreiner
//
// Distributed under the 3-Clause BSD License.  See accompanying
// file LICENSE or https://github.com/scikit-hep/boost-histogram for details.

#pragma once

#include <bh_python/pybind11.hpp>

#include <boost/core/span.hpp>
#include <vector>

/// Generate empty array with same shape and strides as argument
template <class T>
py::array_t<T> array_like(const py::object& obj) {
    if(!py::isinstance<py::array>(obj)) {
        py::ssize_t shape[1] = {0}; // if scalar
        if(py::isinstance<py::sequence>(obj) && !py::isinstance<py::str>(obj)) {
            // if sequence
            auto seq = py::cast<py::sequence>(obj);
            shape[0] = static_cast<py::ssize_t>(seq.size());
        }
        return py::array_t<T>(shape);
    }
    auto arr = py::cast<py::array>(obj);
    std::vector<py::ssize_t> strides;
    strides.reserve(static_cast<std::size_t>(arr.ndim()));
    for(int i = 0; i < arr.ndim(); ++i) {
        strides.emplace_back(arr.strides()[i] / arr.itemsize()
                             * static_cast<py::ssize_t>(sizeof(T)));
    }
    return py::array_t<T>{boost::span<const py::ssize_t>{
                              arr.shape(), static_cast<std::size_t>(arr.ndim())},
                          strides};
}