# sfepy.linalg.utils module

sfepy.linalg.utils.apply_to_sequence(seq, fun, ndim, out_item_shape)

  Applies function fun() to each item of the sequence seq. An item corresponds to the last ndim dimensions of seq.

  Parameters:
    seq array

      The sequence array with shape (n_1, …, n_r, m_1, …, m_{ndim}).

    fun function

      The function taking an array argument of shape of length ndim.

    ndim int

      The number of dimensions of an item in seq.

    out_item_shape tuple

      The shape an output item.

  Returns:
    out array

      The resulting array of shape (n_1, …, n_r) + out_item_shape. The out_item_shape must be compatible with the fun.

sfepy.linalg.utils.argsort_rows(seq)

  Returns an index array that sorts the sequence seq. Works along rows if seq is two-dimensional.

sfepy.linalg.utils.assemble1d(ar_out, indx, ar_in)

  Perform ar_out[indx] += ar_in, where items of ar_in corresponding to duplicate indices in indx are summed together.

sfepy.linalg.utils.chunk_arrays(arrs, chunk_size)

  Yield consecutive views into arrays arrs of the same lengths and most chunk_size long.

sfepy.linalg.utils.cycle(bounds)

  Cycles through all combinations of bounds, returns a generator.

  More specifically, let bounds=[a, b, c, …], so cycle returns all combinations of lists [0<=i<a, 0<=j<b, 0<=k<c, …] for all i,j,k,…

  Examples: In [9]: list(cycle([3, 2])) Out[9]: [[0, 0], [0, 1], [1, 0], [1, 1], [2, 0], [2, 1]]

  In [14]: list(cycle([3, 4])) [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3]]

sfepy.linalg.utils.dets_fast(a)

  Fast determinant calculation of 3-dimensional array.

  Parameters:
    a array

      The input array with shape (m, n, n).

  Returns:
    out array

      The output array with shape (m,): out[i] = det(a[i, :, :]).

sfepy.linalg.utils.dot_sequences(mtx, vec, mode='AB')

  Computes dot product for each pair of items in the two sequences.

  Equivalent to

      >>> out = nm.empty((vec.shape[0], mtx.shape[1], vec.shape[2]),
      >>>                dtype=vec.dtype)
      >>> for ir in range(mtx.shape[0]):
      >>>     out[ir] = nm.dot(mtx[ir], vec[ir])

  Parameters:
    mtx array

      The array of matrices with shape (n_item, m, n).

    vec array

      The array of vectors with shape (n_item, a) or matrices with shape (n_item, a, b).

    mode one of ‘AB’, ‘ATB’, ‘ABT’, ‘ATBT’

      The mode of the dot product - the corresponding axes are dotted together:

      ‘AB’ : a = n ‘ATB’ : a = m ‘ABT’ : b = n (*) ‘ATBT’ : b = m (*)

      (*) The ‘BT’ part is ignored for the vector second argument.

  Returns:
    out array

      The resulting array.

  Notes

  Uses numpy.matmul() via the @ operator.

sfepy.linalg.utils.get_blocks_stats(blocks, *args)

  Return statistics of array/matrix blocks defined by indices in args.

  Returns:
    stats: structured array

      The array with ‘shape’, ‘min’, ‘mean’ and ‘max’ fields at positions of each matrix block.

  Examples

      >>> import numpy as nm
      >>> from sfepy.linalg.utils import get_blocks_stats
      >>>
      >>> A = nm.eye(3)
      >>> B = nm.full((3,2), 2)
      >>> C = nm.full((1,3), 3)
      >>> D = nm.full((1,2), 4)
      >>> M = nm.block([[A, B], [C, D]])
      >>>
      >>> sr = [slice(0, 3), slice(3, 5)]
      >>> sc = [slice(0, 3), slice(3, 4)]
      >>> stats = get_blocks_stats(M, sr, sc)
      >>>
      >>> print(stats['shape'])
      [[(3, 3) (3, 1)]
       [(1, 3) (1, 1)]]
      >>>
      >>> print(stats['min'])
      [[0. 2.]
       [3. 4.]]

sfepy.linalg.utils.insert_strided_axis(ar, axis, length)

  Insert a new axis of given length into an array using numpy stride tricks, i.e. no copy is made.

  Parameters:
    ar array

      The input array.

    axis int

      The axis before which the new axis will be inserted.

    length int

      The length of the inserted axis.

  Returns:
    out array

      The output array sharing data with ar.

  Examples

      >>> import numpy as nm
      >>> from sfepy.linalg import insert_strided_axis
      >>> ar = nm.random.rand(2, 1, 2)
      >>> ar
      array([[[ 0.18905119,  0.44552425]],

  > [[ 0.78593989, 0.71852473]]])

      >>> ar.shape
      (2, 1, 2)
      >>> ar2 = insert_strided_axis(ar, 1, 3)
      >>> ar2
      array([[[[ 0.18905119,  0.44552425]],

  > > [[ 0.18905119, 0.44552425]],

  > > [[ 0.18905119, 0.44552425]]],

  > [[[ 0.78593989, 0.71852473]],

  > > [[ 0.78593989, 0.71852473]],

  > > [[ 0.78593989, 0.71852473]]]])

      >>> ar2.shape
      (2, 3, 1, 2)

sfepy.linalg.utils.invs_fast(a, det=None)

  Fast inversion calculation of 4-dimensional array.

  Parameters:
    a array

      The input array with shape (c, q, n, n).

    det: array

      To speed up the calculation, enter the already calculated determinant.

  Returns:
    out array

      The output array with shape (c, q, n, n): out[c, q] = inv(a[c, q, :, :]).

sfepy.linalg.utils.map_permutations(seq1, seq2, check_same_items=False)

  Returns an index array imap such that seq1[imap] == seq2, if both sequences have the same items - this is not checked by default!

  In other words, finds the indices of items of seq2 in seq1.

sfepy.linalg.utils.max_diff_csr(mtx1, mtx2)

sfepy.linalg.utils.mini_newton(fun, x0, dfun, i_max=100, eps=1e-08)

sfepy.linalg.utils.norm_l2_along_axis(ar, axis=1, n_item=None, squared=False)

  Compute l2 norm of rows (axis=1) or columns (axis=0) of a 2D array.

  n_item … use only the first n_item columns/rows squared … if True, return the norm squared

sfepy.linalg.utils.normalize_vectors(vecs, eps=1e-08)

  Normalize an array of vectors in place.

  Parameters:
    vecs array

      The 2D array of vectors in rows.

    eps float

      The tolerance for considering a vector to have zero norm. Such vectors are left unchanged.

sfepy.linalg.utils.output_array_stats(ar, name, verbose=True)

sfepy.linalg.utils.print_array_info(ar)

  Print array shape and other basic information.

sfepy.linalg.utils.unique_rows(ar, return_index=False, return_inverse=False)

  Return unique rows of a two-dimensional array ar. The arguments follow numpy.unique().