[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/boostorg/python/develop/src/numpy/ndarray.cpp [Back]  [Original]

// Copyright Jim Bosch 2010-2012.
// Copyright Stefan Seefeld 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#define BOOST_PYTHON_NUMPY_INTERNAL
#include 
#include 

namespace boost { namespace python {
namespace converter 
{
NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArray_Type, numpy::ndarray)
} // namespace boost::python::converter

namespace numpy 
{
namespace detail 
{

ndarray::bitflag numpy_to_bitflag(int const f)
{
  ndarray::bitflag r = ndarray::NONE;
  if (f & NPY_ARRAY_C_CONTIGUOUS) r = (r | ndarray::C_CONTIGUOUS);
  if (f & NPY_ARRAY_F_CONTIGUOUS) r = (r | ndarray::F_CONTIGUOUS);
  if (f & NPY_ARRAY_ALIGNED) r = (r | ndarray::ALIGNED);
  if (f & NPY_ARRAY_WRITEABLE) r = (r | ndarray::WRITEABLE);
  return r;
}

int bitflag_to_numpy(ndarray::bitflag f)
{
  int r = 0;
  if (f & ndarray::C_CONTIGUOUS) r |= NPY_ARRAY_C_CONTIGUOUS;
  if (f & ndarray::F_CONTIGUOUS) r |= NPY_ARRAY_F_CONTIGUOUS;
  if (f & ndarray::ALIGNED) r |= NPY_ARRAY_ALIGNED;
  if (f & ndarray::WRITEABLE) r |= NPY_ARRAY_WRITEABLE;
  return r;
}

bool is_c_contiguous(std::vector const & shape,
		     std::vector const & strides,
		     int itemsize)
{
  std::vector::const_reverse_iterator j = strides.rbegin();
  int total = itemsize;
  for (std::vector::const_reverse_iterator i = shape.rbegin(); i != shape.rend(); ++i, ++j) 
  {
    if (total != *j) return false;
    total *= (*i);
  }
  return true;
}

bool is_f_contiguous(std::vector const & shape,
		     std::vector const & strides,
		     int itemsize)
{
  std::vector::const_iterator j = strides.begin();
  int total = itemsize;
  for (std::vector::const_iterator i = shape.begin(); i != shape.end(); ++i, ++j)
  {
    if (total != *j) return false;
    total *= (*i);
  }
  return true;
}

bool is_aligned(std::vector const & strides,
		int itemsize)
{
  for (std::vector::const_iterator i = strides.begin(); i != strides.end(); ++i) 
  {
    if (*i % itemsize) return false;
  }
  return true;
}

inline PyArray_Descr * incref_dtype(dtype const & dt) 
{
  Py_INCREF(dt.ptr());
  return reinterpret_cast(dt.ptr());
}

ndarray from_data_impl(void * data, 
		       dtype const & dt, 
		       python::object const & shape,
		       python::object const & strides,
		       python::object const & owner,
		       bool writeable)
{
  std::vector shape_(len(shape));
  std::vector strides_(len(strides));
  if (shape_.size() != strides_.size()) 
  {
    PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
    python::throw_error_already_set();
  }
  for (std::size_t i = 0; i < shape_.size(); ++i) 
  {
    shape_[i] = python::extract(shape[i]);
    strides_[i] = python::extract(strides[i]);
  }
  return from_data_impl(data, dt, shape_, strides_, owner, writeable);
}

ndarray from_data_impl(void * data, 
		       dtype const & dt, 
		       std::vector const & shape,
		       std::vector const & strides,
		       python::object const & owner,
		       bool writeable)
{
  if (shape.size() != strides.size()) 
  {
    PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
    python::throw_error_already_set();
  }
  int itemsize = dt.get_itemsize();
  int flags = 0;
  if (writeable) flags |= NPY_ARRAY_WRITEABLE;
  if (is_c_contiguous(shape, strides, itemsize)) flags |= NPY_ARRAY_C_CONTIGUOUS;
  if (is_f_contiguous(shape, strides, itemsize)) flags |= NPY_ARRAY_F_CONTIGUOUS;
  if (is_aligned(strides, itemsize)) flags |= NPY_ARRAY_ALIGNED;
  ndarray r(python::detail::new_reference
    (PyArray_NewFromDescr(&PyArray_Type,
			  incref_dtype(dt),
			  shape.size(),
			  const_cast(shape.data()),
			  const_cast(strides.data()),
			  data,
			  flags,
			  NULL)));
    r.set_base(owner);
    return r;
}

} // namespace detail

namespace {
    int normalize_index(int n,int nlim) // wraps [-nlim:nlim) into [0:nlim), throw IndexError otherwise
    {
        if (n= nlim)
        {
            PyErr_SetObject(PyExc_IndexError, Py_None);
            throw_error_already_set();
        }
        return n;
    }
}

Py_intptr_t ndarray::shape(int n) const
{
    return get_shape()[normalize_index(n,get_nd())];
}

Py_intptr_t ndarray::strides(int n) const
{
    return get_strides()[normalize_index(n,get_nd())];
}

ndarray ndarray::view(dtype const & dt) const
{
  return ndarray(python::detail::new_reference
    (PyObject_CallMethod(this->ptr(), const_cast("view"), const_cast("O"), dt.ptr())));
}
    
ndarray ndarray::astype(dtype const & dt) const
{
  return ndarray(python::detail::new_reference
    (PyObject_CallMethod(this->ptr(), const_cast("astype"), const_cast("O"), dt.ptr())));
}

ndarray ndarray::copy() const 
{
  return ndarray(python::detail::new_reference
    (PyObject_CallMethod(this->ptr(), const_cast("copy"), const_cast(""))));
}

dtype ndarray::get_dtype() const 
{
  return dtype(python::detail::borrowed_reference(get_struct()->descr));
}

python::object ndarray::get_base() const 
{
  if (get_struct()->base == NULL) return object();
  return python::object(python::detail::borrowed_reference(get_struct()->base));
}

void ndarray::set_base(object const & base) 
{
  Py_XDECREF(get_struct()->base);
  if (base.ptr())
  {
    Py_INCREF(base.ptr());
    get_struct()->base = base.ptr();
  }
  else
  {
    get_struct()->base = NULL;
  }
}

ndarray::bitflag ndarray::get_flags() const
{
  return numpy::detail::numpy_to_bitflag(get_struct()->flags);
}

ndarray ndarray::transpose() const 
{
  return ndarray(python::detail::new_reference
    (PyArray_Transpose(reinterpret_cast(this->ptr()), NULL)));
}

ndarray ndarray::squeeze() const 
{
  return ndarray(python::detail::new_reference
    (PyArray_Squeeze(reinterpret_cast(this->ptr()))));
}

ndarray ndarray::reshape(python::tuple const & shape) const 
{
  return ndarray(python::detail::new_reference
    (PyArray_Reshape(reinterpret_cast(this->ptr()), shape.ptr())));
}

python::object ndarray::scalarize() const 
{
  Py_INCREF(ptr());
  return python::object(python::detail::new_reference(PyArray_Return(reinterpret_cast(ptr()))));
}

ndarray zeros(python::tuple const & shape, dtype const & dt) 
{
  int nd = len(shape);
  boost::scoped_array dims(new Py_intptr_t[nd]);
  for (int n=0; n

Web Proxy Viewer  |  New URL  |  Original Page