]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/python/doc/numpy/tutorial/ufunc.rst
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / python / doc / numpy / tutorial / ufunc.rst
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