amino  1.0-beta2
Lightweight Robot Utility Library
mat.py
Go to the documentation of this file.
1 # Copyright (c) 2019, Colorado School of Mines
2 # All rights reserved.
3 #
4 # Author(s): Neil T. Dantam <ndantam@mines.edu>
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 #
13 # * Redistributions in binary form must reproduce the above
14 # copyright notice, this list of conditions and the following
15 # disclaimer in the documentation and/or other materials provided
16 # with the distribution.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
23 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
25 # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
28 # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29 # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 # SUCH DAMAGE.
31 
32 
35 """Vectors and Matrices"""
36 
37 import ctypes
38 
39 from amino.lib import libamino
40 from amino.mixin import VecMixin, SSDEqMixin, DivCompatMixin, MatMixin
41 from amino.util import ensure, is_int, is_scalar
42 
43 CBLAS_NO_TRANS = 111
44 CBLAS_TRANS = 112
45 CBLAS_CONJ_TRANS = 113
46 
47 
48 class DVec(ctypes.Structure, VecMixin):
49  """Vector of double floats."""
50  _fields_ = [("_size", ctypes.c_size_t),
51  ("_data", ctypes.POINTER(ctypes.c_double)),
52  ("_inc", ctypes.c_size_t)]
53 
54  @staticmethod
55  def _alloc(size):
56  return (ctypes.c_double * size)()
57 
58  def __init__(self, arg=None):
59  """Constructs a vector.
60 
61  If arg is None -- Create an unitialized DVec
62  If arg is a list -- Fill the DVec with list contents
63  If arg is an int -- Create a DVec of that size
64  """
65  if arg is None:
66  super(DVec, self).__init__(0, None, 0)
67  elif is_int(arg):
68  super(DVec, self).__init__(arg, DVec._alloc(arg), 1)
69  else:
70  s = len(arg)
71  super(DVec, self).__init__(s, DVec._alloc(s), 1)
72  self.copy_fromcopy_fromcopy_from(arg)
73 
74  @staticmethod
75  def ensure(thing):
76  """If thing is not a DVec, construct a DVec containging thing.
77 
78  Returns:
79  thing if already a DVec, other a newly-constructed DVec.
80  """
81  return ensure(thing, DVec)
82 
83  def copy_from(self, src):
84  """Copies the contents of thing into self"""
85  ls = len(self)
86  if ls != len(src):
87  raise IndexError()
88  elif isinstance(src, DVec):
89  libamino.aa_dvec_copy(src, self)
90  else:
91  super(DVec, self).copy_from(src)
92  return src
93 
94  def copy_to(self, dst):
95  """Copies self to thing."""
96  ls = len(self)
97  if ls != len(dst):
98  raise IndexError()
99  elif isinstance(dst, DVec):
100  libamino.aa_dvec_copy(self, dst)
101  else:
102  super(DVec, self).copy_to(dst)
103  return dst
104 
105  def axpy(self, alpha, x):
106  """self = alpha*x, where alpha is a scalar and x is a DVec"""
107  libamino.aa_dvec_axpy(alpha, x, self)
108  return self
109 
110  def zero(self):
111  """Fills self with zeros"""
112  libamino.aa_dvec_zero(self)
113  return self
114 
115  def set(self, alpha):
116  """Sets all elements of self to scalar alpha"""
117  libamino.aa_dvec_set(self, alpha)
118  return self
119 
120  def increment(self, alpha):
121  """self = self + alpha, for scalar alpha"""
122  libamino.aa_dvec_inc(alpha, self)
123  return self
124 
125  def gemv(self, trans, alpha, A, x, beta):
126  """General matrix-vector multiply.
127 
128  self = alpha*A*x + beta*self
129 
130  alpha -- a scalar
131  A -- a matrix
132  x -- a vector
133  beta -- a scalar
134  """
135  if A.rows != len(self):
136  raise IndexError()
137  if A.cols != len(x):
138  raise IndexError()
139  libamino.aa_dmat_gemv(trans, alpha, A, x, beta, self)
140  return self
141 
142  def ssd(self, other):
143  """Sum of square differences"""
144  return libamino.aa_dvec_ssd(self, DVec.ensure(other))
145 
146  def nrm2(self):
147  """Euclidean norm of self"""
148  return libamino.aa_dvec_nrm2(self)
149 
150  def __getitem__(self, key):
151  """Returns an item or slice of self"""
152  if isinstance(key, slice):
153  step = 1 if key.step is None else key.step
154  start = 0 if key.start is None else key.start
155  stop = self._size if key.stop is None else key.stop
156  x = DVec()
157  libamino.aa_dvec_slice(self, start, stop, step, x)
158  return x
159  elif key >= 0 and key < len(self):
160  return self._data[key * self._inc]
161  else:
162  raise IndexError(key)
163 
164  def __setitem__(self, key, item):
165  """Set an item of self"""
166  if key >= 0 and key < len(self):
167  self._data[key * self._inc] = item
168  else:
169  raise IndexError(key)
170 
171  def __len__(self):
172  """Number of elements in self"""
173  return self._size
174 
175  @property
176  def inc(self):
177  """Increment between elements."""
178  return self._inc
179 
180  def __iadd__(self, other):
181  """Add a scalar or vector to self"""
182  if isinstance(other, DVec):
183  return self.axpyaxpy(1, other)
184  if isinstance(other, list):
185  return self.axpyaxpy(1, DVec(other))
186  if is_scalar(other):
187  return self.incrementincrement(other)
188  raise Exception('Invalid argument')
189 
190  def __add__(self, other):
191  """Add a scalar or vector to self"""
192  return DVec(self).__iadd__(other)
193 
194  def __radd__(self, other):
195  """Add a scalar or vector to self"""
196  return DVec(self).__iadd__(other)
197 
198  def __isub(self, other):
199  """Subtract a scalar or vector from self"""
200  if isinstance(other, DVec):
201  return self.axpyaxpy(-1, other)
202  if isinstance(other, list):
203  return self.axpyaxpy(-1, DVec(other))
204  if is_scalar(other):
205  return self.incrementincrement(-other)
206  raise Exception('Invalid argument')
207 
208  def __sub__(self, other):
209  """Subtract a scalar or vector from self"""
210  if isinstance(other, DVec):
211  return DVec(self).axpy(-1, other)
212  if isinstance(other, list):
213  return self.__sub____sub__(DVec(other))
214  if is_scalar(other):
215  return DVec(self).increment(-other)
216  raise Exception('Invalid argument')
217 
218  def __rsub__(self, other):
219  """Subtract a self from a scalar or vector"""
220  if is_scalar(other):
221  return self.__neg____neg__().increment(other)
222  if isinstance(other, list):
223  return DVec(other).axpy(-1, self)
224  raise Exception('Invalid argument')
225 
226  def __imul__(self, other):
227  """Multiply self by a scalar"""
228  libamino.aa_dvec_scal(other, self)
229  return self
230 
231  def __neg__(self):
232  """Negate self"""
233  return DVec(self).__imul__(-1)
234 
235  def __mul__(self, other):
236  """Multiply self by a scalar"""
237  return DVec(self).__imul__(other)
238 
239  def __rmul__(self, other):
240  """Multiply self by a scalar"""
241  return DVec(self).__imul__(other)
242 
243  def __itruediv__(self, other):
244  """Divide self by a scalar"""
245  return self.__imul____imul__(1.0 / other)
246 
247  def __truediv__(self, other):
248  """Divide self by a scalar"""
249  return DVec(self).__itruediv__(other)
250 
251  def __str__(self):
252  s = "DVec(["
253  i = 0
254  n = len(self)
255  while i < n - 1:
256  s += "%f, " % self._data[self._inc * i]
257  i = i + 1
258  if i < n:
259  s += "%f" % self._data[self._inc * i]
260  s += "])"
261  return s
262 
263 
264 class DMat(ctypes.Structure, SSDEqMixin, DivCompatMixin, MatMixin):
265  """Matrix of double floats."""
266  _fields_ = [("_rows", ctypes.c_size_t), ("_cols", ctypes.c_size_t),
267  ("_data", ctypes.POINTER(ctypes.c_double)),
268  ("_ld", ctypes.c_size_t)]
269 
270  @staticmethod
271  def _alloc(rows, cols):
272  return (ctypes.c_double * (rows * cols))()
273 
274  def __init__(self, arg=None):
275  """Constructs a matrix."""
276  if arg is None:
277  super(DMat, self).__init__(0, 0, None, 0)
278  elif isinstance(arg, tuple):
279  rows, cols = arg
280  data = DMat._alloc(rows, cols)
281  super(DMat, self).__init__(rows, cols, data, rows)
282  elif isinstance(arg, DMat):
283  rows = arg.rows
284  cols = arg.cols
285  data = DMat._alloc(arg.rows, arg.cols)
286  super(DMat, self).__init__(rows, cols, data, rows)
287  self.copy_fromcopy_from(arg)
288  else:
289  raise Exception('Invalid argument')
290 
291  def copy_from(self, src):
292  """Copies elements from src into self"""
293  if self._rows != src._rows or self._cols != src._cols:
294  raise IndexError()
295  if isinstance(src, DMat):
296  libamino.aa_dmat_copy(src, self)
297 
298  @property
299  def rows(self):
300  """Number of rows."""
301  return self._rows
302 
303  @property
304  def cols(self):
305  """Number of columns."""
306  return self._cols
307 
308  @property
309  def ld(self):
310  """Leading dimension of data."""
311  return self._ld
312 
313  @property
314  def data(self):
315  """Pointer to data."""
316  return self._data
317 
318  def __len__(self):
319  return self._rows * self._cols
320 
321  def row_vec(self, i):
322  """Returns the i'th row as a DVec."""
323  self._check_row_check_row(i)
324  v = DVec()
325  libamino.aa_dmat_row_vec(self, i, v)
326  return v
327 
328  def col_vec(self, j):
329  """Returns the j'th column as a DVec."""
330  self._check_col_check_col(j)
331  v = DVec()
332  libamino.aa_dmat_col_vec(self, j, v)
333  return v
334 
335  def diag_vec(self):
336  """Returns the diagonal as a DVec."""
337  v = DVec()
338  libamino.aa_dmat_diag_vec(self, v)
339  return v
340 
341  def transpose(self):
342  """Returns the tranpose of the matrix"""
343  At = DMat((self._cols, self._rows))
344  libamino.aa_dmat_trans(self, At)
345  return At
346 
347  @staticmethod
348  def row_matrix(args):
349  """Creates a matrix from rows passed in args."""
350  m = len(args)
351  n = len(args[0]) if m > 0 else 0
352  A = DMat((m, n))
353  for i in range(0, m):
354  A.row_vec(i).copy_from(args[i])
355  return A
356 
357  @staticmethod
358  def col_matrix(args):
359  """Creates a matrix from columns passed in args."""
360  n = len(args)
361  m = len(args[0]) if n > 0 else 0
362  A = DMat((m, n))
363  for j in range(0, n):
364  A.col_vec(j).copy_from(args[j])
365  return A
366 
367  def ssd(self, other):
368  """Returns Sum of square differences."""
369  return libamino.aa_dmat_ssd(self, other)
370 
371  def nrm2(self):
372  """Returns the Euclidean norm of self"""
373  return libamino.aa_dmat_nrm2(self)
374 
375  def gemm(self, transA, transB, alpha, A, B, beta):
376  """General matrix-matrix multiply.
377 
378  Thin wrapper of BLAS dgemm().
379 
380  self := alpha*op(A)*op(B) + beta*self
381 
382  Args:
383  transA: whether to transpose A
384  transB: whether to transpose B
385  alpha: scale factor for A and B
386  beta: scale factor for self
387  """
388  C = self
389  if (A.rows != C.rows or A.cols != B.rows or B.cols != C.cols):
390  raise IndexError()
391  libamino.aa_dmat_gemm(transA, transB, alpha, A, B, beta, C)
392  return C
393 
394  def pinv(self, tol=-1):
395  """Returns the pseudoinverse.
396 
397  Args:
398  tol: singular values less than tol are ignored. Negative values use a default.
399  """
400  M = DMat((self._cols, self._rows))
401  libamino.aa_dmat_pinv(self, tol, M)
402  return M
403 
404  def inv(self):
405  """Returns the inverse."""
406  M = DMat(self)
407  libamino.aa_dmat_inv(M)
408  return M
409 
410  def _check_row(self, i):
411  if (i < 0 or i >= self._rows):
412  raise IndexError(i)
413 
414  def _check_col(self, j):
415  if (j < 0 or j >= self._cols):
416  raise IndexError(j)
417 
418  def _check_index(self, i, j):
419  self._check_row_check_row(i)
420  self._check_col_check_col(j)
421 
422  #def block(self, row_start, col_start, row_end, col_end):
423 
424  def __getitem__(self, key):
425  i, j = key
426  if isinstance(i, slice) and isinstance(j, slice):
427  if not ((i.step is None) or i.step == 0):
428  raise IndexError()
429  if not ((j.step is None) or j.step == 0):
430  raise IndexError()
431  M = DMat()
432  libamino.aa_dmat_block(self, i.start, j.start, i.stop, j.stop, M)
433  return M
434  else:
435  self._check_index_check_index(i, j)
436  return self._data[i + j * self._ld]
437 
438  def __setitem__(self, key, item):
439  i, j = key
440  self._check_index_check_index(i, j)
441  self._data[i + j * self._ld] = item
442 
443  def __imul__(self, other):
444  if is_scalar(other):
445  libamino.aa_dmat_scal(self, other)
446  return self
447  else:
448  raise TypeError('Cannot cale matrix with %s' % type(other))
449 
450  def __neg__(self):
451  """Negate self"""
452  return DMat(self).__imul__(-1)
453 
454  def __mul__(self, other):
455  if is_scalar(other):
456  return DMat(self).__imul__(other)
457  elif isinstance(other, DVec):
458  y = DVec(self._rows)
459  y.gemv(CBLAS_NO_TRANS, 1, self, other, 0)
460  return y
461  elif isinstance(other, list):
462  return self * DVec(other)
463  elif isinstance(other, DMat):
464  A, B = self, other
465  C = DMat((A._rows, B._cols))
466  return C.gemm(CBLAS_NO_TRANS, CBLAS_NO_TRANS, 1, A, B, 1)
467  else:
468  raise TypeError('Cannot multiply matrix with %s' % type(other))
469 
470  def __rmul__(self, other):
471  if is_scalar(other):
472  return DMat(self).__imul__(other)
473  raise TypeError('Cannot multiply matrix with %s' % type(other))
474 
475  def __itruediv__(self, other):
476  """Divide self by a scalar"""
477  return self.__imul____imul__(1.0 / other)
478 
479  def __truediv__(self, other):
480  """Divide self by a scalar"""
481  return DMat(self).__itruediv__(other)
482 
483  def __iadd__(self, other):
484  if is_scalar(other):
485  libamino.aa_dmat_inc(self, other)
486  return self
487  if isinstance(other, DMat):
488  libamino.aa_dmat_axpy(1, other, self)
489  return self
490  raise TypeError('Cannot increment matrix with %s' % type(other))
491 
492  def __add__(self, other):
493  if is_scalar(other) or isinstance(other, DMat):
494  return DMat(self).__iadd__(other)
495  raise TypeError('Cannot add matrix add %s' % type(other))
496 
497  def __radd__(self, other):
498  if is_scalar(other):
499  return DMat(self).__iadd__(other)
500  raise TypeError('Cannot add matrix add %s' % type(other))
501 
502  def __isub__(self, other):
503  if is_scalar(other):
504  libamino.aa_dmat_inc(self, -other)
505  return self
506  if isinstance(other, DMat):
507  libamino.aa_dmat_axpy(-1, other, self)
508  return self
509  raise TypeError('Cannot increment matrix with %s' % type(other))
510 
511  def __sub__(self, other):
512  if is_scalar(other) or isinstance(other, DMat):
513  return DMat(self).__isub__(other)
514  raise TypeError('Cannot subtract matrix with %s' % type(other))
515 
516  def __rsub__(self, other):
517  if is_scalar(other):
518  return self.__neg____neg__().__iadd__(other)
519  raise TypeError('Cannot subtract matrix with %s' % type(other))
520 
521  def __str__(self):
522  return self._str_helper_str_helper("TfMat.row_matrix")
523 
524 
525 #---------------#
526 # LIBRARY CALLS #
527 #---------------#
528 
529 
530 libamino.aa_dvec_axpy.argtypes = [
531  ctypes.c_double,
532  ctypes.POINTER(DVec),
533  ctypes.POINTER(DVec)
534 ]
535 libamino.aa_dvec_copy.argtypes = [ctypes.POINTER(DVec), ctypes.POINTER(DVec)]
536 libamino.aa_dvec_scal.argtypes = [ctypes.c_double, ctypes.POINTER(DVec)]
537 libamino.aa_dvec_inc.argtypes = [ctypes.c_double, ctypes.POINTER(DVec)]
538 
539 libamino.aa_dvec_dot.argtypes = [ctypes.POINTER(DVec), ctypes.POINTER(DVec)]
540 libamino.aa_dvec_dot.restype = ctypes.c_double
541 
542 libamino.aa_dvec_nrm2.argtypes = [ctypes.POINTER(DVec)]
543 libamino.aa_dvec_nrm2.restype = ctypes.c_double
544 
545 libamino.aa_dvec_set.argtypes = [ctypes.POINTER(DVec), ctypes.c_double]
546 
547 libamino.aa_dvec_zero.argtypes = [ctypes.POINTER(DVec)]
548 
549 libamino.aa_dvec_slice.argtypes = [
550  ctypes.POINTER(DVec), ctypes.c_size_t, ctypes.c_size_t, ctypes.c_size_t,
551  ctypes.POINTER(DVec)
552 ]
553 
554 libamino.aa_dvec_ssd.argtypes = [ctypes.POINTER(DVec), ctypes.POINTER(DVec)]
555 libamino.aa_dvec_ssd.restype = ctypes.c_double
556 
557 # Blas 2
558 libamino.aa_dmat_row_vec.argtypes = [
559  ctypes.POINTER(DMat), ctypes.c_size_t,
560  ctypes.POINTER(DVec)
561 ]
562 libamino.aa_dmat_col_vec.argtypes = [
563  ctypes.POINTER(DMat), ctypes.c_size_t,
564  ctypes.POINTER(DVec)
565 ]
566 libamino.aa_dmat_diag_vec.argtypes = [
567  ctypes.POINTER(DMat), ctypes.POINTER(DVec)
568 ]
569 
570 libamino.aa_dmat_block.argtypes = [
571  ctypes.POINTER(DMat), ctypes.c_size_t, ctypes.c_size_t, ctypes.c_size_t,
572  ctypes.c_size_t,
573  ctypes.POINTER(DMat)
574 ]
575 
576 libamino.aa_dmat_gemv.argtypes = [
577  ctypes.c_int, ctypes.c_double,
578  ctypes.POINTER(DMat),
579  ctypes.POINTER(DVec), ctypes.c_double,
580  ctypes.POINTER(DVec)
581 ]
582 
583 # Blas 3
584 libamino.aa_dmat_gemm.argtypes = [
585  ctypes.c_int, ctypes.c_int, ctypes.c_double,
586  ctypes.POINTER(DMat),
587  ctypes.POINTER(DMat), ctypes.c_double,
588  ctypes.POINTER(DMat)
589 ]
590 
591 # Matrix functions
592 libamino.aa_dmat_ssd.argtypes = [ctypes.POINTER(DMat), ctypes.POINTER(DMat)]
593 libamino.aa_dmat_ssd.restype = ctypes.c_double
594 
595 libamino.aa_dmat_scal.argtypes = [ctypes.POINTER(DMat), ctypes.c_double]
596 libamino.aa_dmat_inc.argtypes = [ctypes.POINTER(DMat), ctypes.c_double]
597 libamino.aa_dmat_axpy.argtypes = [
598  ctypes.c_double,
599  ctypes.POINTER(DMat),
600  ctypes.POINTER(DMat)
601 ]
602 
603 libamino.aa_dmat_nrm2.argtypes = [ctypes.POINTER(DMat)]
604 libamino.aa_dmat_nrm2.restype = ctypes.c_double
605 
606 libamino.aa_dmat_trans.argtypes = [ctypes.POINTER(DMat), ctypes.POINTER(DMat)]
607 
608 libamino.aa_dmat_pinv.argtypes = [
609  ctypes.POINTER(DMat), ctypes.c_double,
610  ctypes.POINTER(DMat)
611 ]
612 libamino.aa_dmat_inv.argtypes = [ctypes.POINTER(DMat)]
613 
614 libamino.aa_dmat_copy.argtypes = [ctypes.POINTER(DMat), ctypes.POINTER(DMat)]
Matrix of double floats.
Definition: mat.py:272
def row_matrix(args)
Creates a matrix from rows passed in args.
Definition: mat.py:359
def _check_row(self, i)
Definition: mat.py:420
def rows(self)
Number of rows.
Definition: mat.py:310
def __init__(self, arg=None)
Constructs a matrix.
Definition: mat.py:285
def data(self)
Pointer to data.
Definition: mat.py:325
def _check_col(self, j)
Definition: mat.py:424
def __imul__(self, other)
Definition: mat.py:453
def transpose(self)
Returns the tranpose of the matrix.
Definition: mat.py:352
def inv(self)
Returns the inverse.
Definition: mat.py:415
def ssd(self, other)
Returns Sum of square differences.
Definition: mat.py:378
def pinv(self, tol=-1)
Returns the pseudoinverse.
Definition: mat.py:409
def ld(self)
Leading dimension of data.
Definition: mat.py:320
def col_matrix(args)
Creates a matrix from columns passed in args.
Definition: mat.py:369
def gemm(self, transA, transB, alpha, A, B, beta)
General matrix-matrix multiply.
Definition: mat.py:397
def diag_vec(self)
Returns the diagonal as a DVec.
Definition: mat.py:346
def __itruediv__(self, other)
Divide self by a scala.
Definition: mat.py:486
def cols(self)
Number of columns.
Definition: mat.py:315
def __truediv__(self, other)
Divide self by a scala.
Definition: mat.py:490
def col_vec(self, j)
Returns the j'th column as a DVec.
Definition: mat.py:339
def row_vec(self, i)
Returns the i'th row as a DVec.
Definition: mat.py:332
def copy_from(self, src)
Copies elements from src into self.
Definition: mat.py:302
def _check_index(self, i, j)
Definition: mat.py:428
def nrm2(self)
Returns the Euclidean norm of self.
Definition: mat.py:382
def __neg__(self)
Negate self.
Definition: mat.py:461
Vector of double floats.
Definition: mat.py:49
def set(self, alpha)
Sets all elements of self to scalar alpha.
Definition: mat.py:119
def __rsub__(self, other)
Subtract a self from a scalar or vecto.
Definition: mat.py:226
def __rmul__(self, other)
Multiply self by a scala.
Definition: mat.py:247
def __iadd__(self, other)
Add a scalar or vector to self.
Definition: mat.py:186
def nrm2(self)
Euclidean norm of self.
Definition: mat.py:152
def zero(self)
Fills self with zeros.
Definition: mat.py:114
def __init__(self, arg=None)
Constructs a vector.
Definition: mat.py:67
def __radd__(self, other)
Add a scalar or vector to self.
Definition: mat.py:200
def gemv(self, trans, alpha, A, x, beta)
General matrix-vector multiply.
Definition: mat.py:139
def __sub__(self, other)
Subtract a scalar or vector from self.
Definition: mat.py:216
def __imul__(self, other)
Multiply self by a scala.
Definition: mat.py:234
def __len__(self)
Number of elements in self.
Definition: mat.py:177
def axpy(self, alpha, x)
self = alpha*x, where alpha is a scalar and x is a DVec
Definition: mat.py:109
def ensure(thing)
If thing is not a DVec, construct a DVec containging thing.
Definition: mat.py:83
def copy_from(self, src)
Copies the contents of thing into self.
Definition: mat.py:87
def __itruediv__(self, other)
Divide self by a scala.
Definition: mat.py:251
def __setitem__(self, key, item)
Set an item of self.
Definition: mat.py:170
def increment(self, alpha)
self = self + alpha, for scalar alpha
Definition: mat.py:124
def __add__(self, other)
Add a scalar or vector to self.
Definition: mat.py:196
def copy_to(self, dst)
Copies self to thing.
Definition: mat.py:98
def __neg__(self)
Negate self.
Definition: mat.py:239
def __getitem__(self, key)
Returns an item or slice of self.
Definition: mat.py:156
def inc(self)
Increment between elements.
Definition: mat.py:182
def __mul__(self, other)
Multiply self by a scala.
Definition: mat.py:243
def __truediv__(self, other)
Divide self by a scala.
Definition: mat.py:255
def ssd(self, other)
Sum of square differences.
Definition: mat.py:148
def copy_from(self, src)
Copy elements from src to self.
Definition: mixin.py:59
Mixin for compatibility division operator.
Definition: mixin.py:78
Mixin for matrix-like objects.
Definition: mixin.py:95
def _str_helper(self, name, m=None, n=None)
Definition: mixin.py:96
Helper mixins.
Definition: mixin.py:37
Definition: lib.py:1