Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

""" 

compressed_jac_store 

------ 

 

Functions to deal with compressed storage matrices. 

Note: compressed here has nothing to do with data compression, 

but since the banded callbacks were already using "packed" as 

a term, compressed was used. 

""" 

 

from __future__ import (absolute_import, division, 

                        print_function, unicode_literals) 

 

import numpy as np 

 

 

def diag_data_len(N, n, ndiag): 

    return n*(N*ndiag - ((ndiag+1)*(ndiag+1) - (ndiag+1))//2) 

 

 

def get_compressed(A, n, N, ndiag, cmaj=True): 

    """ 

    Turns a dense matrix (n*N)*(n*N) into a packed storage of 

    block diagonal submatrices (column major order) followed by 

    sub diagonal data (sequential starting with diagonals closest to 

    main diagonal), followed by super diagonal data. 

 

    Parameters 

    ---------- 

    A: 2-dimensional square matrix 

    n: int 

        sub-block dimension 

    N: int 

        number of super-blocks 

    ndiag: int 

        number of sub diagonals (also implies number of 

        super diagonals) 

    cmaj: bool 

        column major ordering in diagonal blocks. 

 

    Raises 

    ------ 

    ValueError on mismatch of A.shape and n*N 

    """ 

    if A.shape != (n*N, n*N): 

        raise ValueError("Shape of A != (n*N, n*N)") 

    B = np.zeros((n*n*N + 2*diag_data_len(N, n, ndiag))) 

    idx = 0 

    for bi in range(N): 

        for imaj in range(n): 

            for imin in range(n): 

                if cmaj: 

                    B[idx] = A[bi*n+imin, bi*n+imaj] 

                else: 

                    B[idx] = A[bi*n+imaj, bi*n+imin] 

                idx += 1 

    for di in range(ndiag): 

        for bi in range(N-di-1): 

            for ci in range(n): 

                B[idx] = A[n*(bi+di+1) + ci, n*bi + ci] 

                idx += 1 

    for di in range(ndiag): 

        for bi in range(N-di-1): 

            for ci in range(n): 

                B[idx] = A[n*bi + ci, n*(bi+di+1) + ci] 

                idx += 1 

    return B