This file is indexed.

/usr/share/pyshared/pymc/gp/GPutils.py is in python-pymc 2.2+ds-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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# Copyright (c) Anand Patil, 2007

__docformat__='reStructuredText'
__all__ = ['observe', 'plot_envelope', 'predictive_check', 'regularize_array', 'trimult', 'trisolve', 'vecs_to_datmesh', 'caching_call', 'caching_callable',
            'fast_matrix_copy', 'point_predict','square_and_sum','point_eval']


# TODO: Implement lintrans, allow obs_V to be a huge matrix or an ndarray in observe().

from numpy import *
from numpy.linalg import solve, cholesky, eigh
from numpy.linalg.linalg import LinAlgError
from .linalg_utils import *
from threading import Thread, Lock
import sys
from pymc import thread_partition_array, map_noreturn
from pymc.gp import chunksize
import pymc

from pymc import six
from pymc.six import print_
xrange = six.moves.xrange

try:
    from PyMC2 import ZeroProbability
except ImportError:
    class ZeroProbability(ValueError):
        pass

half_log_2pi = .5 * log(2. * pi)

def fast_matrix_copy(f, t=None, n_threads=1):
    """
    Not any faster than a serial copy so far.
    """
    if not f.flags['F_CONTIGUOUS']:
        raise RuntimeError('This will not be fast unless input array f is Fortran-contiguous.')

    if t is None:
        t=asmatrix(empty(f.shape, order='F'))
    elif not t.flags['F_CONTIGUOUS']:
        raise RuntimeError('This will not be fast unless input array t is Fortran-contiguous.')

    # Figure out how to divide job up between threads.
    dcopy_wrap(ravel(asarray(f.T)),ravel(asarray(t.T)))
    return t

def zero_lower_triangle(C):
    pass

def caching_call(f, x, x_sofar, f_sofar):
    """
    Computes f(x) given that f(x_sofar) = x_sofar.
    returns f(x), and new versions of x_sofar and f_sofar.
    """
    lenx = x.shape[0]

    nr,rf,rt,nu,xu,ui = remove_duplicates(x)

    unique_indices=ui[:nu]
    x_unique=xu[:nu]
    repeat_from=rf[:nr]
    repeat_to=rt[:nr]

    # Check which observations have already been made.
    if x_sofar is not None:

        f_unique, new_indices, N_new_indices  = check_repeats(x_unique, x_sofar, f_sofar)

        # If there are any new input points, draw values over them.
        if N_new_indices>0:

            x_new = x_unique[new_indices[:N_new_indices]]
            f_new = f(x_new)

            f_unique[new_indices[:N_new_indices]] = f_new

            # Record the new values
            x_sofar = vstack((x_sofar, x_new))
            f_sofar = hstack((f_sofar, f_new))
        else:
            f=f_unique

    # If no observations have been made, don't check.
    else:
        f_unique = f(x_unique)
        x_sofar = x_unique
        f_sofar = f_unique

    f=empty(lenx)
    f[unique_indices]=f_unique
    f[repeat_to]=f[repeat_from]

    return f, x_sofar, f_sofar
    
def square_and_sum(a,s):
    """
    Writes np.sum(a**2,axis=0) into s
    """
    cmin, cmax = thread_partition_array(a)
    map_noreturn(asqs, [(a,s,cmin[i],cmax[i]) for i in xrange(len(cmax))])
    return a

class caching_callable(object):
    """
    F = caching_callable(f[, x_sofar, f_sofar, update_cache=True])

    f is the function whose output should be cached.
    x_sofar, if provided, is an initial list of caching locations.
    f_sofar, if provided, is the value of f at x_sofar.
    update_cache tells whether x_sofar and f_sofar should be updated as additional calls are made.
    """
    def __init__(self, f, x_sofar=None, f_sofar=None, update_cache=True):
        self.f = f
        self.x_sofar = x_sofar
        self.f_sofar = f_sofar
        self.update_cache = update_cache
        if self.x_sofar is not None and self.f_sofar is None:
            junk, self.x_sofar, self.f_sofar = caching_call(self.f, self.x_sofar)
        self.last_x = x_sofar
        self.last_f = f_sofar

    def __call__(self, x):
        if x is self.x_sofar:
            return self.f_sofar
        elif x is self.last_x:
            return self.last_f
        f, x_sofar, f_sofar = caching_call(self.f, x, self.x_sofar, self.f_sofar)
        self.last_x = x
        self.last_f = f
        if self.update_cache:
            self.x_sofar = x_sofar
            self.f_sofar = f_sofar
        return f

def vecs_to_datmesh(x, y):
    """
    Converts input arguments x and y to a 2d meshgrid,
    suitable for calling Means, Covariances and Realizations.
    """
    x,y = meshgrid(x,y)
    out = zeros(x.shape + (2,), dtype=float)
    out[:,:,0] = x
    out[:,:,1] = y
    return out

def trimult(U,x,uplo='U',transa='N',alpha=1.,inplace=False):
    """
    b = trimult(U,x, uplo='U')


    Multiplies U x, where U is upper triangular if uplo='U'
    or lower triangular if uplo = 'L'.
    """
    if inplace:
        b=x
    else:
        b = x.copy('F')
    dtrmm_wrap(a=U,b=b,uplo=uplo,transa=transa,alpha=alpha)
    return b


def trisolve(U,b,uplo='U',transa='N',alpha=1.,inplace=False):
    """
    x = trisolve(U,b, uplo='U')


    Solves U x = b, where U is upper triangular if uplo='U'
    or lower triangular if uplo = 'L'.


    If a degenerate column is found, an error is raised.
    """
    if inplace:
        x=b
    else:
        x = b.copy('F')
    if U.shape[0] == 0:
        raise ValueError('Attempted to solve zero-rank triangular system')
    dtrsm_wrap(a=U,b=x,side='L',uplo=uplo,transa=transa,alpha=alpha)
    return x

def regularize_array(A):
    """
    Takes an ndarray as an input.


    -   If the array is one-dimensional, it's assumed to be an array of input values.

    -   If the array is more than one-dimensional, its last index is assumed to curse
        over spatial dimension.


    Either way, the return value is at least two dimensional. A.shape[-1] gives the
    number of spatial dimensions.
    """
    # Make sure A is an array.
    if not isinstance(A,ndarray):
        A = array(A, dtype=float)
    elif A.__class__ is not ndarray:
        A = asarray(A, dtype=float)

    # If A is one-dimensional, interpret it as an array of points on the line.
    if len(A.shape) <= 1:
        return A.reshape(-1,1)

    # Otherwise, interpret it as an array of n-dimensional points, where n
    # is the size of A along its last index.
    elif A.shape[-1]>1 and len(A.shape) > 2:
        return A.reshape(-1, A.shape[-1])

    else:
        return A

def plot_envelope(M,C,mesh):
    """
    plot_envelope(M,C,mesh)


    plots the pointwise mean +/- sd envelope defined by M and C
    along their base mesh.


    :Arguments:

        -   `M`: A Gaussian process mean.

        -   `C`: A Gaussian process covariance

        -   `mesh`: The mesh on which to evaluate the mean and cov.
    """

    try:
        from pylab import fill, plot, clf, axis
        x=concatenate((mesh, mesh[::-1]))
        mean, var = point_eval(M,C,mesh)
        sig = sqrt(var)
        mean = M(mesh)
        y=concatenate((mean-sig, (mean+sig)[::-1]))
        # clf()
        fill(x,y,facecolor='.8',edgecolor='1.')
        plot(mesh, mean, 'k-.')
    except ImportError:
        print_("Matplotlib is not installed; plotting is disabled.")

def observe(M, C, obs_mesh, obs_vals, obs_V = 0, lintrans = None, cross_validate = True):
    """
    (M, C, obs_mesh, obs_vals[, obs_V = 0, lintrans = None, cross_validate = True])


    Imposes observation of the value of obs_vals on M and C, where

    obs_vals ~ N(lintrans * f(obs_mesh), V)
    f ~ GP(M,C)


    :Arguments:

        -   `M`: The mean function

        -   `C`: The covariance function

        -   `obs_mesh`: The places where f has been evaluated.

        -   `obs_vals`: The values of f that were observed there.

        -   `obs_V`: The observation variance. If None, assumed to be infinite
            (observations made with no error).

        -   `lintrans`: A linear transformation. If None, assumed to be the
            identity transformation (pretend it doesn't exist).

        -   `cross_validate`: A flag indicating whether a check should be done to
            see if the data could have arisen from M and C with positive probability.

    """
    obs_mesh = regularize_array(obs_mesh)
    # print_(obs_mesh)
    obs_V = resize(obs_V, obs_mesh.shape[0])
    obs_vals = resize(obs_vals, obs_mesh.shape[0])

    # First observe C.
    relevant_slice, obs_mesh_new = C.observe(obs_mesh, obs_V, output_type='o')

    # Then observe M from C.
    M.observe(C, obs_mesh_new, obs_vals.ravel()[relevant_slice])

    # Cross-validate if not asked not to.
    if obs_mesh_new.shape[0] < obs_mesh.shape[0]:
        if cross_validate:
            if not predictive_check(obs_vals, obs_mesh, M, C.obs_piv, sqrt(C.relative_precision)):
                raise ValueError("These data seem extremely improbable given your GP prior. \n Suggestions: decrease observation precision, or adjust the covariance to \n allow the function to be less smooth.")


def predictive_check(obs_vals, obs_mesh, M, posdef_indices, tolerance):
    """
    OK = predictive_check(obs_vals, obs_mesh, M, posdef_indices, tolerance)


    If an internal covariance is low-rank, make sure the observations
    are consistent. Returns True if good, False if bad.


    :Arguments:

        -   `obs_vals`: The observed values.

        -   `obs_mesh`: The mesh on which the observed values were observed.

        -   `M`: The mean function, observed at obs_vals[posdef_indices].

        -   `tolerance`: The maximum allowable deviation at M(obs_mesh[non_posdef_indices]).
    """

    non_posdef_indices = array(list(set(range(len(obs_vals))) - set(posdef_indices)),dtype=int)
    if len(non_posdef_indices)>0:
        M_under = M(obs_mesh[non_posdef_indices,:]).ravel()
        dev = abs((M_under - obs_vals[non_posdef_indices]))
        if dev.max()>tolerance:
            return False

    return True

def point_predict(f, x, size=1, nugget=None):
    """
    point_predict(f, x[, size, nugget])

    Makes 'size' simulations for f(x) + N(0,nugget).
    Simulated values of f(x_i) are uncorrelated for different i.
    Useful for geostatistical predictions.
    """
    orig_shape = x.shape
    x = regularize_array(x)

    mu = f.M_internal(x, regularize=False)
    V = f.C_internal(x, regularize=False)
    if nugget is not None:
        V += nugget
    out= random.normal(size=(size, x.shape[0])) * sqrt(V) + mu
    return out.reshape((size,)+ orig_shape[:-1]).squeeze()


def point_eval(M, C, x):
    """
    Evaluates M(x) and C(x).
    
    Minimizes computation; evaluating M(x) and C(x) separately would
    evaluate the off-diagonal covariance term twice, but callling
    point_eval(M,C,x) would only evaluate it once.
    
    Also chunks the evaluations if the off-diagonal term.
    """
    
    x_ = regularize_array(x)
    
    M_out = empty(x_.shape[0])
    V_out = empty(x_.shape[0])
    
    if isinstance(C, pymc.gp.BasisCovariance):
        y_size = len(C.basis)
    elif C.obs_mesh is not None:
        y_size = C.obs_mesh.shape[0]
    else:
        y_size = 1
    
    n_chunks = ceil(y_size*x_.shape[0]/float(chunksize))
    bounds = array(linspace(0,x_.shape[0],n_chunks+1),dtype='int')
    cmin=bounds[:-1]
    cmax=bounds[1:]
    for (cmin,cmax) in zip(bounds[:-1],bounds[1:]):           
        x__ = x_[cmin:cmax] 
        V_out[cmin:cmax], Uo_Cxo = C(x__, regularize=False, return_Uo_Cxo=True)
        M_out[cmin:cmax] = M(x__, regularize=False, Uo_Cxo=Uo_Cxo)

    if len(x.shape) > 1:
        targ_shape = x.shape[:-1]
    else:
        targ_shape = x.shape
    return M_out.reshape(targ_shape), V_out.reshape(targ_shape)