• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SCIInstitute / UncertainSCI / 6478081804

11 Oct 2023 04:38AM UTC coverage: 50.269% (-0.3%) from 50.522%
6478081804

Pull #114

github

jessdtate
try without forwarding
Pull Request #114: Deploy testing

1588 of 3159 relevant lines covered (50.27%)

4.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.42
/UncertainSCI/transformations.py
1
import numpy as np
9✔
2
from scipy import sparse as sprs
9✔
3

4

5
class AffineTransform:
9✔
6
    def __init__(self, domain=None, image=None, A=None, b=None):
9✔
7
        """
8
        Initializes a general affine map of the form
9

10
          x ---> x*A.T + b,
11

12
        where x is a (row) vector, A is an invertible matrix, and b is a
13
        vector.
14

15
        If domain and image are specified, they are each 2 x d matrices
16
        specifying box constraints on a d-dimensional hypercube.
17
        """
18

19
        if domain is not None:
9✔
20
            if image is None:
9✔
21
                raise ValueError('If domain is specified, '
×
22
                                 'image must also be specified.')
23
            else:
24
                assert domain.shape == image.shape, \
9✔
25
                       "Domain, image matrices must be of same shape"
26

27
            self.diagonal = True
9✔
28
            d = domain.shape[1]
9✔
29
            self.A = sprs.eye(d)
9✔
30

31
            a = np.zeros(d)
9✔
32
            b = np.zeros(d)
9✔
33
            for q in range(d):
9✔
34
                a[q] = (image[1, q] - image[0, q]) / \
9✔
35
                       (domain[1, q] - domain[0, q])
36
                b[q] = image[0, q] - domain[0, q]*a[q]
9✔
37

38
            self.A = sprs.diags(a, 0)
9✔
39
            self.b = b
9✔
40

41
            self.Ainv = sprs.diags(1/a, 0)
9✔
42
            self.binv = self.Ainv.dot(-self.b)
9✔
43

44
        elif (A is not None) and (b is not None):
9✔
45
            # Assume A is a numpy array
46
            assert (A.ndim == 1) or (A.shape[0] == A.shape[1]), \
9✔
47
                   ValueError("Input matrix A must be square")
48
            assert b.ndim == 1, ValueError("Input b must be a vector")
9✔
49
            assert b.size == A.shape[0], \
9✔
50
                   ValueError("Input vector b must have same dimension as A")
51

52
            if A.ndim == 1:
9✔
53
                A = np.reshape(A, [1,1])
×
54

55
            self.A, self.b = A, b
9✔
56
            self.Ainv = np.linalg.inv(A)
9✔
57
            self.binv = self.Ainv.dot(-self.b)
9✔
58
        else:
59
            raise ValueError('Domain/image or A/b must be specified')
×
60

61
    def map(self, x):
9✔
62
        if len(x.shape) < 2:
9✔
63
            # either len(x) == dim or dim == 1
64
            if len(x) == self.b.size:
×
65
                return self.A.dot(x) + self.b
×
66
            elif self.b.size == 1:
×
67
                if isinstance(self.A, sprs.spmatrix):
×
68
                    return self.A.todense()[0, 0]*x + self.b
×
69
                else:
70
                    return self.A[0, 0]*x + self.b
×
71

72
        else:
73
            return self.A.dot(x.T).T + self.b
9✔
74

75
    def mapinv(self, x):
9✔
76
        if len(x.shape) < 2:
9✔
77
            # either len(x) == dim or dim == 1
78
            if len(x) == self.binv.size:
×
79
                return self.Ainv.dot(x) + self.binv
×
80
            elif self.b.size == 1:
×
81
                if isinstance(self.A, sprs.spmatrix):
×
82
                    return self.Ainv.todense()[0, 0]*x + self.binv
×
83
                else:
84
                    return self.Ainv[0, 0]*x + self.binv
×
85

86
        else:
87
            return self.Ainv.dot(x.T).T + self.binv
9✔
88

89
    def jacobian_determinant(self):
9✔
90
        """ Returns the Jacobian determinant of the map.
91

92
        Args:
93
            None
94
        Returns:
95
            jacdet: positive float, the absolute value of the map determinant
96
        """
97

98
        if isinstance(self.A, sprs.spmatrix):
×
99
            return np.abs(np.linalg.det(self.A.todense()))
×
100
        else:
101
            return np.abs(np.linalg.det(self.A))
×
102

103
    def compose(self, other):
9✔
104
        """ Returns composition of two AffineTransform's
105

106
        Args:
107
            other: An AffineTransform instance where the domain and range are
108
              the same dimension as for self.
109
       Returns:
110
            composition: AffineTransform instance, corresponding to the map
111
              self :math:`\\circ` other
112
        """
113

114
        A1 = np.asarray(self.A.todense())
9✔
115
        A2 = np.asarray(other.A.todense())
9✔
116

117
        assert A1.shape[0] == A2.shape[0]
9✔
118

119
        return AffineTransform(A=(A1 @ A2), b=(A1 @ other.b + self.b))
9✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc