Now ATIDLAS is standalone. Everything dynamic....
This commit is contained in:
51
python/pyatidlas/external/boost/libs/numpy/example/CMakeLists.txt
vendored
Normal file
51
python/pyatidlas/external/boost/libs/numpy/example/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# custom macro with most of the redundant code for making a python example module
|
||||
macro( addPythonExe _name _srccpp )
|
||||
ADD_EXECUTABLE(${_name} ${_srccpp})
|
||||
|
||||
# make the pyd library link against boost_numpy python and boost
|
||||
TARGET_LINK_LIBRARIES(${_name} boost_numpy ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
# put the example target into a VS solution folder named example (should
|
||||
# be a no-op for Linux)
|
||||
SET_PROPERTY(TARGET ${_name} PROPERTY FOLDER "example")
|
||||
endmacro()
|
||||
|
||||
macro( addPythonMod _name _srccpp )
|
||||
PYTHON_ADD_MODULE(${_name} ${_srccpp})
|
||||
|
||||
# make the pyd library link against boost_numpy python and boost
|
||||
TARGET_LINK_LIBRARIES(${_name} boost_numpy ${PYTHON_LIBRARIES} ${Boost_LIBRARIES})
|
||||
|
||||
# put the example target into a VS solution folder named example (should
|
||||
# be a no-op for Linux)
|
||||
SET_PROPERTY(TARGET ${_name} PROPERTY FOLDER "example")
|
||||
endmacro()
|
||||
|
||||
addPythonMod(gaussian gaussian.cpp)
|
||||
addPythonExe(dtype dtype.cpp)
|
||||
addPythonExe(fromdata fromdata.cpp)
|
||||
addPythonExe(ndarray ndarray.cpp)
|
||||
addPythonExe(simple simple.cpp)
|
||||
addPythonExe(ufunc ufunc.cpp)
|
||||
addPythonExe(wrap wrap.cpp)
|
||||
|
||||
# # installation logic (skip until it is better thought out)
|
||||
# set(DEST_EXAMPLE boost.numpy/example)
|
||||
#
|
||||
# # install executables demonstrating embedding python
|
||||
# install(TARGETS dtype fromdata ndarray simple ufunc wrap RUNTIME
|
||||
# DESTINATION ${DEST_EXAMPLE}
|
||||
# ${INSTALL_PERMSSIONS_RUNTIME}
|
||||
# )
|
||||
#
|
||||
# # install extension module
|
||||
# install(TARGETS gaussian LIBRARY
|
||||
# DESTINATION ${DEST_EXAMPLE}
|
||||
# ${INSTALL_PERMSSIONS_RUNTIME}
|
||||
# )
|
||||
#
|
||||
# # install source file using the extension module
|
||||
# install(FILES demo_gaussian.py
|
||||
# DESTINATION ${DEST_EXAMPLE}
|
||||
# ${INSTALL_PERMSSIONS_SRC}
|
||||
# )
|
20
python/pyatidlas/external/boost/libs/numpy/example/Jamfile
vendored
Normal file
20
python/pyatidlas/external/boost/libs/numpy/example/Jamfile
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright 2011 Stefan Seefeld.
|
||||
# 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)
|
||||
|
||||
import python ;
|
||||
|
||||
use-project /boost/numpy : ../src ;
|
||||
project /boost/numpy/example ;
|
||||
|
||||
lib boost_python ;
|
||||
|
||||
exe simple : simple.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
exe dtype : dtype.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
exe ndarray : ndarray.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
exe hybrid : hybrid.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
exe fromdata : fromdata.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
exe ufunc : ufunc.cpp ../src//boost_numpy boost_python /python//python ;
|
||||
|
||||
python-extension gaussian : gaussian.cpp ../src//boost_numpy boost_python ;
|
27
python/pyatidlas/external/boost/libs/numpy/example/SConscript
vendored
Normal file
27
python/pyatidlas/external/boost/libs/numpy/example/SConscript
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- python -*-
|
||||
|
||||
# Copyright Jim Bosch 2010-2012.
|
||||
# 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)
|
||||
|
||||
Import("env")
|
||||
|
||||
import os
|
||||
|
||||
example_env = env.Clone()
|
||||
lib_path = os.path.abspath(os.path.join("..", "src"))
|
||||
example_env.Append(LIBPATH=[lib_path])
|
||||
example_env.Append(RPATH=[lib_path])
|
||||
example_env.Append(LINKFLAGS = ["$__RPATH"]) # workaround for SCons bug #1644
|
||||
example_env.Append(LIBS=["boost_numpy"])
|
||||
|
||||
example = []
|
||||
|
||||
for name in ("ufunc", "dtype", "fromdata", "ndarray", "simple"):
|
||||
example.extend(example_env.Program(name, "%s.cpp" % name))
|
||||
|
||||
for name in ("gaussian",):
|
||||
example.extend(example_env.SharedLibrary(name, "%s.cpp" % name, SHLIBPREFIX=""))
|
||||
|
||||
Return("example")
|
37
python/pyatidlas/external/boost/libs/numpy/example/demo_gaussian.py
vendored
Normal file
37
python/pyatidlas/external/boost/libs/numpy/example/demo_gaussian.py
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
# Copyright Jim Bosch 2010-2012.
|
||||
# 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)
|
||||
|
||||
import numpy
|
||||
import gaussian
|
||||
|
||||
mu = numpy.zeros(2, dtype=float)
|
||||
sigma = numpy.identity(2, dtype=float)
|
||||
sigma[0, 1] = 0.15
|
||||
sigma[1, 0] = 0.15
|
||||
|
||||
g = gaussian.bivariate_gaussian(mu, sigma)
|
||||
|
||||
r = numpy.linspace(-40, 40, 1001)
|
||||
x, y = numpy.meshgrid(r, r)
|
||||
|
||||
z = g(x, y)
|
||||
|
||||
s = z.sum() * (r[1] - r[0])**2
|
||||
print "sum (should be ~ 1):", s
|
||||
|
||||
xc = (z * x).sum() / z.sum()
|
||||
print "x centroid (should be ~ %f): %f" % (mu[0], xc)
|
||||
|
||||
yc = (z * y).sum() / z.sum()
|
||||
print "y centroid (should be ~ %f): %f" % (mu[1], yc)
|
||||
|
||||
xx = (z * (x - xc)**2).sum() / z.sum()
|
||||
print "xx moment (should be ~ %f): %f" % (sigma[0,0], xx)
|
||||
|
||||
yy = (z * (y - yc)**2).sum() / z.sum()
|
||||
print "yy moment (should be ~ %f): %f" % (sigma[1,1], yy)
|
||||
|
||||
xy = 0.5 * (z * (x - xc) * (y - yc)).sum() / z.sum()
|
||||
print "xy moment (should be ~ %f): %f" % (sigma[0,1], xy)
|
49
python/pyatidlas/external/boost/libs/numpy/example/dtype.cpp
vendored
Normal file
49
python/pyatidlas/external/boost/libs/numpy/example/dtype.cpp
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to create ndarrays with built-in python data types, and extract
|
||||
* the types and values of member variables
|
||||
*
|
||||
* @todo Add an example to show type conversion.
|
||||
* Add an example to show use of user-defined types
|
||||
*
|
||||
*/
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create a 3x3 shape...
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
// ...as well as a type for C++ double
|
||||
np::dtype dtype = np::dtype::get_builtin<double>();
|
||||
// Construct an array with the above shape and type
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
// Print the array
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
// Print the datatype of the elements
|
||||
std::cout << "Datatype is:\n" << p::extract<char const *>(p::str(a.get_dtype())) << std::endl ;
|
||||
// Using user defined dtypes to create dtype and an array of the custom dtype
|
||||
// First create a tuple with a variable name and its dtype, double, to create a custom dtype
|
||||
p::tuple for_custom_dtype = p::make_tuple("ha",dtype) ;
|
||||
// The list needs to be created, because the constructor to create the custom dtype
|
||||
// takes a list of (variable,variable_type) as an argument
|
||||
p::list list_for_dtype ;
|
||||
list_for_dtype.append(for_custom_dtype) ;
|
||||
// Create the custom dtype
|
||||
np::dtype custom_dtype = np::dtype(list_for_dtype) ;
|
||||
// Create an ndarray with the custom dtype
|
||||
np::ndarray new_array = np::zeros(shape,custom_dtype);
|
||||
|
||||
}
|
48
python/pyatidlas/external/boost/libs/numpy/example/fromdata.cpp
vendored
Normal file
48
python/pyatidlas/external/boost/libs/numpy/example/fromdata.cpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to access data using raw pointers. This shows that you can use and
|
||||
* manipulate data in either Python or C++ and have the changes reflected in both.
|
||||
*/
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create an array in C++
|
||||
int arr[] = {1,2,3,4} ;
|
||||
// Create the ndarray in Python
|
||||
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
|
||||
// Print the ndarray that we just created, and the source C++ array
|
||||
std::cout << "C++ array :" << std::endl ;
|
||||
for (int j=0;j<4;j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ' ;
|
||||
}
|
||||
std::cout << std::endl << "Python ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
// Change an element in the python ndarray
|
||||
py_array[1] = 5 ;
|
||||
// And see if the C++ container is changed or not
|
||||
std::cout << "Is the change reflected in the C++ array used to create the ndarray ? " << std::endl ;
|
||||
for (int j = 0;j<4 ; j++)
|
||||
{
|
||||
std::cout << arr[j] << ' ' ;
|
||||
}
|
||||
// Conversely, change it in C++
|
||||
arr[2] = 8 ;
|
||||
// And see if the changes are reflected in the Python ndarray
|
||||
std::cout << std::endl << "Is the change reflected in the Python ndarray ?" << std::endl << p::extract<char const *>(p::str(py_array)) << std::endl;
|
||||
|
||||
}
|
315
python/pyatidlas/external/boost/libs/numpy/example/gaussian.cpp
vendored
Normal file
315
python/pyatidlas/external/boost/libs/numpy/example/gaussian.cpp
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
// Copyright Jim Bosch 2010-2012.
|
||||
// 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)
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#ifndef M_PI
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
const double M_PI = boost::math::constants::pi<double>();
|
||||
#endif
|
||||
|
||||
namespace bp = boost::python;
|
||||
namespace bn = boost::numpy;
|
||||
|
||||
/**
|
||||
* A 2x2 matrix class, purely for demonstration purposes.
|
||||
*
|
||||
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
|
||||
*/
|
||||
class matrix2 {
|
||||
public:
|
||||
|
||||
double & operator()(int i, int j) {
|
||||
return _data[i*2 + j];
|
||||
}
|
||||
|
||||
double const & operator()(int i, int j) const {
|
||||
return _data[i*2 + j];
|
||||
}
|
||||
|
||||
double const * data() const { return _data; }
|
||||
|
||||
private:
|
||||
double _data[4];
|
||||
};
|
||||
|
||||
/**
|
||||
* A 2-element vector class, purely for demonstration purposes.
|
||||
*
|
||||
* Instead of wrapping this class with Boost.Python, we'll convert it to/from numpy.ndarray.
|
||||
*/
|
||||
class vector2 {
|
||||
public:
|
||||
|
||||
double & operator[](int i) {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
double const & operator[](int i) const {
|
||||
return _data[i];
|
||||
}
|
||||
|
||||
double const * data() const { return _data; }
|
||||
|
||||
vector2 operator+(vector2 const & other) const {
|
||||
vector2 r;
|
||||
r[0] = _data[0] + other[0];
|
||||
r[1] = _data[1] + other[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
vector2 operator-(vector2 const & other) const {
|
||||
vector2 r;
|
||||
r[0] = _data[0] - other[0];
|
||||
r[1] = _data[1] - other[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
double _data[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* Matrix-vector multiplication.
|
||||
*/
|
||||
vector2 operator*(matrix2 const & m, vector2 const & v) {
|
||||
vector2 r;
|
||||
r[0] = m(0, 0) * v[0] + m(0, 1) * v[1];
|
||||
r[1] = m(1, 0) * v[0] + m(1, 1) * v[1];
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vector inner product.
|
||||
*/
|
||||
double dot(vector2 const & v1, vector2 const & v2) {
|
||||
return v1[0] * v2[0] + v1[1] * v2[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents a simple 2-d Gaussian (Normal) distribution, defined by a
|
||||
* mean vector 'mu' and a covariance matrix 'sigma'.
|
||||
*/
|
||||
class bivariate_gaussian {
|
||||
public:
|
||||
|
||||
vector2 const & get_mu() const { return _mu; }
|
||||
|
||||
matrix2 const & get_sigma() const { return _sigma; }
|
||||
|
||||
/**
|
||||
* Evaluate the density of the distribution at a point defined by a two-element vector.
|
||||
*/
|
||||
double operator()(vector2 const & p) const {
|
||||
vector2 u = _cholesky * (p - _mu);
|
||||
return 0.5 * _cholesky(0, 0) * _cholesky(1, 1) * std::exp(-0.5 * dot(u, u)) / M_PI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the density of the distribution at an (x, y) point.
|
||||
*/
|
||||
double operator()(double x, double y) const {
|
||||
vector2 p;
|
||||
p[0] = x;
|
||||
p[1] = y;
|
||||
return operator()(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from a mean vector and covariance matrix.
|
||||
*/
|
||||
bivariate_gaussian(vector2 const & mu, matrix2 const & sigma)
|
||||
: _mu(mu), _sigma(sigma), _cholesky(compute_inverse_cholesky(sigma))
|
||||
{}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* This evaluates the inverse of the Cholesky factorization of a 2x2 matrix;
|
||||
* it's just a shortcut in evaluating the density.
|
||||
*/
|
||||
static matrix2 compute_inverse_cholesky(matrix2 const & m) {
|
||||
matrix2 l;
|
||||
// First do cholesky factorization: l l^t = m
|
||||
l(0, 0) = std::sqrt(m(0, 0));
|
||||
l(0, 1) = m(0, 1) / l(0, 0);
|
||||
l(1, 1) = std::sqrt(m(1, 1) - l(0,1) * l(0,1));
|
||||
// Now do forward-substitution (in-place) to invert:
|
||||
l(0, 0) = 1.0 / l(0, 0);
|
||||
l(1, 0) = l(0, 1) = -l(0, 1) / l(1, 1);
|
||||
l(1, 1) = 1.0 / l(1, 1);
|
||||
return l;
|
||||
}
|
||||
|
||||
vector2 _mu;
|
||||
matrix2 _sigma;
|
||||
matrix2 _cholesky;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* We have a two options for wrapping get_mu and get_sigma into NumPy-returning Python methods:
|
||||
* - we could deep-copy the data, making totally new NumPy arrays;
|
||||
* - we could make NumPy arrays that point into the existing memory.
|
||||
* The latter is often preferable, especially if the arrays are large, but it's dangerous unless
|
||||
* the reference counting is correct: the returned NumPy array needs to hold a reference that
|
||||
* keeps the memory it points to from being deallocated as long as it is alive. This is what the
|
||||
* "owner" argument to from_data does - the NumPy array holds a reference to the owner, keeping it
|
||||
* from being destroyed.
|
||||
*
|
||||
* Note that this mechanism isn't completely safe for data members that can have their internal
|
||||
* storage reallocated. A std::vector, for instance, can be invalidated when it is resized,
|
||||
* so holding a Python reference to a C++ class that holds a std::vector may not be a guarantee
|
||||
* that the memory in the std::vector will remain valid.
|
||||
*/
|
||||
|
||||
/**
|
||||
* These two functions are custom wrappers for get_mu and get_sigma, providing the shallow-copy
|
||||
* conversion with reference counting described above.
|
||||
*
|
||||
* It's also worth noting that these return NumPy arrays that cannot be modified in Python;
|
||||
* the const overloads of vector::data() and matrix::data() return const references,
|
||||
* and passing a const pointer to from_data causes NumPy's 'writeable' flag to be set to false.
|
||||
*/
|
||||
static bn::ndarray py_get_mu(bp::object const & self) {
|
||||
vector2 const & mu = bp::extract<bivariate_gaussian const &>(self)().get_mu();
|
||||
return bn::from_data(
|
||||
mu.data(),
|
||||
bn::dtype::get_builtin<double>(),
|
||||
bp::make_tuple(2),
|
||||
bp::make_tuple(sizeof(double)),
|
||||
self
|
||||
);
|
||||
}
|
||||
static bn::ndarray py_get_sigma(bp::object const & self) {
|
||||
matrix2 const & sigma = bp::extract<bivariate_gaussian const &>(self)().get_sigma();
|
||||
return bn::from_data(
|
||||
sigma.data(),
|
||||
bn::dtype::get_builtin<double>(),
|
||||
bp::make_tuple(2, 2),
|
||||
bp::make_tuple(2 * sizeof(double), sizeof(double)),
|
||||
self
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* To allow the constructor to work, we need to define some from-Python converters from NumPy arrays
|
||||
* to the matrix/vector types. The rvalue-from-python functionality is not well-documented in Boost.Python
|
||||
* itself; you can learn more from boost/python/converter/rvalue_from_python_data.hpp.
|
||||
*/
|
||||
|
||||
/**
|
||||
* We start with two functions that just copy a NumPy array into matrix/vector objects. These will be used
|
||||
* in the templated converted below. The first just uses the operator[] overloads provided by
|
||||
* bp::object.
|
||||
*/
|
||||
static void copy_ndarray_to_mv2(bn::ndarray const & array, vector2 & vec) {
|
||||
vec[0] = bp::extract<double>(array[0]);
|
||||
vec[1] = bp::extract<double>(array[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Here, we'll take the alternate approach of using the strides to access the array's memory directly.
|
||||
* This can be much faster for large arrays.
|
||||
*/
|
||||
static void copy_ndarray_to_mv2(bn::ndarray const & array, matrix2 & mat) {
|
||||
// Unfortunately, get_strides() can't be inlined, so it's best to call it once up-front.
|
||||
Py_intptr_t const * strides = array.get_strides();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
mat(i, j) = *reinterpret_cast<double const *>(array.get_data() + i * strides[0] + j * strides[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Here's the actual converter. Because we've separated the differences into the above functions,
|
||||
* we can write a single template class that works for both matrix2 and vector2.
|
||||
*/
|
||||
template <typename T, int N>
|
||||
struct mv2_from_python {
|
||||
|
||||
/**
|
||||
* Register the converter.
|
||||
*/
|
||||
mv2_from_python() {
|
||||
bp::converter::registry::push_back(
|
||||
&convertible,
|
||||
&construct,
|
||||
bp::type_id< T >()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if we can convert this to the desired type; if not return zero.
|
||||
* If we can convert, returned pointer can be used by construct().
|
||||
*/
|
||||
static void * convertible(PyObject * p) {
|
||||
try {
|
||||
bp::object obj(bp::handle<>(bp::borrowed(p)));
|
||||
std::auto_ptr<bn::ndarray> array(
|
||||
new bn::ndarray(
|
||||
bn::from_object(obj, bn::dtype::get_builtin<double>(), N, N, bn::ndarray::V_CONTIGUOUS)
|
||||
)
|
||||
);
|
||||
if (array->shape(0) != 2) return 0;
|
||||
if (N == 2 && array->shape(1) != 2) return 0;
|
||||
return array.release();
|
||||
} catch (bp::error_already_set & err) {
|
||||
bp::handle_exception();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish the conversion by initializing the C++ object into memory prepared by Boost.Python.
|
||||
*/
|
||||
static void construct(PyObject * obj, bp::converter::rvalue_from_python_stage1_data * data) {
|
||||
// Extract the array we passed out of the convertible() member function.
|
||||
std::auto_ptr<bn::ndarray> array(reinterpret_cast<bn::ndarray*>(data->convertible));
|
||||
// Find the memory block Boost.Python has prepared for the result.
|
||||
typedef bp::converter::rvalue_from_python_storage<T> storage_t;
|
||||
storage_t * storage = reinterpret_cast<storage_t*>(data);
|
||||
// Use placement new to initialize the result.
|
||||
T * m_or_v = new (storage->storage.bytes) T();
|
||||
// Fill the result with the values from the NumPy array.
|
||||
copy_ndarray_to_mv2(*array, *m_or_v);
|
||||
// Finish up.
|
||||
data->convertible = storage->storage.bytes;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(gaussian) {
|
||||
bn::initialize();
|
||||
|
||||
// Register the from-python converters
|
||||
mv2_from_python< vector2, 1 >();
|
||||
mv2_from_python< matrix2, 2 >();
|
||||
|
||||
typedef double (bivariate_gaussian::*call_vector)(vector2 const &) const;
|
||||
|
||||
bp::class_<bivariate_gaussian>("bivariate_gaussian", bp::init<bivariate_gaussian const &>())
|
||||
|
||||
// Declare the constructor (wouldn't work without the from-python converters).
|
||||
.def(bp::init< vector2 const &, matrix2 const & >())
|
||||
|
||||
// Use our custom reference-counting getters
|
||||
.add_property("mu", &py_get_mu)
|
||||
.add_property("sigma", &py_get_sigma)
|
||||
|
||||
// First overload accepts a two-element array argument
|
||||
.def("__call__", (call_vector)&bivariate_gaussian::operator())
|
||||
|
||||
// This overload works like a binary NumPy universal function: you can pass
|
||||
// in scalars or arrays, and the C++ function will automatically be called
|
||||
// on each element of an array argument.
|
||||
.def("__call__", bn::binary_ufunc<bivariate_gaussian,double,double,double>::make())
|
||||
;
|
||||
}
|
71
python/pyatidlas/external/boost/libs/numpy/example/ndarray.cpp
vendored
Normal file
71
python/pyatidlas/external/boost/libs/numpy/example/ndarray.cpp
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* @brief An example to show how to create ndarrays using arbitrary Python sequences.
|
||||
*
|
||||
* The Python sequence could be any object whose __array__ method returns an array, or any
|
||||
* (nested) sequence. This example also shows how to create arrays using both unit and
|
||||
* non-unit strides.
|
||||
*/
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
#if _MSC_VER
|
||||
using boost::uint8_t;
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create an ndarray from a simple tuple
|
||||
p::object tu = p::make_tuple('a','b','c') ;
|
||||
np::ndarray example_tuple = np::array (tu) ;
|
||||
// and from a list
|
||||
p::list l ;
|
||||
np::ndarray example_list = np::array (l) ;
|
||||
// Optionally, you can also specify a dtype
|
||||
np::dtype dt = np::dtype::get_builtin<int>();
|
||||
np::ndarray example_list1 = np::array (l,dt);
|
||||
// You can also create an array by supplying data.First,create an integer array
|
||||
int data[] = {1,2,3,4} ;
|
||||
// Create a shape, and strides, needed by the function
|
||||
p::tuple shape = p::make_tuple(4) ;
|
||||
p::tuple stride = p::make_tuple(4) ;
|
||||
// The function also needs an owner, to keep track of the data array passed. Passing none is dangerous
|
||||
p::object own ;
|
||||
// The from_data function takes the data array, datatype,shape,stride and owner as arguments
|
||||
// and returns an ndarray
|
||||
np::ndarray data_ex = np::from_data(data,dt,shape,stride,own);
|
||||
// Print the ndarray we created
|
||||
std::cout << "Single dimensional array ::" << std::endl << p::extract < char const * > (p::str(data_ex)) << std::endl ;
|
||||
// Now lets make an 3x2 ndarray from a multi-dimensional array using non-unit strides
|
||||
// First lets create a 3x4 array of 8-bit integers
|
||||
uint8_t mul_data[][4] = {{1,2,3,4},{5,6,7,8},{1,3,5,7}};
|
||||
// Now let's create an array of 3x2 elements, picking the first and third elements from each row
|
||||
// For that, the shape will be 3x2
|
||||
shape = p::make_tuple(3,2) ;
|
||||
// The strides will be 4x2 i.e. 4 bytes to go to the next desired row, and 2 bytes to go to the next desired column
|
||||
stride = p::make_tuple(4,2) ;
|
||||
// Get the numpy dtype for the built-in 8-bit integer data type
|
||||
np::dtype dt1 = np::dtype::get_builtin<uint8_t>();
|
||||
// First lets create and print out the ndarray as is
|
||||
np::ndarray mul_data_ex = np::from_data(mul_data,dt1, p::make_tuple(3,4),p::make_tuple(4,1),p::object());
|
||||
std::cout << "Original multi dimensional array :: " << std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
|
||||
// Now create the new ndarray using the shape and strides
|
||||
mul_data_ex = np::from_data(mul_data,dt1, shape,stride,p::object());
|
||||
// Print out the array we created using non-unit strides
|
||||
std::cout << "Selective multidimensional array :: "<<std::endl << p::extract < char const * > (p::str(mul_data_ex)) << std::endl ;
|
||||
|
||||
}
|
||||
|
||||
|
32
python/pyatidlas/external/boost/libs/numpy/example/simple.cpp
vendored
Normal file
32
python/pyatidlas/external/boost/libs/numpy/example/simple.cpp
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright 2011 Stefan Seefeld.
|
||||
// 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)
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Create a 3x3 shape...
|
||||
p::tuple shape = p::make_tuple(3, 3);
|
||||
// ...as well as a type for C++ float
|
||||
np::dtype dtype = np::dtype::get_builtin<float>();
|
||||
// Construct an array with the above shape and type
|
||||
np::ndarray a = np::zeros(shape, dtype);
|
||||
// Construct an empty array with the above shape and dtype as well
|
||||
np::ndarray b = np::empty(shape,dtype);
|
||||
// Print the array
|
||||
std::cout << "Original array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
// Reshape the array into a 1D array
|
||||
a = a.reshape(p::make_tuple(9));
|
||||
// Print it again.
|
||||
std::cout << "Reshaped array:\n" << p::extract<char const *>(p::str(a)) << std::endl;
|
||||
}
|
86
python/pyatidlas/external/boost/libs/numpy/example/ufunc.cpp
vendored
Normal file
86
python/pyatidlas/external/boost/libs/numpy/example/ufunc.cpp
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright Ankit Daftery 2011-2012.
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* @brief An example to demonstrate use of universal functions or ufuncs
|
||||
*
|
||||
*
|
||||
* @todo Calling the overloaded () operator is in a roundabout manner, find a simpler way
|
||||
* None of the methods like np::add, np::multiply etc are supported as yet
|
||||
*/
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
|
||||
// Create the structs necessary to implement the ufuncs
|
||||
// The typedefs *must* be made
|
||||
|
||||
struct UnarySquare
|
||||
{
|
||||
typedef double argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double r) const { return r * r;}
|
||||
};
|
||||
|
||||
struct BinarySquare
|
||||
{
|
||||
typedef double first_argument_type;
|
||||
typedef double second_argument_type;
|
||||
typedef double result_type;
|
||||
|
||||
double operator()(double a,double b) const { return (a*a + b*b) ; }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
// Initialize NumPy
|
||||
np::initialize();
|
||||
// Expose the struct UnarySquare to Python as a class, and let ud be the class object
|
||||
p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare")
|
||||
.def("__call__", np::unary_ufunc<UnarySquare>::make());
|
||||
// Let inst be an instance of the class ud
|
||||
p::object inst = ud();
|
||||
// Use the "__call__" method to call the overloaded () operator and print the value
|
||||
std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
|
||||
// Create an array in C++
|
||||
int arr[] = {1,2,3,4} ;
|
||||
// ..and use it to create the ndarray in Python
|
||||
np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
|
||||
// Print out the demo array
|
||||
std::cout << "Demo array is " << p::extract <char const * > (p::str(demo_array)) << std::endl ;
|
||||
// Call the "__call__" method to perform the operation and assign the value to result_array
|
||||
p::object result_array = inst.attr("__call__")(demo_array) ;
|
||||
// Print the resultant array
|
||||
std::cout << "Square of demo array is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
// Lets try the same with a list
|
||||
p::list li ;
|
||||
li.append(3);
|
||||
li.append(7);
|
||||
// Print out the demo list
|
||||
std::cout << "Demo list is " << p::extract <char const * > (p::str(li)) << std::endl ;
|
||||
// Call the ufunc for the list
|
||||
result_array = inst.attr("__call__")(li) ;
|
||||
// And print the list out
|
||||
std::cout << "Square of demo list is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
// Now lets try Binary ufuncs
|
||||
// Expose the struct BinarySquare to Python as a class, and let ud be the class object
|
||||
ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare")
|
||||
.def("__call__", np::binary_ufunc<BinarySquare>::make());
|
||||
// Again initialise inst as an instance of the class ud
|
||||
inst = ud();
|
||||
// Print the two input listsPrint the two input lists
|
||||
std::cout << "The two input list for binary ufunc are " << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl << p::extract <char const * > (p::str(demo_array)) << std::endl ;
|
||||
// Call the binary ufunc taking demo_array as both inputs
|
||||
result_array = inst.attr("__call__")(demo_array,demo_array) ;
|
||||
std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
|
||||
}
|
||||
|
132
python/pyatidlas/external/boost/libs/numpy/example/wrap.cpp
vendored
Normal file
132
python/pyatidlas/external/boost/libs/numpy/example/wrap.cpp
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
// Copyright Jim Bosch 2011-2012.
|
||||
// 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)
|
||||
|
||||
/**
|
||||
* A simple example showing how to wrap a couple of C++ functions that
|
||||
* operate on 2-d arrays into Python functions that take NumPy arrays
|
||||
* as arguments.
|
||||
*
|
||||
* If you find have a lot of such functions to wrap, you may want to
|
||||
* create a C++ array type (or use one of the many existing C++ array
|
||||
* libraries) that maps well to NumPy arrays and create Boost.Python
|
||||
* converters. There's more work up front than the approach here,
|
||||
* but much less boilerplate per function. See the "Gaussian" example
|
||||
* included with Boost.NumPy for an example of custom converters, or
|
||||
* take a look at the "ndarray" project on GitHub for a more complete,
|
||||
* high-level solution.
|
||||
*
|
||||
* Note that we're using embedded Python here only to make a convenient
|
||||
* self-contained example; you could just as easily put the wrappers
|
||||
* in a regular C++-compiled module and imported them in regular
|
||||
* Python. Again, see the Gaussian demo for an example.
|
||||
*/
|
||||
|
||||
#include <boost/numpy.hpp>
|
||||
#include <boost/scoped_array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace p = boost::python;
|
||||
namespace np = boost::numpy;
|
||||
|
||||
// This is roughly the most efficient way to write a C/C++ function that operates
|
||||
// on a 2-d NumPy array - operate directly on the array by incrementing a pointer
|
||||
// with the strides.
|
||||
void fill1(double * array, int rows, int cols, int row_stride, int col_stride) {
|
||||
double * row_iter = array;
|
||||
double n = 0.0; // just a counter we'll fill the array with.
|
||||
for (int i = 0; i < rows; ++i, row_iter += row_stride) {
|
||||
double * col_iter = row_iter;
|
||||
for (int j = 0; j < cols; ++j, col_iter += col_stride) {
|
||||
*col_iter = ++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Here's a simple wrapper function for fill1. It requires that the passed
|
||||
// NumPy array be exactly what we're looking for - no conversion from nested
|
||||
// sequences or arrays with other data types, because we want to modify it
|
||||
// in-place.
|
||||
void wrap_fill1(np::ndarray const & array) {
|
||||
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (array.get_nd() != 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
fill1(reinterpret_cast<double*>(array.get_data()),
|
||||
array.shape(0), array.shape(1),
|
||||
array.strides(0) / sizeof(double), array.strides(1) / sizeof(double));
|
||||
}
|
||||
|
||||
// Another fill function that takes a double**. This is less efficient, because
|
||||
// it's not the native NumPy data layout, but it's common enough in C/C++ that
|
||||
// it's worth its own example. This time we don't pass the strides, and instead
|
||||
// in wrap_fill2 we'll require the C_CONTIGUOUS bitflag, which guarantees that
|
||||
// the column stride is 1 and the row stride is the number of columns. That
|
||||
// restricts the arrays that can be passed to fill2 (it won't work on most
|
||||
// subarray views or transposes, for instance).
|
||||
void fill2(double ** array, int rows, int cols) {
|
||||
double n = 0.0; // just a counter we'll fill the array with.
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
for (int j = 0; j < cols; ++j) {
|
||||
array[i][j] = ++n;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Here's the wrapper for fill2; it's a little more complicated because we need
|
||||
// to check the flags and create the array of pointers.
|
||||
void wrap_fill2(np::ndarray const & array) {
|
||||
if (array.get_dtype() != np::dtype::get_builtin<double>()) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect array data type");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (array.get_nd() != 2) {
|
||||
PyErr_SetString(PyExc_TypeError, "Incorrect number of dimensions");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
if (!(array.get_flags() & np::ndarray::C_CONTIGUOUS)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Array must be row-major contiguous");
|
||||
p::throw_error_already_set();
|
||||
}
|
||||
double * iter = reinterpret_cast<double*>(array.get_data());
|
||||
int rows = array.shape(0);
|
||||
int cols = array.shape(1);
|
||||
boost::scoped_array<double*> ptrs(new double*[rows]);
|
||||
for (int i = 0; i < rows; ++i, iter += cols) {
|
||||
ptrs[i] = iter;
|
||||
}
|
||||
fill2(ptrs.get(), array.shape(0), array.shape(1));
|
||||
}
|
||||
|
||||
BOOST_PYTHON_MODULE(example) {
|
||||
np::initialize(); // have to put this in any module that uses Boost.NumPy
|
||||
p::def("fill1", wrap_fill1);
|
||||
p::def("fill2", wrap_fill2);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// This line makes our module available to the embedded Python intepreter.
|
||||
PyImport_AppendInittab("example", &initexample);
|
||||
|
||||
// Initialize the Python runtime.
|
||||
Py_Initialize();
|
||||
|
||||
PyRun_SimpleString(
|
||||
"import example\n"
|
||||
"import numpy\n"
|
||||
"z1 = numpy.zeros((5,6), dtype=float)\n"
|
||||
"z2 = numpy.zeros((4,3), dtype=float)\n"
|
||||
"example.fill1(z1)\n"
|
||||
"example.fill2(z2)\n"
|
||||
"print z1\n"
|
||||
"print z2\n"
|
||||
);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user