Michele De Stefano's C++ Utilities
matrix_usage.i
1 // matrix_usage.i
2 //
3 // Copyright (c) 2014 - Michele De Stefano (micdestefano@users.sourceforge.net)
4 //
5 // Distributed under the MIT License (See accompanying file LICENSE)
6 
7 
8 /*
9  * Instructions for generating and building the extension:
10  *
11  * 1. swig -c++ -Wall -python -I../../../../include -o matrix_usage_wrap.cpp matrix_usage.i
12  *
13  * 2. python setup.py build
14  */
15 
16 /**
17  * \example matrix_usage.i
18  *
19  * A simple SWIG interface for a Python extension module that shows the
20  * mds_utils::python::ublas::to_python and
21  * mds_utils::python::ublas::get usage for boost::numeric::ublas::matrix objects.
22  * These functions are indirectly
23  * used through typemaps included with the matrix.i interface.
24  * The output from the Python command line is shown in matrix_usage.pycmd.
25  *
26  * \remarks Here I've used SWIG for convenience only. The C++ code of
27  * mds-utils does not require you to make this choice.
28  */
29 
30 %module matrix_usage
31 
32 // The following instruction includes all the required typemaps
33 %include "mds_utils/python/ublas/matrix.i"
34 
35 %header %{
36 #include <boost/numeric/ublas/io.hpp>
37 #include <algorithm>
38 #include <iostream>
39 #include <complex>
40 
41 namespace mdspy = mds_utils::python;
42 using namespace std;
43 %}
44 
45 
46 %feature("autodoc","3");
47 
48 %inline %{
49 
50 // Tests building and returning a matrix with column major ordering, without direct conversion to NumPy
51 boost::numeric::ublas::matrix<double,boost::numeric::ublas::column_major>*
52  create_ublas_matrix_column_major() {
53 
54  namespace ub = boost::numeric::ublas;
55 
56  double buf[] = {1.1,2.2,3.3,4.4,5.5,6.6};
57 
58  size_t Nel(sizeof(buf)/sizeof(buf[0]));
59 
60  ub::matrix<double,ub::column_major>
61  *pM(new ub::matrix<double,ub::column_major>(3,2));
62 
63  copy(buf,buf+Nel,pM->data().begin());
64 
65  return pM;
66 }
67 
68 
69 void destroy_ublas_matrix_column_major(boost::numeric::ublas::matrix<double,boost::numeric::ublas::column_major>* pM) {
70 
71  delete pM;
72 }
73 
74 
75 // Tests building and returning a matrix with column major ordering
76 ublas_convert::matrix<double,boost::numeric::ublas::column_major>
77  create_npy_array() {
78 
79  namespace ub = boost::numeric::ublas;
80 
81  ub::matrix<double,ub::column_major>*
82  pM(create_ublas_matrix_column_major());
83 
84  ub::matrix<double,ub::column_major>
85  out(*pM);
86 
87  delete pM; pM = NULL;
88 
89  return out;
90 }
91 
92 
93 // Tests building and returning a matrix with row major ordering
94 ublas_convert::matrix<double>
95  create_npy_array_row() {
96 
97  namespace ub = boost::numeric::ublas;
98 
99  double buf[] = {1.1,2.2,3.3,4.4,5.5,6.6};
100 
101  size_t Nel(sizeof(buf)/sizeof(buf[0]));
102 
103  ub::matrix<double>
104  M(3,2);
105 
106  copy(buf,buf+Nel,M.data().begin());
107 
108  return M;
109 }
110 
111 
112 // Tests building and returning a matrix with complex elements
113 ublas_convert::matrix< std::complex<double> >
114  create_npy_array_cplx() {
115 
116  namespace ub = boost::numeric::ublas;
117 
118  complex<double> buf[] = {
119  complex<double>(1.1,1.1),
120  complex<double>(2.2,2.2),
121  complex<double>(3.3,3.3),
122  complex<double>(4.4,4.4),
123  complex<double>(5.5,5.5),
124  complex<double>(6.6,6.6)
125  };
126 
127  size_t Nel(6);
128 
129  ub::matrix< complex<double> >
130  M(3,2);
131 
132  copy(buf,buf+Nel,M.data().begin());
133 
134  return M;
135 }
136 
137 
138 // Tests building and returning a matrix of short, without conversion
139 boost::numeric::ublas::matrix<short>
140  create_ublas_matrix_short() {
141 
142  namespace ub = boost::numeric::ublas;
143 
144  short buf[] = {-1,2,-3,4,5,-6};
145 
146  size_t Nel(sizeof(buf)/sizeof(buf[0]));
147 
148  ub::matrix<short>
149  M(3,2);
150 
151  copy(buf,buf+Nel,M.data().begin());
152 
153  return M;
154 }
155 
156 
157 // Tests building and returning a matrix of short
158 ublas_convert::matrix<short>
159  create_npy_array_short() {
160 
161  return create_ublas_matrix_short();
162 }
163 
164 
165 
166 // Tests the "from Python converter"
167 void get_matrix(ublas_convert::matrix<double> m) {
168  using namespace std;
169 
170  cout << "Matrix got:" << endl << m << endl;
171 }
172 
173 
174 // Tests getting a matrix directly (i.e. without conversion from NumPy)
175 void get_matrix_no_conversion(const boost::numeric::ublas::matrix<double,boost::numeric::ublas::column_major>& m) {
176  using namespace std;
177 
178  cout << "Matrix got:" << endl << m << endl;
179 }
180 
181 
182 // Tests the "from Python converter" (opposite storage)
183 void get_matrix2(ublas_convert::matrix<double,boost::numeric::ublas::column_major> m) {
184  using namespace std;
185 
186  cout << "Matrix got:" << endl << m << endl;
187 }
188 
189 // Tests the "from Python converter" for complex numbers
190 void get_matrix3(ublas_convert::matrix< std::complex<double> > m) {
191  using namespace std;
192 
193  cout << "Matrix got:" << endl << m << endl;
194 }
195 
196 // Tests the "from Python converter", with conversion cast
197 void get_matrix4(ublas_convert::matrix<char> m) {
198  using namespace std;
199 
200  cout << "Matrix got:" << endl << m << endl;
201 }
202 
203 
204 
205 %}
206 
207 
208 %init %{
209  // The following instruction probably performs a dlopen for loading the
210  // numpy library. Without it, nothing works.
211  import_array();
212 %}
213 
214