This file is indexed.

/usr/lib/python2.7/dist-packages/pymc/InstantiationDecorators.py is in python-pymc 2.2+ds-1.1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
"""
The decorators stochastic, deterministic, discrete_stochastic, binary_stochastic, potential and data
are defined here, but the actual objects are defined in PyMCObjects.py
"""

__all__ = ['stochastic', 'stoch', 'deterministic', 'dtrm', 'potential', 'pot', 'data', 'observed', 'robust_init','disable_special_methods','enable_special_methods','check_special_methods']

import sys, inspect, pdb
from imp import load_dynamic
from .PyMCObjects import Stochastic, Deterministic, Potential
from .Node import ZeroProbability, ContainerBase, Node, StochasticMeta
from .Container import Container
import numpy as np

special_methods_available = [True]
def disable_special_methods(sma=special_methods_available):
    sma[0]=False
def enable_special_methods(sma=special_methods_available):
    sma[0]=True
def check_special_methods(sma=special_methods_available):
    return sma[0]

from . import six

def _extract(__func__, kwds, keys, classname, probe=True):
    """
    Used by decorators stochastic and deterministic to inspect declarations
    """

    # Add docs and name
    kwds['doc'] = __func__.__doc__
    if not 'name' in kwds:
        kwds['name'] = __func__.__name__
    # kwds.update({'doc':__func__.__doc__, 'name':__func__.__name__})

    # Instanitate dictionary of parents
    parents = {}

    # This gets used by stochastic to check for long-format logp and random:
    if probe:
        cur_status = check_special_methods()
        disable_special_methods()
        # Define global tracing function (I assume this is for debugging??)
        # No, it's to get out the logp and random functions, if they're in there.
        def probeFunc(frame, event, arg):
            if event == 'return':
                locals = frame.f_locals
                kwds.update(dict((k,locals.get(k)) for k in keys))
                sys.settrace(None)
            return probeFunc

        sys.settrace(probeFunc)

        # Get the functions logp and random (complete interface).
        # Disable special methods to prevent the formation of a hurricane of Deterministics
        try:
            __func__()
        except:
            if 'logp' in keys:
                kwds['logp']=__func__
            else:
                kwds['eval'] =__func__
        # Reenable special methods.
        if cur_status:
            enable_special_methods()

    for key in keys:
        if not key in kwds:
            kwds[key] = None

    for key in ['logp', 'eval']:
        if key in keys:
            if kwds[key] is None:
                kwds[key] = __func__

    # Build parents dictionary by parsing the __func__tion's arguments.
    (args, varargs, varkw, defaults) = inspect.getargspec(__func__)

    if defaults is None:
        defaults = ()

    # Make sure all parents were defined
    arg_deficit = (len(args) - ('value' in args)) - len(defaults)
    if arg_deficit > 0:
        err_str =  classname + ' ' + __func__.__name__ + ': no parent provided for the following labels:'
        for i in range(arg_deficit):
            err_str +=  " " + args[i + ('value' in args)]
            if i < arg_deficit-1:
                err_str += ','
        raise ValueError(err_str)

    # Fill in parent dictionary
    try:
        parents.update(dict(zip(args[-len(defaults):], defaults)))
    except TypeError:
        pass

    value = parents.pop('value', None)

    return (value, parents)

def stochastic(__func__=None, __class__=Stochastic, binary=False, discrete=False, **kwds):
    """
    Decorator function for instantiating stochastic variables. Usages:

    Medium:

        @stochastic
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):
            return foo(value, parent_name, ...)

    Long:

        @stochastic
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)


        @stochastic(trace=trace_object)
        def A(value = ., parent_name = .,  ...):

            def logp(value, parent_name, ...):
                return foo(value, parent_name, ...)

            def random(parent_name, ...):
                return bar(parent_name, ...)

    where foo() computes the log-probability of the variable A
    conditional on its value and its parents' values, and bar()
    generates a random value from A's distribution conditional on
    its parents' values.

    :SeeAlso:
      Stochastic, Deterministic, deterministic, data, Potential, potential, Model,
      distributions
    """

    def instantiate_p(__func__):
        value, parents = _extract(__func__, kwds, keys, 'Stochastic') 
        return __class__(value=value, parents=parents, **kwds)

    keys = ['logp','random','rseed']

    instantiate_p.kwds = kwds

    if __func__:
        return instantiate_p(__func__)

    return instantiate_p

# Shortcut alias
stoch = stochastic

def potential(__func__ = None, **kwds):
    """
    Decorator function instantiating potentials. Usage:

    @potential
    def B(parent_name = ., ...)
        return baz(parent_name, ...)

    where baz returns the deterministic B's value conditional
    on its parents.

    :SeeAlso:
      Deterministic, deterministic, Stochastic, Potential, stochastic, data, Model
    """
    def instantiate_pot(__func__):
        junk, parents = _extract(__func__, kwds, keys, 'Potential', probe=False)
        return Potential(parents=parents, **kwds)

    keys = ['logp']

    instantiate_pot.kwds = kwds

    if __func__:
        return instantiate_pot(__func__)

    return instantiate_pot
pot = potential

def deterministic(__func__ = None, **kwds):
    """
    Decorator function instantiating deterministic variables. Usage:

    @deterministic
    def B(parent_name = ., ...)
        return baz(parent_name, ...)

    @deterministic(trace = trace_object)
    def B(parent_name = ., ...)
        return baz(parent_name, ...)

    where baz returns the variable B's value conditional
    on its parents.

    :SeeAlso:
      Deterministic, Potential, potential, Stochastic, stochastic, data, Model,
      CommonDeterministics
    """
    def instantiate_n(__func__):
        junk, parents = _extract(__func__, kwds, keys, 'Deterministic', probe=False)
        return Deterministic(parents=parents, **kwds)

    keys = ['eval']

    instantiate_n.kwds = kwds

    if __func__:
        return instantiate_n(__func__)

    return instantiate_n

# Shortcut alias
dtrm = deterministic

def observed(obj=None, **kwds):
    """
    Decorator function to instantiate data objects.
    If given a Stochastic, sets a the observed flag to True.

    Can be used as

    @observed
    def A(value = ., parent_name = .,  ...):
        return foo(value, parent_name, ...)

    or as

    @stochastic(observed=True)
    def A(value = ., parent_name = .,  ...):
        return foo(value, parent_name, ...)


    :SeeAlso:
      stochastic, Stochastic, dtrm, Deterministic, potential, Potential, Model,
      distributions
    """

    if obj is not None:
        if isinstance(obj, Stochastic):
            obj._observed=True
            return obj
        else:
            p = stochastic(__func__=obj, observed=True, **kwds)
            return p

    kwds['observed']=True
    def instantiate_observed(func):
        return stochastic(func, **kwds)

    return instantiate_observed

data = observed

def robust_init(stochclass, tries, *args, **kwds):
    """Robust initialization of a Stochastic.

    If the evaluation of the log-probability returns a ZeroProbability
    error, due for example to a parent being outside of the support for
    this Stochastic, the values of parents are randomly sampled until
    a valid log-probability is obtained.

    If the log-probability is still not valid after `tries` attempts, the
    original ZeroProbability error is raised.

    :Parameters:
    stochclass : Stochastic, eg. Normal, Uniform, ...
      The Stochastic distribution to instantiate.
    tries : int
      Maximum number of times parents will be sampled.
    *args, **kwds
      Positional and keyword arguments to declare the Stochastic variable.

    :Example:
    >>> lower = pymc.Uniform('lower', 0., 2., value=1.5, rseed=True)
    >>> pymc.robust_init(pymc.Uniform, 100, 'data', lower=lower, upper=5, value=[1,2,3,4], observed=True)
    """
    # Find the direct parents
    stochs = [arg for arg in (list(args) + list(kwds.values())) \
                                if isinstance(arg.__class__, StochasticMeta)]

    # Find the extended parents
    parents = stochs
    for s in stochs:
        parents.extend(s.extended_parents)

    extended_parents = set(parents)

    # Select the parents with a random method.
    random_parents = [p for p in extended_parents if p.rseed is True and hasattr(p, 'random')]

    for i in range(tries):
        try:
            return stochclass(*args, **kwds)
        except ZeroProbability:
            exc = sys.exc_info()
            for parent in random_parents:
                try:
                    parent.random()
                except:
                    six.reraise(*exc)

    six.reraise(*exc)