numpycpp
 All Classes Namespaces Files Functions Typedefs Pages
demo.cpp
Go to the documentation of this file.
1 /*
2  C *opyright (c) 2016 Michael Welter
3 
4  This file is part of numpycpp.
5 
6  numpycpp is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  numpycpp is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with numpycpp. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <iostream>
20 #include <sstream>
21 #include <boost/python/object.hpp>
22 #include "numpy.hpp"
23 
24 namespace py = boost::python;
25 namespace np = boost::python::numpy;
26 namespace nm = boost::python::numeric;
27 using namespace std;
28 
29 template<class T>
30 void print(const T &x, std::ostream &os)
31 {
32  os << x;
33 }
34 
35 template<>
36 void print<char>(const char &x, std::ostream &os)
37 {
38  os << (int)x;
39 }
40 
41 template<>
42 void print<PyObject*>(PyObject* const &x, std::ostream &os)
43 {
44  // increase reference count, so the object is not destructed when p goes out of scope.
45  // See http://www.boost.org/doc/libs/1_53_0/libs/python/doc/tutorial/doc/html/python/object.html#python.creating_python_object
46  py::object p(py::borrowed(x));
47  std::string s = py::extract<std::string>(py::str(p));
48  cout << s;
49 }
50 
51 
52 
53 template<class T>
54 void printElements(const np::arrayt<T> &a, int dim, int *indices)
55 {
56  if (dim >= a.rank())
57  {
58  cout << "(";
59  int i = 0;
60  while (i<a.rank()-1) cout << indices[i++] << ',';
61  cout << indices[i] << ") = ";
62  print(a(indices), cout);
63  cout << endl;
64  }
65  else
66  {
67  const int n = a.shape()[dim];
68  for (indices[dim]=0; indices[dim]<n; ++indices[dim])
69  {
70  printElements(a, dim+1, indices);
71  }
72  }
73 }
74 
75 template<class T>
76 void handleType(np::arraytbase arr, bool printContents)
77 {
78  if (np::getItemtype<T>() == arr.itemtype())
79  {
80  cout << "getItemtype<" << typeid(T).name() << "> matches type of array" << endl;
81  }
82  if (np::isCompatibleType<T>(arr.itemtype()))
83  {
84  if (printContents)
85  {
86  cout << "Printing array of type " << typeid(T).name() << endl;
87  int indices[np::MAX_DIM];
88  printElements(np::arrayt<T>(arr), 0, indices);
89  }
90  else
91  {
92  cout << "mapped c++ type = " << typeid(T).name() << endl;
93  }
94  }
95 }
96 
97 void printArrayInfo(const np::arraytbase &arr)
98 {
99  int i;
100  cout << "rank() = " << arr.rank() << endl;
101  cout << "itemtype() = " << arr.itemtype() << endl;
102  cout << "itemsize() = " << arr.itemsize() << endl;
103  cout << "isWriteable() = " << arr.isWriteable() << endl;
104  cout << "isCContiguous() = " << arr.isCContiguous() << endl;
105  cout << "isFContiguous() = " << arr.isFContiguous() << endl;
106  cout << "shape() = ";
107  for (i=0; i<arr.rank()-1; ++i)
108  cout << arr.shape()[i] << ',';
109  cout << arr.shape()[i] << endl;
110  cout << "strides() = ";
111  for (i=0; i<arr.rank()-1; ++i)
112  cout << arr.strides()[i] << ',';
113  cout << arr.strides()[i] << endl;
114 }
115 
116 
117 void printArray(nm::array pyarr, bool printContents)
118 {
119  np::arraytbase arr(pyarr);
120  printArrayInfo(arr);
121 
122  handleType<PyObject*>(arr, printContents);
123  handleType<float>(arr, printContents);
124  handleType<double>(arr, printContents);
125 
126  handleType<bool>(arr, printContents);
127  handleType<int>(arr, printContents);
128  handleType<short>(arr, printContents);
129  handleType<char>(arr, printContents);
130  handleType<long>(arr, printContents);
131  handleType<long long>(arr, printContents);
132 
133  handleType<unsigned int>(arr, printContents);
134  handleType<unsigned short>(arr, printContents);
135  handleType<unsigned char>(arr, printContents);
136  handleType<unsigned long>(arr, printContents);
137  handleType<unsigned long long>(arr, printContents);
138 }
139 
140 
141 template<class T>
142 void printConvertedArray(np::arrayt<T> arr)
143 {
144  printArrayInfo(arr);
145  handleType<T>(arr, true);
146 }
147 
148 template<class T>
149 std::string scalar_to_str(const T &x)
150 {
151  std::ostringstream os;
152  os << x;
153  return os.str();
154 }
155 
156 template<>
157 std::string scalar_to_str(const char &x)
158 {
159  std::ostringstream os;
160  os << (int)x;
161  return os.str();
162 }
163 
164 
165 np::arraytbase ReturnedFromCPP()
166 {
167  np::ssize_t dims = 5;
168  np::arrayt<float> ret(np::empty(1, &dims, np::getItemtype<float>()));
169  for (int i=0; i<dims; ++i)
170  ret[i] = i;
171  return ret;
172 }
173 
174 
175 py::object SumArrayT(np::arrayt<float> arr1, np::arrayt<float> arr2)
176 {
177  np::arrayt<float> ret(np::empty(arr1.rank(), arr1.dims(), arr1.itemtype()));
178 
179  const np::ssize_t *dims = arr1.dims();
180  for (int i=0; i<dims[0]; ++i)
181  {
182  ret(i) = arr1(i) + arr2(i);
183  }
184  return ret.getObject();
185 }
186 
187 py::object SumNumericArray(nm::array arr1, nm::array arr2)
188 {
189  const np::ssize_t len = py::extract<int>(py::getattr(arr1, "shape")[0]);
190  nm::array ret = py::extract<nm::array>(np::empty(1, &len, np::getItemtype(arr1)));
191  for (int i=0; i<len; ++i)
192  {
193  float x1 = py::extract<float>(arr1[i]);
194  float x2 = py::extract<float>(arr2[i]);
195  ret[i] = py::object(x1 + x2);
196  }
197  return ret;
198 }
199 
200 
201 
202 BOOST_PYTHON_MODULE(libdemo)
203 {
205  py::def("printArray", printArray);
206  py::def("printConvertedArray_int", printConvertedArray<int>);
207  py::def("char_to_str", scalar_to_str<char>);
208  py::def("int_to_str", scalar_to_str<int>);
209  py::def("float_to_str", scalar_to_str<float>);
210  py::def("double_to_str", scalar_to_str<double>);
211  py::def("SumArrayT", SumArrayT);
212  py::def("SumNumericArray", SumNumericArray);
213  py::def("ReturnedFromCPP", ReturnedFromCPP);
214 }
215 
216 
int getItemtype(const object &a)
Obtain numpy's data type number from an boost-python object which should hold a ndarray.
Definition: numpy.cpp:241
This is the base class from which type specific variants are derived.
Definition: numpy.hpp:248
Py_ssize_t ssize_t
Synonymous for Py_ssize_t.
Definition: numpy.hpp:145
object empty(int rank, const Py_ssize_t *dims, int type)
Create a new ndarray with uninitialized memory.
Definition: numpy.cpp:232
void importNumpyAndRegisterTypes()
Initializes things.
Definition: numpy.cpp:196
This class defines operators () and [] to allow for direct memory access to array elements of type T...
Definition: numpy.hpp:354
const ssize_t * strides() const
Returned in number of bytes.
Definition: numpy.cpp:309
Things are in here.