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

pymc-devs / pymc3 / 9386

pending completion
9386

Pull #3634

travis-ci

web-flow
WIP: refactoring the DifferentialEquation Op
+ full support for test_values
+ explicit input/output types
+ 2D return shape
+ optional return of sensitivities
+ gradient without helper Op
Pull Request #3634: [WIP] DifferentialEquation Op improvements

99 of 99 new or added lines in 3 files covered. (100.0%)

42609 of 80628 relevant lines covered (52.85%)

1.86 hits per line

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

59.8
/pymc3/blocking.py
1
"""
2
pymc3.blocking
3

4
Classes for working with subsets of parameters.
5
"""
6
import copy
5✔
7
import numpy as np
5✔
8
import collections
5✔
9

10
__all__ = ['ArrayOrdering', 'DictToArrayBijection', 'DictToVarBijection']
5✔
11

12
VarMap = collections.namedtuple('VarMap', 'var, slc, shp, dtyp')
5✔
13
DataMap = collections.namedtuple('DataMap', 'list_ind, slc, shp, dtype, name')
5✔
14

15

16
# TODO Classes and methods need to be fully documented.
17

18

19
class ArrayOrdering:
5✔
20
    """
21
    An ordering for an array space
22
    """
23

24
    def __init__(self, vars):
5✔
25
        self.vmap = []
5✔
26
        self.by_name = {}
5✔
27
        self.size = 0
5✔
28

29
        for var in vars:
5✔
30
            name = var.name
5✔
31
            if name is None:
5✔
32
                raise ValueError('Unnamed variable in ArrayOrdering.')
×
33
            if name in self.by_name:
5✔
34
                raise ValueError('Name of variable not unique: %s.' % name)
×
35
            if not hasattr(var, 'dshape') or not hasattr(var, 'dsize'):
5✔
36
                raise ValueError('Shape of variable not known %s' % name)
×
37

38
            slc = slice(self.size, self.size + var.dsize)
5✔
39
            varmap = VarMap(name, slc, var.dshape, var.dtype)
5✔
40
            self.vmap.append(varmap)
5✔
41
            self.by_name[name] = varmap
5✔
42
            self.size += var.dsize
5✔
43

44
    def __getitem__(self, key):
5✔
45
        return self.by_name[key]
4✔
46

47

48
class DictToArrayBijection:
5✔
49
    """
50
    A mapping between a dict space and an array space
51
    """
52

53
    def __init__(self, ordering, dpoint):
5✔
54
        self.ordering = ordering
5✔
55
        self.dpt = dpoint
5✔
56

57
        # determine smallest float dtype that will fit all data
58
        if all([x.dtyp == 'float16' for x in ordering.vmap]):
5✔
59
            self.array_dtype = 'float16'
×
60
        elif all([x.dtyp == 'float32' for x in ordering.vmap]):
5✔
61
            self.array_dtype = 'float32'
3✔
62
        else:
63
            self.array_dtype = 'float64'
5✔
64

65
    def map(self, dpt):
5✔
66
        """
67
        Maps value from dict space to array space
68

69
        Parameters
70
        ----------
71
        dpt : dict
72
        """
73
        apt = np.empty(self.ordering.size, dtype=self.array_dtype)
5✔
74
        for var, slc, _, _ in self.ordering.vmap:
5✔
75
            apt[slc] = dpt[var].ravel()
5✔
76
        return apt
5✔
77

78
    def rmap(self, apt):
5✔
79
        """
80
        Maps value from array space to dict space
81

82
        Parameters
83
        ----------
84
        apt : array
85
        """
86
        dpt = self.dpt.copy()
5✔
87

88
        for var, slc, shp, dtyp in self.ordering.vmap:
5✔
89
            dpt[var] = np.atleast_1d(apt)[slc].reshape(shp).astype(dtyp)
5✔
90

91
        return dpt
5✔
92

93
    def mapf(self, f):
5✔
94
        """
95
         function f : DictSpace -> T to ArraySpace -> T
96

97
        Parameters
98
        ----------
99

100
        f : dict -> T
101

102
        Returns
103
        -------
104
        f : array -> T
105
        """
106
        return Compose(f, self.rmap)
3✔
107

108

109
class ListArrayOrdering:
5✔
110
    """
111
    An ordering for a list to an array space. Takes also non theano.tensors.
112
    Modified from pymc3 blocking.
113

114
    Parameters
115
    ----------
116
    list_arrays : list
117
        :class:`numpy.ndarray` or :class:`theano.tensor.Tensor`
118
    intype : str
119
        defining the input type 'tensor' or 'numpy'
120
    """
121

122
    def __init__(self, list_arrays, intype='numpy'):
5✔
123
        if intype not in {'tensor', 'numpy'}:
×
124
            raise ValueError("intype not in {'tensor', 'numpy'}")
×
125
        self.vmap = []
×
126
        self.intype = intype
×
127
        self.size = 0
×
128
        for array in list_arrays:
×
129
            if self.intype == 'tensor':
×
130
                name = array.name
×
131
                array = array.tag.test_value
×
132
            else:
133
                name = 'numpy'
×
134

135
            slc = slice(self.size, self.size + array.size)
×
136
            self.vmap.append(DataMap(
×
137
                len(self.vmap), slc, array.shape, array.dtype, name))
138
            self.size += array.size
×
139

140

141
class ListToArrayBijection:
5✔
142
    """
143
    A mapping between a List of arrays and an array space
144

145
    Parameters
146
    ----------
147
    ordering : :class:`ListArrayOrdering`
148
    list_arrays : list
149
        of :class:`numpy.ndarray`
150
    """
151

152
    def __init__(self, ordering, list_arrays):
5✔
153
        self.ordering = ordering
×
154
        self.list_arrays = list_arrays
×
155

156
    def fmap(self, list_arrays):
5✔
157
        """
158
        Maps values from List space to array space
159

160
        Parameters
161
        ----------
162
        list_arrays : list
163
            of :class:`numpy.ndarray`
164

165
        Returns
166
        -------
167
        array : :class:`numpy.ndarray`
168
            single array comprising all the input arrays
169
        """
170

171
        array = np.empty(self.ordering.size)
×
172
        for list_ind, slc, _, _, _ in self.ordering.vmap:
×
173
            array[slc] = list_arrays[list_ind].ravel()
×
174
        return array
×
175

176
    def dmap(self, dpt):
5✔
177
        """
178
        Maps values from dict space to List space
179

180
        Parameters
181
        ----------
182
        list_arrays : list
183
            of :class:`numpy.ndarray`
184

185
        Returns
186
        -------
187
        point
188
        """
189
        a_list = copy.copy(self.list_arrays)
×
190

191
        for list_ind, _, _, _, var in self.ordering.vmap:
×
192
            a_list[list_ind] = dpt[var].ravel()
×
193

194
        return a_list
×
195

196
    def rmap(self, array):
5✔
197
        """
198
        Maps value from array space to List space
199
        Inverse operation of fmap.
200

201
        Parameters
202
        ----------
203
        array : :class:`numpy.ndarray`
204

205
        Returns
206
        -------
207
        a_list : list
208
            of :class:`numpy.ndarray`
209
        """
210

211
        a_list = copy.copy(self.list_arrays)
×
212

213
        for list_ind, slc, shp, dtype, _ in self.ordering.vmap:
×
214
            a_list[list_ind] = np.atleast_1d(
×
215
                                    array)[slc].reshape(shp).astype(dtype)
216

217
        return a_list
×
218

219

220
class DictToVarBijection:
5✔
221
    """
222
    A mapping between a dict space and the array space for one element within the dict space
223
    """
224

225
    def __init__(self, var, idx, dpoint):
5✔
226
        self.var = str(var)
×
227
        self.idx = idx
×
228
        self.dpt = dpoint
×
229

230
    def map(self, dpt):
5✔
231
        return dpt[self.var][self.idx]
×
232

233
    def rmap(self, apt):
5✔
234
        dpt = self.dpt.copy()
×
235

236
        dvar = dpt[self.var].copy()
×
237
        dvar[self.idx] = apt
×
238

239
        dpt[self.var] = dvar
×
240

241
        return dpt
×
242

243
    def mapf(self, f):
5✔
244
        return Compose(f, self.rmap)
×
245

246

247
class Compose:
5✔
248
    """
249
    Compose two functions in a pickleable way
250
    """
251

252
    def __init__(self, fa, fb):
5✔
253
        self.fa = fa
3✔
254
        self.fb = fb
3✔
255

256
    def __call__(self, x):
5✔
257
        return self.fa(self.fb(x))
3✔
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

© 2025 Coveralls, Inc