HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PyImathFixedMatrix.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
4 //
5 
6 // clang-format off
7 
8 #ifndef _PyImathFixedMatrix_h_
9 #define _PyImathFixedMatrix_h_
10 
11 #define HBOOST_BIND_GLOBAL_PLACEHOLDERS
12 #include <hboost/python.hpp>
13 #include <iostream>
14 #include "PyImathFixedArray.h"
15 #include "PyImathOperators.h"
16 
17 namespace PyImath {
18 
19 //
20 // Utility class for a runtime-specified fixed sized matrix type in python
21 //
22 template <class T>
24 {
25  T * _ptr;
26  int _rows;
27  int _cols;
28  int _rowStride;
29  int _colStride;
30  int * _refcount; // refcount if allocated, null if externally allocated
31 
32  public:
33 
34  FixedMatrix(T *ptr, int rows, int cols, int rowStride = 1, int colStride = 1)
35  : _ptr(ptr), _rows(rows), _cols(cols),
36  _rowStride(rowStride), _colStride(colStride), _refcount(0)
37  {
38  // nothing
39  }
40 
41  FixedMatrix(int rows, int cols)
42  : _ptr(new T[rows*cols]), _rows(rows), _cols(cols),
43  _rowStride(1), _colStride(1), _refcount(new int(1))
44  {
45  // nothing
46  }
47 
48  FixedMatrix(const FixedMatrix &other)
49  : _ptr(other._ptr), _rows(other._rows), _cols(other._cols),
50  _rowStride(other._rowStride), _colStride(other._colStride),
51  _refcount(other._refcount)
52  {
53  if (_refcount) *_refcount += 1;
54  }
55 
56  const FixedMatrix &
57  operator = (const FixedMatrix &other)
58  {
59  if (&other == this) return *this;
60  unref();
61  _ptr = other._ptr;
62  _rows = other._rows;
63  _cols = other._cols;
64  _rowStride = other._rowStride;
65  _colStride = other._colStride;
66  _refcount = other._refcount;
67 
68  if (_refcount) *_refcount += 1;
69  return *this;
70  }
71 
72  void
74  {
75  if (_refcount) {
76  *_refcount -= 1;
77  if (*_refcount == 0) {
78  delete [] _ptr;
79  delete _refcount;
80  }
81  }
82  _ptr = 0;
83  _rows = 0;
84  _cols = 0;
85  _rowStride = 0;
86  _colStride = 0;
87  _refcount = 0;
88  }
89 
91  {
92  unref();
93  }
94 
95  Py_ssize_t convert_index(int index) const
96  {
97  if (index < 0) index += _rows;
98  if (index >= _rows || index < 0) {
99  PyErr_SetString(PyExc_IndexError, "Index out of range");
100  hboost::python::throw_error_already_set();
101  }
102  return index;
103  }
104 
105  void extract_slice_indices(PyObject *index, Py_ssize_t &start, Py_ssize_t &end, Py_ssize_t &step, Py_ssize_t &slicelength) const
106  {
107  slicelength = 0;
108  if (PySlice_Check(index)) {
109 #if PY_MAJOR_VERSION > 2
110  PyObject *slice = index;
111 #else
112  PySliceObject *slice = reinterpret_cast<PySliceObject *>(index);
113 #endif
114  if (PySlice_GetIndicesEx(slice,_rows,&start,&end,&step,&slicelength) == -1) {
115  hboost::python::throw_error_already_set();
116  }
117  } else if (PyInt_Check(index)) {
118  Py_ssize_t i = convert_index(PyInt_AS_LONG(index));
119  start = i; end = i+1; step = 1; slicelength = 1;
120  } else {
121  PyErr_SetString(PyExc_TypeError, "Object is not a slice");
122  hboost::python::throw_error_already_set();
123  }
124  //std::cout << "Slice indices are " << start << " " << end << " " << step << " " << slicelength << std::endl;
125  }
126 
127  const FixedArray<T> * getitem(int index) const
128  {
129  return new FixedArray<T>(const_cast<T *>(&_ptr[convert_index(index)*_rowStride*_cols*_colStride]),_cols,_colStride);
130  }
131 
132  FixedMatrix getslice(PyObject *index) const
133  {
134  Py_ssize_t start, end, step, slicelength;
135  extract_slice_indices(index,start,end,step,slicelength);
136  FixedMatrix f(slicelength,_cols);
137  for (int i=0; i<slicelength; ++i) {
138  for (int j=0; j<_cols; ++j) {
139  f.element(i,j) = element((start+i*step),j);
140  }
141  }
142  return f;
143  }
144 
145  void
146  setitem_scalar(PyObject *index, const T &data)
147  {
148  Py_ssize_t start, end, step, slicelength;
149  extract_slice_indices(index,start,end,step,slicelength);
150  for (int i=0; i<slicelength; ++i) {
151  for (int j = 0; j < _cols; ++j) {
152  element(start+i*step,j) = data;
153  }
154  }
155  }
156 
157  void
159  {
160  Py_ssize_t start, end, step, slicelength;
161  extract_slice_indices(index,start,end,step,slicelength);
162  if (data.len() != _cols) {
163  PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
164  hboost::python::throw_error_already_set();
165  }
166  for (int i=0; i<slicelength; ++i) {
167  for (int j = 0; j < _cols; ++j) {
168  element(start+i*step,j) = data[j];
169  }
170  }
171  }
172 
173  void
175  {
176  Py_ssize_t start, end, step, slicelength;
177  extract_slice_indices(index,start,end,step,slicelength);
178 
179  // we have a valid range of indices
180  if (data.rows() != slicelength || data.cols() != cols()) {
181  PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
182  hboost::python::throw_error_already_set();
183  }
184  for (int i=0; i<slicelength; ++i) {
185  for (int j=0; j<cols(); ++j) {
186  element(start+i*step,j) = data.element(i,j);
187  }
188  }
189  }
190 
191  int rows() const { return _rows; }
192  int cols() const { return _cols; }
193  int rowStride() const { return _rowStride; }
194  int colStride() const { return _colStride; }
195 
196  T & element(int i, int j) { return _ptr[i*_rowStride*_cols*_colStride+j*_colStride]; }
197  const T & element(int i, int j) const { return _ptr[i*_rowStride*_cols*_colStride+j*_colStride]; }
198 
199  FixedArray<T> operator [] (int i) { return FixedArray<T>(&_ptr[i*_rowStride*_cols*_colStride],_cols,_colStride); }
200  const FixedArray<T> operator [] (int i) const { return FixedArray<T>(const_cast<T *>(&_ptr[i*_rowStride*_cols*_colStride]),_cols,_colStride); }
201 
202  static hboost::python::class_<FixedMatrix<T> > register_(const char *name, const char *doc)
203  {
204  hboost::python::class_<FixedMatrix<T> > c(name,doc, hboost::python::init<int,int>("return an uninitialized array of the specified rows and cols"));
205  c
206  .def("__getitem__", &FixedMatrix<T>::getslice)
207  .def("__getitem__", &FixedMatrix<T>::getitem, hboost::python::return_internal_reference<>())
208  .def("__setitem__", &FixedMatrix<T>::setitem_scalar)
209  .def("__setitem__", &FixedMatrix<T>::setitem_vector)
210  .def("__setitem__", &FixedMatrix<T>::setitem_matrix)
211  .def("__len__",&FixedMatrix<T>::rows)
212  .def("rows",&FixedMatrix<T>::rows)
213  .def("columns",&FixedMatrix<T>::cols)
214  ;
215  return c;
216  }
217 
218  template <class T2>
219  int match_dimension(const FixedMatrix<T2> &a1) const
220  {
221  if (rows() != a1.rows() || cols() != a1.cols()) {
222  PyErr_SetString(PyExc_IndexError, "Dimensions of source do not match destination");
223  hboost::python::throw_error_already_set();
224  }
225  return rows();
226  }
227 };
228 
229 // unary operation application
230 template <template <class,class> class Op, class T1, class Ret>
232 {
233  int rows = a1.rows();
234  int cols = a1.cols();
235  FixedMatrix<Ret> retval(rows,cols);
236  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
237  retval.element(i,j) = Op<T1,Ret>::apply(a1.element(i,j));
238  }
239  return retval;
240 }
241 
242 // binary operation application
243 template <template <class,class,class> class Op, class T1, class T2, class Ret>
245 {
246  int rows = a1.match_dimension(a2);
247  int cols = a1.cols();
248  FixedMatrix<Ret> retval(rows,cols);
249  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
250  retval.element(i,j) = Op<T1,T2,Ret>::apply(a1.element(i,j),a2.element(i,j));
251  }
252  return retval;
253 }
254 
255 template <template <class,class,class> class Op, class T1, class T2, class Ret>
257 {
258  int rows = a1.rows();
259  int cols = a1.cols();
260  FixedMatrix<Ret> retval(rows,cols);
261  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
262  retval.element(i,j) = Op<T1,T2,Ret>::apply(a1.element(i,j),a2);
263  }
264  return retval;
265 }
266 
267 template <template <class,class,class> class Op, class T1, class T2, class Ret>
269 {
270  int rows = a1.rows();
271  int cols = a1.cols();
272  FixedMatrix<Ret> retval(rows,cols);
273  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
274  retval.element(i,j) = Op<T2,T1,Ret>::apply(a2,a1.element(i,j));
275  }
276  return retval;
277 }
278 
279 // in-place binary operation application
280 template <template <class,class> class Op, class T1, class T2>
282 {
283  int rows = a1.match_dimension(a2);
284  int cols = a1.cols();
285  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
286  Op<T1,T2>::apply(a1.element(i,j),a2.element(i,j));
287  }
288  return a1;
289 }
290 
291 // in-place binary operation application
292 template <template <class,class> class Op, class T1, class T2>
294 {
295  int rows = a1.rows();
296  int cols = a1.cols();
297  for (int i=0;i<rows;++i) for (int j=0; j<cols; ++j) {
298  Op<T1,T2>::apply(a1.element(i,j),a2);
299  }
300  return a1;
301 }
302 
303 // PyObject* PyNumber_Add( PyObject *o1, PyObject *o2)
304 template <class T> static FixedMatrix<T> operator + (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_add,T,T,T>(a0,a1); }
305 template <class T> static FixedMatrix<T> operator + (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_add,T,T,T>(a0,v1); }
306 template <class T> static FixedMatrix<T> operator + (const T &v1, const FixedMatrix<T> &a0) { return a0+v1; }
307 
308 // PyObject* PyNumber_Subtract( PyObject *o1, PyObject *o2)
309 template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_sub,T,T,T>(a0,a1); }
310 template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_sub,T,T,T>(a0,v1); }
311 template <class T> static FixedMatrix<T> operator - (const T &v1, const FixedMatrix<T> &a0) { return apply_matrix_scalar_binary_op<op_rsub,T,T,T>(a0,v1); }
312 
313 // PyObject* PyNumber_Multiply( PyObject *o1, PyObject *o2)
314 template <class T> static FixedMatrix<T> operator * (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_mul,T,T,T>(a0,a1); }
315 template <class T> static FixedMatrix<T> operator * (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_mul,T,T,T>(a0,v1); }
316 template <class T> static FixedMatrix<T> operator * (const T &v1, const FixedMatrix<T> &a0) { return a0*v1; }
317 
318 // PyObject* PyNumber_Divide( PyObject *o1, PyObject *o2)
319 template <class T> static FixedMatrix<T> operator / (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_div,T,T,T>(a0,a1); }
320 template <class T> static FixedMatrix<T> operator / (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_div,T,T,T>(a0,v1); }
321 // no reversed scalar/matrix divide - no meaning
322 
323 // PyObject* PyNumber_FloorDivide( PyObject *o1, PyObject *o2)
324 // PyObject* PyNumber_TrueDivide( PyObject *o1, PyObject *o2)
325 // PyObject* PyNumber_Remainder( PyObject *o1, PyObject *o2)
326 template <class T> static FixedMatrix<T> operator % (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_mod,T,T,T>(a0,a1); }
327 template <class T> static FixedMatrix<T> operator % (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_mod,T,T,T>(a0,v1); }
328 // no reversed scalar%matrix remainder - no meaning
329 
330 // PyObject* PyNumber_Divmod( PyObject *o1, PyObject *o2)
331 
332 // PyObject* PyNumber_Power( PyObject *o1, PyObject *o2, PyObject *o3)
333 template <class T> static FixedMatrix<T> pow_matrix_matrix (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_pow,T,T,T>(a0,a1); }
334 template <class T> static FixedMatrix<T> pow_matrix_scalar (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_pow,T,T,T>(a0,v1); }
335 // no reversed scalar/matrix pow - no meaning
336 
337 // PyObject* PyNumber_Negative( PyObject *o)
338 template <class T> static FixedMatrix<T> operator - (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_neg,T,T>(a0); }
339 
340 // PyObject* PyNumber_Positive( PyObject *o)
341 
342 // PyObject* PyNumber_Absolute( PyObject *o)
343 template <class T> static FixedMatrix<T> abs (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_abs,T,T>(a0); }
344 
345 // PyObject* PyNumber_Invert( PyObject *o)
346 template <class T> static FixedMatrix<T> operator ~ (const FixedMatrix<T> &a0) { return apply_matrix_unary_op<op_inverse,T,T>(a0); }
347 
348 // PyObject* PyNumber_Lshift( PyObject *o1, PyObject *o2)
349 template <class T> static FixedMatrix<T> operator << (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_lshift,T,T,T>(a0,a1); }
350 template <class T> static FixedMatrix<T> operator << (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_lshift,T,T,T>(a0,v1); }
351 // no reversed
352 
353 // PyObject* PyNumber_Rshift( PyObject *o1, PyObject *o2)
354 template <class T> static FixedMatrix<T> operator >> (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_rshift,T,T,T>(a0,a1); }
355 template <class T> static FixedMatrix<T> operator >> (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_rshift,T,T,T>(a0,v1); }
356 // no reversed
357 
358 // PyObject* PyNumber_And( PyObject *o1, PyObject *o2)
359 template <class T> static FixedMatrix<T> operator & (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_bitand,T,T,T>(a0,a1); }
360 template <class T> static FixedMatrix<T> operator & (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_bitand,T,T,T>(a0,v1); }
361 template <class T> static FixedMatrix<T> operator & (const T &v1, const FixedMatrix<T> &a0) { return a0&v1; }
362 
363 // PyObject* PyNumber_Xor( PyObject *o1, PyObject *o2)
364 template <class T> static FixedMatrix<T> operator ^ (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_xor,T,T,T>(a0,a1); }
365 template <class T> static FixedMatrix<T> operator ^ (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_xor,T,T,T>(a0,v1); }
366 template <class T> static FixedMatrix<T> operator ^ (const T &v1, const FixedMatrix<T> &a0) { return a0^v1; }
367 
368 // PyObject* PyNumber_Or( PyObject *o1, PyObject *o2)
369 template <class T> static FixedMatrix<T> operator | (const FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_binary_op<op_bitor,T,T,T>(a0,a1); }
370 template <class T> static FixedMatrix<T> operator | (const FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_binary_op<op_bitor,T,T,T>(a0,v1); }
371 template <class T> static FixedMatrix<T> operator | (const T &v1, const FixedMatrix<T> &a0) { return a0|v1; }
372 
373 
374 // PyObject* PyNumber_InPlaceAdd( PyObject *o1, PyObject *o2)
375 template <class T> static FixedMatrix<T> & operator += (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_iadd,T,T>(a0,a1); }
376 template <class T> static FixedMatrix<T> & operator += (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_iadd,T,T>(a0,v1); }
377 
378 // PyObject* PyNumber_InPlaceSubtract( PyObject *o1, PyObject *o2)
379 template <class T> static FixedMatrix<T> & operator -= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_isub,T,T>(a0,a1); }
380 template <class T> static FixedMatrix<T> & operator -= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_isub,T,T>(a0,v1); }
381 
382 // PyObject* PyNumber_InPlaceMultiply( PyObject *o1, PyObject *o2)
383 template <class T> static FixedMatrix<T> & operator *= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_imul,T,T>(a0,a1); }
384 template <class T> static FixedMatrix<T> & operator *= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_imul,T,T>(a0,v1); }
385 
386 // PyObject* PyNumber_InPlaceDivide( PyObject *o1, PyObject *o2)
387 template <class T> static FixedMatrix<T> & operator /= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_idiv,T,T>(a0,a1); }
388 template <class T> static FixedMatrix<T> & operator /= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_idiv,T,T>(a0,v1); }
389 
390 // PyObject* PyNumber_InPlaceFloorDivide( PyObject *o1, PyObject *o2)
391 // not implemented
392 
393 // PyObject* PyNumber_InPlaceTrueDivide( PyObject *o1, PyObject *o2)
394 // not implemented
395 
396 // PyObject* PyNumber_InPlaceRemainder( PyObject *o1, PyObject *o2)
397 template <class T> static FixedMatrix<T> & operator %= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_imod,T,T>(a0,a1); }
398 template <class T> static FixedMatrix<T> & operator %= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_imod,T,T>(a0,v1); }
399 
400 // PyObject* PyNumber_InPlacePower( PyObject *o1, PyObject *o2, PyObject *o3)
401 template <class T> static FixedMatrix<T> & ipow_matrix_matrix (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ipow,T,T>(a0,a1); }
402 template <class T> static FixedMatrix<T> & ipow_matrix_scalar (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ipow,T,T>(a0,v1); }
403 
404 // PyObject* PyNumber_InPlaceLshift( PyObject *o1, PyObject *o2)
405 template <class T> static FixedMatrix<T> & operator <<= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ilshift,T,T>(a0,a1); }
406 template <class T> static FixedMatrix<T> & operator <<= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ilshift,T,T>(a0,v1); }
407 
408 // PyObject* PyNumber_InPlaceRshift( PyObject *o1, PyObject *o2)
409 template <class T> static FixedMatrix<T> & operator >>= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_irshift,T,T>(a0,a1); }
410 template <class T> static FixedMatrix<T> & operator >>= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_irshift,T,T>(a0,v1); }
411 
412 // PyObject* PyNumber_InPlaceAnd( PyObject *o1, PyObject *o2)
413 template <class T> static FixedMatrix<T> & operator &= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ibitand,T,T>(a0,a1); }
414 template <class T> static FixedMatrix<T> & operator &= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ibitand,T,T>(a0,v1); }
415 
416 // PyObject* PyNumber_InPlaceXor( PyObject *o1, PyObject *o2)
417 template <class T> static FixedMatrix<T> & operator ^= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ixor,T,T>(a0,a1); }
418 template <class T> static FixedMatrix<T> & operator ^= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ixor,T,T>(a0,v1); }
419 
420 // PyObject* PyNumber_InPlaceOr( PyObject *o1, PyObject *o2)
421 template <class T> static FixedMatrix<T> & operator |= (FixedMatrix<T> &a0, const FixedMatrix<T> &a1) { return apply_matrix_matrix_ibinary_op<op_ibitor,T,T>(a0,a1); }
422 template <class T> static FixedMatrix<T> & operator |= (FixedMatrix<T> &a0, const T &v1) { return apply_matrix_scalar_ibinary_op<op_ibitor,T,T>(a0,v1); }
423 
424 template <class T>
425 static void add_arithmetic_math_functions(hboost::python::class_<FixedMatrix<T> > &c) {
426  using namespace hboost::python;
427  c
428  .def("__add__",&apply_matrix_matrix_binary_op<op_add,T,T,T>)
429  .def("__add__",&apply_matrix_scalar_binary_op<op_add,T,T,T>)
430  .def("__radd__",&apply_matrix_scalar_binary_rop<op_add,T,T,T>)
431  .def("__sub__",&apply_matrix_matrix_binary_op<op_sub,T,T,T>)
432  .def("__sub__",&apply_matrix_scalar_binary_op<op_sub,T,T,T>)
433  .def("__rsub__",&apply_matrix_scalar_binary_op<op_rsub,T,T,T>)
434  .def("__mul__",&apply_matrix_matrix_binary_op<op_mul,T,T,T>)
435  .def("__mul__",&apply_matrix_scalar_binary_op<op_mul,T,T,T>)
436  .def("__rmul__",&apply_matrix_scalar_binary_rop<op_mul,T,T,T>)
437  .def("__div__",&apply_matrix_matrix_binary_op<op_div,T,T,T>)
438  .def("__div__",&apply_matrix_scalar_binary_op<op_div,T,T,T>)
439  .def("__truediv__",&apply_matrix_matrix_binary_op<op_div,T,T,T>)
440  .def("__truediv__",&apply_matrix_scalar_binary_op<op_div,T,T,T>)
441  .def("__neg__",&apply_matrix_unary_op<op_neg,T,T>)
442  .def("__iadd__",&apply_matrix_matrix_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
443  .def("__iadd__",&apply_matrix_scalar_ibinary_op<op_iadd,T,T>,return_internal_reference<>())
444  .def("__isub__",&apply_matrix_matrix_ibinary_op<op_isub,T,T>,return_internal_reference<>())
445  .def("__isub__",&apply_matrix_scalar_ibinary_op<op_isub,T,T>,return_internal_reference<>())
446  .def("__imul__",&apply_matrix_matrix_ibinary_op<op_imul,T,T>,return_internal_reference<>())
447  .def("__imul__",&apply_matrix_scalar_ibinary_op<op_imul,T,T>,return_internal_reference<>())
448  .def("__idiv__",&apply_matrix_matrix_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
449  .def("__idiv__",&apply_matrix_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
450  .def("__itruediv__",&apply_matrix_matrix_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
451  .def("__itruediv__",&apply_matrix_scalar_ibinary_op<op_idiv,T,T>,return_internal_reference<>())
452  ;
453 }
454 
455 template <class T>
456 static void add_pow_math_functions(hboost::python::class_<FixedMatrix<T> > &c) {
457  using namespace hboost::python;
458  c
459  .def("__pow__",&pow_matrix_scalar<T>)
460  .def("__pow__",&pow_matrix_matrix<T>)
461  .def("__ipow__",&ipow_matrix_scalar<T>,return_internal_reference<>())
462  .def("__ipow__",&ipow_matrix_matrix<T>,return_internal_reference<>())
463  ;
464 }
465 
466 template <class T>
467 static void add_mod_math_functions(hboost::python::class_<FixedMatrix<T> > &c) {
468  using namespace hboost::python;
469  c
470  .def(self % self) // NOSONAR - suppress SonarCloud bug report.
471  .def(self % other<T>())
472  .def(self %= self) // NOSONAR - suppress SonarCloud bug report.
473  .def(self %= other<T>())
474  ;
475 }
476 
477 template <class T>
478 static void add_shift_math_functions(hboost::python::class_<FixedMatrix<T> > &c) {
479  using namespace hboost::python;
480  c
481  .def(self << self) // NOSONAR - suppress SonarCloud bug report.
482  .def(self << other<T>())
483  .def(self <<= self) // NOSONAR - suppress SonarCloud bug report.
484  .def(self <<= other<T>())
485  .def(self >> self) // NOSONAR - suppress SonarCloud bug report.
486  .def(self >> other<T>())
487  .def(self >>= self) // NOSONAR - suppress SonarCloud bug report.
488  .def(self >>= other<T>())
489  ;
490 }
491 
492 template <class T>
493 static void add_bitwise_math_functions(hboost::python::class_<FixedMatrix<T> > &c) {
494  using namespace hboost::python;
495  c
496  .def(self & self)
497  .def(self & other<T>())
498  .def(self &= self) // NOSONAR - suppress SonarCloud bug report.
499  .def(self &= other<T>())
500  .def(self | self)
501  .def(self | other<T>())
502  .def(self |= self) // NOSONAR - suppress SonarCloud bug report.
503  .def(self |= other<T>())
504  .def(self ^ self)
505  .def(self ^ other<T>())
506  .def(self ^= self) // NOSONAR - suppress SonarCloud bug report.
507  .def(self ^= other<T>())
508  ;
509 }
510 
511 
512 }
513 
514 #endif
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
Py_ssize_t len() const
GLboolean * data
Definition: glcorearb.h:131
GLuint start
Definition: glcorearb.h:475
FixedMatrix< Ret > apply_matrix_matrix_binary_op(const FixedMatrix< T1 > &a1, const FixedMatrix< T2 > &a2)
FixedMatrix getslice(PyObject *index) const
T & element(int i, int j)
GLfloat f
Definition: glcorearb.h:1926
const T & element(int i, int j) const
FixedMatrix< Ret > apply_matrix_scalar_binary_rop(const FixedMatrix< T1 > &a1, const T2 &a2)
FixedMatrix< T1 > & apply_matrix_matrix_ibinary_op(FixedMatrix< T1 > &a1, const FixedMatrix< T2 > &a2)
GLuint GLuint end
Definition: glcorearb.h:475
void setitem_scalar(PyObject *index, const T &data)
Py_ssize_t convert_index(int index) const
GLuint const GLchar * name
Definition: glcorearb.h:786
static hboost::python::class_< FixedMatrix< T > > register_(const char *name, const char *doc)
FixedMatrix(T *ptr, int rows, int cols, int rowStride=1, int colStride=1)
const FixedMatrix & operator=(const FixedMatrix &other)
void setitem_matrix(PyObject *index, const FixedMatrix &data)
GLint j
Definition: glad.h:2733
FixedMatrix< Ret > apply_matrix_scalar_binary_op(const FixedMatrix< T1 > &a1, const T2 &a2)
void extract_slice_indices(PyObject *index, Py_ssize_t &start, Py_ssize_t &end, Py_ssize_t &step, Py_ssize_t &slicelength) const
FixedMatrix< Ret > apply_matrix_unary_op(const FixedMatrix< T1 > &a1)
FixedMatrix(const FixedMatrix &other)
GLuint index
Definition: glcorearb.h:786
void setitem_vector(PyObject *index, const FixedArray< T > &data)
GLfloat GLfloat v1
Definition: glcorearb.h:817
auto ptr(T p) -> const void *
Definition: format.h:4331
FixedMatrix(int rows, int cols)
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER IMATH_HOSTDEVICE constexpr T abs(T a) IMATH_NOEXCEPT
Definition: ImathFun.h:26
FixedArray< T > operator[](int i)
int match_dimension(const FixedMatrix< T2 > &a1) const
FixedMatrix< T1 > & apply_matrix_scalar_ibinary_op(FixedMatrix< T1 > &a1, const T2 &a2)
const FixedArray< T > * getitem(int index) const
Definition: format.h:1821