Using SWIG Numpy Homework 10. Using C++ in Python Ján Dugáček November 21, 2018 Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Table of Contents 1 Using SWIG Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info 2 Numpy A note about C arrays A function SWIG file Result Exercise More info 3 Homework Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Motivation You will run into a lot of code written in Python in your life You might need to integrate C++ into it because cycles are not exactly fast in Python Using C++ is the only way to add new builtin types into Python Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Some class #i f n d e f PSEUDOFUNC_H #d e f i n e PSEUDOFUNC_H #i n c l u d e c l a s s pseudofunc { std : : map data ; p u b l i c : void add ( f l o a t x , f l o a t fx ) ; f l o a t at ( f l o a t x ) ; }; #e n d i f The parts with #ifndef and others are preventing the file from being included more than once, all you have to do is to give it a unique name Name is supposed to be pseudofunc.h Declarations of methods will be in another file Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Some class #2 #i n c l u d e " pseudofunc . h" void pseudofunc : : add ( f l o a t x , f l o a t fx ) { data [ x ] = fx ; } f l o a t pseudofunc : : at ( f l o a t x ) { i f ( data . empty ( ) ) r e t u r n 0; i f ( x f i r s t ) r e t u r n data . begin()−>second ; i f ( x>data . r b e g i n ()−> f i r s t ) r e t u r n data . r b e g i n ()−>second ; auto more = data . upper_bound ( x ) ; auto l e s s = std : : prev ( more ) ; f l o a t part =(x − l e s s −>f i r s t )/( more−>f i r s t − l e s s −>f i r s t ) ; r e t u r n part ∗ more−>second + (1 − part ) ∗ l e s s −>second ; } Now we define the methods, in a file that should be named pseudofunc.cpp Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Configuration file for SWIG %module pseudofunc %{ #i n c l u d e " pseudofunc . h" %} %i n c l u d e " pseudofunc . h" It tells SWIG how to compile the file, it allows a lot of tricks Make sure you don’t mistake the % for the # If using some other python-bound types, %include them as std_string.i These slides assume this file is named pseudofunc.i Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Using SWIG swig −c++ −python pseudofunc . i You need to have SWIG installed to do this in the command line You have to specify the code is in C++ (and not in C) and that you want to generate python code (and not for other programming languages) Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Using distutils to have Python compile it for itself #!/ usr / bin /env python3 from d i s t u t i l s . core import setup , Extension pseudofunc_module = Extension ( ’ _pseudofunc ’ , s o u r c e s =[ ’ pseudofunc_wrap . cxx ’ , ’ pseudofunc . cpp ’ ] , ) setup (name = ’ pseudofunc ’ , v e r s i o n = ’ 1 ’ , author = "Dugi" , d e s c r i p t i o n = """A pseudofunction """ , ext_modules = [ pseudofunc_module ] , py_modules = [ " pseudofunc " ] , ) If it’s called makePseudofunc.py, call python3 makePseudofunc.py build in command line Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Usage >>> import pseudofunc >>> p = pseudofunc . pseudofunc () >>> p . add (3 ,15) >>> p . add (4 ,20) >>> p . add (5 ,30) >>> p . at ( 4 . 1 ) 21.0 If you have the compiled file and the generated python file available (for example in the same folder), you can import it and use the class in Python Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info Exercise 1 Use C++ to create a mumpy Python module that will tell a random yer mum joke (out of at least 3) 2 Use C++ to create a simulacrum of std::vector in Pyton (or easy::vector 3 Use C++ to create some sort of 2D vector in Python 4 Use C++ to create a function in Python that computes the derivative of data in a form that fits you Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Motivation Some class Configuration file for SWIG Using SWIG Using distutils to have Python compile it for itself Usage Exercise More info More info A short guide to using SWIG is at https://www.cs.ubc.ca/~gberseth/blog/ using-swig-to-wrap-c-for-python.html A very detailed description of this functionality is at http://www.swig.org/Doc1.3/Python.html Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info A note about C arrays void arrayDemoC ( i n t ∗ a r r a y ) { i n t a = ∗ a r r a y ; i n t b = a r r a y [ 0 ] ; i n t c = a r r a y [ 1 ] ; } Arrays in C are actually naked pointers to the first element in an array Naked pointers, the only kind of pointers in C, are thus used in the same way as arrays The array’s size must be in another variable Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info A function #i n c l u d e " unnormalise . h" void unnormalise ( double ∗ in , i n t inS , double ∗ out , i n t outS ) { i f ( inS == 0 | | inS != outS ) r e t u r n ; double min = i n [ 0 ] ; f o r ( i n t i = 0; i < inS ; i++) i f ( i n [ i ] < min ) min = i n [ i ] ; min = 1 / min ; f o r ( i n t i = 0; i < inS ; i++) out [ i ] = i n [ i ] ∗ min ; } Numpy arrays are accessed as 2 variables, data and size Can you guess what this does? Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info A function #2 #i f n d e f UNNORMALISE_H #d e f i n e UUNORMALISE_H void unnormalise ( double ∗ in , i n t inS , double ∗ out , i n t outS ) ; #e n d i f We make it a header Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info SWIG file %module unnormalise %{ #d e f i n e SWIG_FILE_WITH_INIT #i n c l u d e " unnormalise . h" %} %i n c l u d e "numpy . i " %i n i t %{ import_array ( ) ; %} %apply ( double ∗ IN_ARRAY1, i n t DIM1) {( double ∗ in , i n t inS )} %apply ( double ∗ INPLACE_ARRAY1, i n t DIM1) {( double ∗ out , i n t %i n c l u d e " unnormalise . h" We need to enable the swig initialisation function import_array() with SWIG_FILE_WITH_INIT We need to map the input types to the argument names we are using Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info Result >>> import unnormalise >>> r e s u l t = numpy . empty_like ( x ) >>> unnormalise . unnormalise ( x , y ) It’s compiled like before It’s not possible to return an array (numpy’s SWIG interface is not great) It’s faster without returning, as new arrays aren’t created You can add a Python function that creates the result array and returns it To bind more values, use: %apply ( double ∗ IN_ARRAY1, i n t DIM1) {( double ∗ in1 , i n t inS1 ) , ( double ∗ in2 , i n t inS2 )} Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info Exercise 1 Write a C++ function that can find the median of a numpy array 2 Write a C++ function that can find the highest common denominator of all numbers in a numpy array 3 Write a C++ function that interpolates a two-variable function given by a 2D numpy array (assuming the indexes are x and y) 4 Write a C++ function that computes the divergence of a function given by a 3D numpy array 5 Write a C++ function that computes the curl of a function given by a 3D numpy array %apply ( double ∗ IN_ARRAY2, i n t DIM1 , i n t DIM2) {( double ∗ in , i n t in1 , i n t in2 )} Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info Exercise for those who don’t know numpy 1 Use C++ to add a function to Python that will sort a vector so that the highest number is the first 2 Use C++ to add a function to Python that prints a smiley of a given size made of spaces and some letter 3 Use C++ to create a Python class vector3D that supports addition and vector product 4 Use C++ to create a Python function to compute the mean root-mean-square deviation of given data 5 Use C++ to create a Python function to compute the covariance of two sets of given data Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework A note about C arrays A function SWIG file Result Exercise More info More info A description of using numpy with C++ is at https://www.scipy-lectures.org/advanced/ interfacing_with_c/interfacing_with_c.html#swig In-depth information can be found here https://docs.scipy.org/doc/numpy/reference/swig. interface-file.html Ján Dugáček 10. Using C++ in Python Using SWIG Numpy Homework Homework Use C++ to create a Python class that represents analytical functions composed of addition, subtraction, multiplication, division, power and logarithm You have two weeks to do it It’s recommended to compose it in a tree structure, starting with function f (x) = 1 and function f (x) = x and using operators to compose it, then operator() to call it For the ambitious: Give it a method to compute its derivative (still in analytical form) For lunatics: Give it a method to compute its primitive function (still in analytical form) Ján Dugáček 10. Using C++ in Python