]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | Ufuncs |
2 | ====== | |
3 | ||
4 | Ufuncs or universal functions operate on ndarrays element by element, and support array broadcasting, type casting, and other features. | |
5 | ||
6 | Lets try and see how we can use the binary and unary ufunc methods | |
7 | ||
8 | After the neccessary includes :: | |
9 | ||
10 | #include <boost/python/numpy.hpp> | |
11 | #include <iostream> | |
12 | ||
13 | namespace p = boost::python; | |
14 | namespace np = boost::python::numpy; | |
15 | ||
16 | Now we create the structs necessary to implement the ufuncs. The typedefs *must* be made as the ufunc generators take these typedefs as inputs and return an error otherwise :: | |
17 | ||
18 | struct UnarySquare | |
19 | { | |
20 | typedef double argument_type; | |
21 | typedef double result_type; | |
22 | ||
23 | double operator()(double r) const { return r * r;} | |
24 | }; | |
25 | ||
26 | struct BinarySquare | |
27 | { | |
28 | typedef double first_argument_type; | |
29 | typedef double second_argument_type; | |
30 | typedef double result_type; | |
31 | ||
32 | double operator()(double a,double b) const { return (a*a + b*b) ; } | |
33 | }; | |
34 | ||
35 | Initialise the Python runtime and the numpy module :: | |
36 | ||
37 | int main(int argc, char **argv) | |
38 | { | |
39 | Py_Initialize(); | |
40 | np::initialize(); | |
41 | ||
42 | Now expose the struct UnarySquare to Python as a class, and let ud be the class object. :: | |
43 | ||
44 | p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare"); | |
45 | ud.def("__call__", np::unary_ufunc<UnarySquare>::make()); | |
46 | ||
47 | Let inst be an instance of the class ud :: | |
48 | ||
49 | p::object inst = ud(); | |
50 | ||
51 | Use the "__call__" method to call the overloaded () operator and print the value :: | |
52 | ||
53 | std::cout << "Square of unary scalar 1.0 is " << p::extract<char const *>(p::str(inst.attr("__call__")(1.0))) << std::endl; | |
54 | ||
55 | Create an array in C++ :: | |
56 | ||
57 | int arr[] = {1,2,3,4} ; | |
58 | ||
59 | ||
60 | ..and use it to create the ndarray in Python :: | |
61 | ||
62 | np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>(), | |
63 | p::make_tuple(4), | |
64 | p::make_tuple(4), | |
65 | p::object()); | |
66 | ||
67 | Print out the demo array :: | |
68 | ||
69 | std::cout << "Demo array is " << p::extract<char const *>(p::str(demo_array)) << std::endl; | |
70 | ||
71 | Call the "__call__" method to perform the operation and assign the value to result_array :: | |
72 | ||
73 | p::object result_array = inst.attr("__call__")(demo_array); | |
74 | ||
75 | Print the resultant array :: | |
76 | ||
77 | std::cout << "Square of demo array is " << p::extract<char const *>(p::str(result_array)) << std::endl; | |
78 | ||
79 | Lets try the same with a list :: | |
80 | ||
81 | p::list li; | |
82 | li.append(3); | |
83 | li.append(7); | |
84 | ||
85 | Print out the demo list :: | |
86 | ||
87 | std::cout << "Demo list is " << p::extract<char const *>(p::str(li)) << std::endl; | |
88 | ||
89 | Call the ufunc for the list :: | |
90 | ||
91 | result_array = inst.attr("__call__")(li); | |
92 | ||
93 | And print the list out :: | |
94 | ||
95 | std::cout << "Square of demo list is " << p::extract<char const *>(p::str(result_array)) << std::endl; | |
96 | ||
97 | Now lets try Binary ufuncs. Again, expose the struct BinarySquare to Python as a class, and let ud be the class object :: | |
98 | ||
99 | ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare"); | |
100 | ud.def("__call__", np::binary_ufunc<BinarySquare>::make()); | |
101 | ||
102 | And initialise ud :: | |
103 | ||
104 | inst = ud(); | |
105 | ||
106 | Print the two input lists :: | |
107 | ||
108 | std::cout << "The two input list for binary ufunc are " << std::endl | |
109 | << p::extract<char const *>(p::str(demo_array)) << std::endl | |
110 | << p::extract<char const *>(p::str(demo_array)) << std::endl; | |
111 | ||
112 | Call the binary ufunc taking demo_array as both inputs :: | |
113 | ||
114 | result_array = inst.attr("__call__")(demo_array,demo_array); | |
115 | ||
116 | And print the output :: | |
117 | ||
118 | std::cout << "Square of list with binary ufunc is " << p::extract<char const *>(p::str(result_array)) << std::endl; | |
119 | } | |
120 |