This file is indexed.

/usr/share/pyshared/brian/experimental/integrodiff.py is in python-brian 1.3.1-1build1.

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
'''
Conversion from integral form to differential form.
See BEP-5.
 
TODO:
* maximum rank
* better function name
* discrete time version
* rescale X0 to avoid numerical problems
* automatic determination of T?
'''
import re
import inspect
from brian.units import *
from brian.stdunits import *
from brian.inspection import get_identifiers
from brian.utils.autodiff import *
from brian.equations import *
from scipy import linalg

def integral2differential(expr, T=20 * ms, level=0, N=20, suffix=None, matrix_output=False):
    '''
    Example:
      eqs,w=integral2differential('g(t)=t*exp(-t/tau)')
      M,nvar,w=integral2differential('g(t)=t*exp(-t/tau)',matrix_output=True)
      
    Returns an Equations object corresponding to the time-invariant linear system specified
    by the impulse response g(t), and the value w to generate the impulse response:
    g_in->g_in+w.
    
    If matrix_output is True, returns the matrix of the corresponding differential system, the
    index nvar of the variable and the initial condition w=x_nvar(0).
    
    T is the interval over which the function is calculated.
    N is the number of points chosen in that interval.
    level is the frame level where the expression is defined.
    suffix is a string added to internal variable names (default: unique string).
    '''
    # Expression matching
    varname, time, RHS = re.search('\s*(\w+)\s*\(\s*(\w+)\s*\)\s*=\s*(.+)\s*', expr).groups()

    # Build the namespace
    frame = inspect.stack()[level + 1][0]
    global_namespace, local_namespace = frame.f_globals, frame.f_locals
    # Find external objects
    vars = list(get_identifiers(RHS))
    namespace = {}
    for var in vars:
        if var == time: # time variable
            pass
        elif var in local_namespace: #local
            namespace[var] = local_namespace[var]
        elif var in global_namespace: #global
            namespace[var] = global_namespace[var]
        elif var in globals(): # typically units
            namespace[var] = globals()[var]

    # Convert to a function
    f = eval('lambda ' + time + ':' + RHS, namespace)

    # Unit
    unit = get_unit(f(rand()*second)).name

    # Pick N points
    t = rand(N) * T

    # Calculate derivatives and find rank
    n = 0
    rank = 0
    M = f(t).reshape(N, 1)
    while rank == n:
        n += 1
        dfn = differentiate(f, t, order=n).reshape(N, 1)
        x, _, rank, _ = linalg.lstsq(M, dfn)
        if rank == n:
            M = hstack([M, dfn])
            oldx = x
    # oldx expresses dfn as a function of df0,..,dfn-1 (n=rank)

    # Find initial condition
    X0 = array([differentiate(f, 0 * ms, order=n) for n in range(rank)])

    # Rescaling DOES NOT WORK
    #R=ones(rank)
    #for i in range(rank):
    #    if X0[i]!=0.:
    #        R[i]=1./X0[i]
    #    else:
    #        R[i]=1.
    #R=diag(R)
    #X0=dot(R,X0)
    #oldx=dot(R,oldx)

    # Build A
    A = diag(ones(rank - 1), 1)
    A[-1, :] = oldx.reshape(1, rank)

    # Find Q=P^{-1}
    Q = eye(rank)
    if X0[0] == 0.: # continuous g, spikes act on last variable: x->x+1
        Q[:, -1] = X0
        nvar = rank - 1
        w = 1.
        # Exact inversion
        P = eye(rank)
        P[:-1, -1] = -X0[:-1] / X0[-1] # Has to be !=0 !!
        P[-1, -1] = 1. / X0[-1]
    else: # discontinuous g, spikes act on first variable: x->x+g(0)
        Q[:, 0] = X0
        nvar = 0
        w = X0[0]
        P = linalg.inv(Q)

    M = dot(dot(P, A), Q)
    #M=dot(linalg.inv(R),dot(M,R))

    # Turn into string
    # Set variable names
    if rank < 5:
        names = [varname] + ['x', 'y', 'z'][:rank - 1]
    else:
        names = [varname] + ['x' + str(i) for i in range(rank - 1)]

    # Add suffix
    if suffix is None:
        suffix = unique_id()
    names[1:] = [name + suffix for name in names[1:]]

    # Build string
    eqs = []
    for i in range(rank):
        eqs.append('d' + names[i] + '/dt=' + '+'.join([str(x) + '*' + name for x, name in zip(M[i, :], names) if x != 0.]) +
                   ' : ' + str(unit))
    eqs.append(varname + '_in=' + names[nvar]) # alias
    eq_string = '\n'.join(eqs).replace('+-', '-')

    if matrix_output:
        return M, nvar, w
    else:
        return Equations(eq_string), w

if __name__ == '__main__':
    from brian import *
    from scipy import linalg
    tau = 10 * ms
    tau2 = 5 * ms
    freq = 350 * Hz
    # The gammatone example does not seem to work for higher orders
    # probably a numerical problem; use a rescaling matrix for X0?
    f = lambda t:(t / tau) ** 1 * exp(-t / tau) * cos(2 * pi * freq * t)
    A, nvar, w = integral2differential('g(t)=(t/tau)**1*exp(-t/tau)*cos(2*pi*freq*t)', suffix='',
                                   matrix_output=True)
    eq, w = integral2differential('g(t)=(t/tau)**1*exp(-t/tau)*cos(2*pi*freq*t)', suffix='',
                                   matrix_output=False)
    print eq
    #f=lambda t:exp(-t/tau)-exp(-t/tau2)*cos(2*pi*t/tau)
    #A,nvar,w=integral2differential('g(t)=exp(-t/tau)-exp(-t/tau2)*cos(2*pi*t/tau)',
    #                                matrix_output=True)
    print A, nvar, w
    for t in range(10):
        t = t * 1 * ms
        print linalg.expm(A * t)[0, nvar] * w, f(t)
    #t=arange(50)*.5*ms
    #plot(t,f(t))
    #show()