ufunc.cpp 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright Ankit Daftery 2011-2012.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. /**
  6. * @brief An example to demonstrate use of universal functions or ufuncs
  7. *
  8. *
  9. * @todo Calling the overloaded () operator is in a roundabout manner, find a simpler way
  10. * None of the methods like np::add, np::multiply etc are supported as yet
  11. */
  12. #include <boost/python/numpy.hpp>
  13. #include <iostream>
  14. namespace p = boost::python;
  15. namespace np = boost::python::numpy;
  16. // Create the structs necessary to implement the ufuncs
  17. // The typedefs *must* be made
  18. struct UnarySquare
  19. {
  20. typedef double argument_type;
  21. typedef double result_type;
  22. double operator()(double r) const { return r * r;}
  23. };
  24. struct BinarySquare
  25. {
  26. typedef double first_argument_type;
  27. typedef double second_argument_type;
  28. typedef double result_type;
  29. double operator()(double a,double b) const { return (a*a + b*b) ; }
  30. };
  31. int main(int argc, char **argv)
  32. {
  33. // Initialize the Python runtime.
  34. Py_Initialize();
  35. // Initialize NumPy
  36. np::initialize();
  37. // Expose the struct UnarySquare to Python as a class, and let ud be the class object
  38. p::object ud = p::class_<UnarySquare, boost::shared_ptr<UnarySquare> >("UnarySquare")
  39. .def("__call__", np::unary_ufunc<UnarySquare>::make());
  40. // Let inst be an instance of the class ud
  41. p::object inst = ud();
  42. // Use the "__call__" method to call the overloaded () operator and print the value
  43. std::cout << "Square of unary scalar 1.0 is " << p::extract <char const * > (p::str(inst.attr("__call__")(1.0))) << std::endl ;
  44. // Create an array in C++
  45. int arr[] = {1,2,3,4} ;
  46. // ..and use it to create the ndarray in Python
  47. np::ndarray demo_array = np::from_data(arr, np::dtype::get_builtin<int>() , p::make_tuple(4), p::make_tuple(4), p::object());
  48. // Print out the demo array
  49. std::cout << "Demo array is " << p::extract <char const * > (p::str(demo_array)) << std::endl ;
  50. // Call the "__call__" method to perform the operation and assign the value to result_array
  51. p::object result_array = inst.attr("__call__")(demo_array) ;
  52. // Print the resultant array
  53. std::cout << "Square of demo array is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
  54. // Lets try the same with a list
  55. p::list li ;
  56. li.append(3);
  57. li.append(7);
  58. // Print out the demo list
  59. std::cout << "Demo list is " << p::extract <char const * > (p::str(li)) << std::endl ;
  60. // Call the ufunc for the list
  61. result_array = inst.attr("__call__")(li) ;
  62. // And print the list out
  63. std::cout << "Square of demo list is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
  64. // Now lets try Binary ufuncs
  65. // Expose the struct BinarySquare to Python as a class, and let ud be the class object
  66. ud = p::class_<BinarySquare, boost::shared_ptr<BinarySquare> >("BinarySquare")
  67. .def("__call__", np::binary_ufunc<BinarySquare>::make());
  68. // Again initialise inst as an instance of the class ud
  69. inst = ud();
  70. // Print the two input listsPrint the two input lists
  71. 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 ;
  72. // Call the binary ufunc taking demo_array as both inputs
  73. result_array = inst.attr("__call__")(demo_array,demo_array) ;
  74. std::cout << "Square of list with binary ufunc is " << p::extract <char const * > (p::str(result_array)) << std::endl ;
  75. }