Beispiel #1
0
def symvec(A, UPLO='F'):
    if isinstance(A, UTPM):
        return UTPM.symvec(A, UPLO=UPLO)

    elif isinstance(A, Function):
        return Function.symvec(A, UPLO=UPLO)

    elif isinstance(A, numpy.ndarray):
        return utils.symvec(A, UPLO=UPLO)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #2
0
def dot(a,b):
    """
    Same as NumPy dot but in UTP arithmetic
    """
    if isinstance(a,Function) or isinstance(b,Function):
        return Function.dot(a,b)

    elif isinstance(a,UTPM) or isinstance(b,UTPM):
        return UTPM.dot(a,b)

    else:
        return numpy.dot(a,b)
Beispiel #3
0
def dot(a, b):
    """
    Same as NumPy dot but in UTP arithmetic
    """
    if isinstance(a, Function) or isinstance(b, Function):
        return Function.dot(a, b)

    elif isinstance(a, UTPM) or isinstance(b, UTPM):
        return UTPM.dot(a, b)

    else:
        return numpy.dot(a, b)
Beispiel #4
0
def vecsym(v):
    if isinstance(v, UTPM):
        return UTPM.vecsym(v)

    elif isinstance(v, Function):
        return Function.vecsym(v)

    elif isinstance(v, numpy.ndarray):
        return utils.vecsym(v)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #5
0
def outer(a, b):
    """
    Same as NumPy outer but in UTP arithmetic
    """
    if isinstance(a, Function) or isinstance(b, Function):
        return Function.outer(a, b)

    elif isinstance(a, UTPM) or isinstance(b, UTPM):
        return UTPM.outer(a, b)

    else:
        return numpy.outer(a, b)
Beispiel #6
0
def symvec(A, UPLO='F'):
    if isinstance(A, UTPM):
        return UTPM.symvec(A, UPLO=UPLO)

    elif isinstance(A, Function):
        return Function.symvec(A, UPLO=UPLO)

    elif isinstance(A, numpy.ndarray):
        return utils.symvec(A, UPLO=UPLO)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #7
0
def vecsym(v):
    if isinstance(v, UTPM):
        return UTPM.vecsym(v)

    elif isinstance(v, Function):
        return Function.vecsym(v)

    elif isinstance(v, numpy.ndarray):
        return utils.vecsym(v)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #8
0
def outer(a,b):
    """
    Same as NumPy outer but in UTP arithmetic
    """
    if isinstance(a,Function) or isinstance(b,Function):
        return Function.outer(a,b)

    elif isinstance(a,UTPM) or isinstance(b,UTPM):
        return UTPM.outer(a,b)

    else:
        return numpy.outer(a,b)
Beispiel #9
0
    def test_dpm_hyp1f1(self):
        """
        check that algopy.special.dpm_hyp1f1 can be called with
        UTPM and Function instances as arguments
        """

        a, b, x = 1., 2., 3.
        y1 = dpm_hyp1f1(a, b, x)

        a, b, x = 1., 2., UTPM(3. * numpy.ones((1, 1)))
        y2 = dpm_hyp1f1(a, b, x)
        assert_almost_equal(y1, y2.data[0, 0])

        a, b, x = 1., 2., Function(3.)
        y3 = dpm_hyp1f1(a, b, x)
        assert_almost_equal(y1, y3.x)
Beispiel #10
0
    def test_logit(self):
        """
        check that algopy.special.logit can be called with
        UTPM and Function instances as arguments
        """
        p = 0.5
        x = p
        y1 = logit(x)

        x = UTPM(p * numpy.ones((1, 1)))
        y2 = logit(x)
        assert_almost_equal(y1, y2.data[0, 0])

        x = Function(p)
        y3 = logit(x)
        assert_almost_equal(y1, y3.x)
Beispiel #11
0
    def test_polygamma(self):
        """
        check that algopy.special.polygamma can be called with
        UTPM and Function instances as arguments
        """

        n, x = 2, 3.
        y1 = polygamma(n, x)

        n, x = 2, UTPM(3. * numpy.ones((1, 1)))
        y2 = polygamma(n, x)
        assert_almost_equal(y1, y2.data[0, 0])

        n, x = 2, Function(3.)
        y3 = polygamma(n, x)
        assert_almost_equal(y1, y3.x)
Beispiel #12
0
    def test_expit(self):
        """
        check that algopy.special.expit can be called with
        UTPM and Function instances as arguments
        """

        x = 3.
        y1 = expit(x)

        x = UTPM(3. * numpy.ones((1, 1)))
        y2 = expit(x)
        assert_almost_equal(y1, y2.data[0, 0])

        x = Function(3.)
        y3 = expit(x)
        assert_almost_equal(y1, y3.x)
Beispiel #13
0
    def test_psi(self):
        """
        check that algopy.special.polygamma can be called with
        UTPM and Function instances as arguments
        """

        x = 1.2
        y1 = psi(x)

        x = UTPM(1.2 * numpy.ones((1, 1)))
        y2 = psi(x)
        assert_almost_equal(y1, y2.data[0, 0])

        x = Function(1.2)
        y3 = psi(x)
        assert_almost_equal(y1, y3.x)
Beispiel #14
0
    def test_tracer_on_mixed_utpm_ndarray_mul(self):
        D, P = 1, 1
        A = numpy.arange(2 * 2, dtype=float).reshape(2, 2)

        x = UTPM(numpy.zeros((D, P, 2, 2)))

        def f(x):
            return sum(A * x)

        cg = CGraph()
        ax = Function(x)
        ay = f(ax)
        cg.independentFunctionList = [ax]
        cg.dependentFunctionList = [ay]

        assert_array_almost_equal(A, cg.gradient(x))
Beispiel #15
0
    def test_hyp0f1(self):
        """
        check that algopy.special.hyp0f1 can be called with
        UTPM and Function instances as arguments
        """

        b, x = 2., 3.
        y1 = hyp0f1(b, x)

        b, x = 2., UTPM(3. * numpy.ones((1, 1)))
        y2 = hyp0f1(b, x)
        assert_almost_equal(y1, y2.data[0, 0])

        b, x = 2., Function(3.)
        y3 = hyp0f1(b, x)
        assert_almost_equal(y1, y3.x)
Beispiel #16
0
    def test_hyp2f0(self):
        """
        check that algopy.special.hyp2f0 can be called with
        UTPM and Function instances as arguments
        """

        # use small x to ameliorate convergence issues
        a1, a2, x = 1., 2., 0.03
        y1 = hyp2f0(a1, a2, x)

        a1, a2, x = 1., 2., UTPM(0.03 * numpy.ones((1, 1)))
        y2 = hyp2f0(a1, a2, x)
        assert_almost_equal(y1, y2.data[0, 0])

        a1, a2, x = 1., 2., Function(0.03)
        y3 = hyp2f0(a1, a2, x)
        assert_almost_equal(y1, y3.x)
Beispiel #17
0
def eigh1(A):
    """
    generic implementation of eigh1
    """

    if isinstance(A, UTPM):
        return UTPM.eigh1(A)

    elif isinstance(A, Function):
        return Function.eigh1(A)

    elif isinstance(A, numpy.ndarray):
        A = UTPM(A.reshape((1,1) + A.shape))
        retval = UTPM.eigh1(A)
        return retval[0].data[0,0], retval[1].data[0,0],retval[2]

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #18
0
def fft(a, n=None, axis=-1):
    """
     
    equivalent to numpy.fft.fft(a, n=None, axis=-1)

    """

    if isinstance(a, UTPM):
        return UTPM.fft(a, n=n, axis=axis)

    elif isinstance(a, Function):
        return Function.fft(a, n=n, axis=axis)

    elif isinstance(a, numpy.ndarray):
        return numpy.fft.fft(a, n=n, axis=axis)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #19
0
def eigh1(A):
    """
    generic implementation of eigh1
    """

    if isinstance(A, UTPM):
        return UTPM.eigh1(A)

    elif isinstance(A, Function):
        return Function.eigh1(A)

    elif isinstance(A, numpy.ndarray):
        A = UTPM(A.reshape((1,1) + A.shape))
        retval = UTPM.eigh1(A)
        return retval[0].data[0,0], retval[1].data[0,0],retval[2]

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #20
0
    def test_dpm_hyp2f0(self):
        """
        check that algopy.special.dpm_hyp2f0 can be called with
        UTPM and Function instances as arguments
        """

        # these give hyp2f0 a chance of outputting real numbers
        a1, a2 = 1.5, 1.0

        # use small x to ameliorate convergence issues
        x = 0.03
        y1 = dpm_hyp2f0(a1, a2, x)

        x = UTPM(0.03 * numpy.ones((1, 1)))
        y2 = dpm_hyp2f0(a1, a2, x)
        assert_almost_equal(y1, y2.data[0, 0])

        x = Function(0.03)
        y3 = dpm_hyp2f0(a1, a2, x)
        assert_almost_equal(y1, y3.x)
Beispiel #21
0
def qr_full(A):
    """
    Q,R = qr_full(A)

    This function is merely a wrapper of
    UTPM.qr_full,  Function.qr_full, scipy.linalg.qr

    Parameters
    ----------

    A:      algopy.UTPM or algopy.Function or numpy.ndarray
            A.shape = (M,N),  M >= N

    Returns
    --------

    Q:      same type as A
            Q.shape = (M,M)

    R:      same type as A
            R.shape = (M,N)


    """

    if isinstance(A, UTPM):
        return UTPM.qr_full(A)

    elif isinstance(A, Function):
        return Function.qr_full(A)

    elif isinstance(A, numpy.ndarray):
        return scipy.linalg.qr(A)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
Beispiel #22
0
    def test_expm(self):
        def f(x):
            x = x.reshape((2, 2))
            return sum(expm(x))

        x = numpy.random.random(2 * 2)

        # forward mode

        ax = UTPM.init_jacobian(x)
        ay = f(ax)
        g1 = UTPM.extract_jacobian(ay)

        # reverse mode

        cg = CGraph()
        ax = Function(x)
        ay = f(ax)
        cg.independentFunctionList = [ax]
        cg.dependentFunctionList = [ay]

        g2 = cg.gradient(x)

        assert_array_almost_equal(g1, g2)
Beispiel #23
0
def qr_full(A):
    """
    Q,R = qr_full(A)

    This function is merely a wrapper of
    UTPM.qr_full,  Function.qr_full, scipy.linalg.qr

    Parameters
    ----------

    A:      algopy.UTPM or algopy.Function or numpy.ndarray
            A.shape = (M,N),  M >= N

    Returns
    --------

    Q:      same type as A
            Q.shape = (M,M)

    R:      same type as A
            R.shape = (M,N)


    """

    if isinstance(A, UTPM):
        return UTPM.qr_full(A)

    elif isinstance(A, Function):
        return Function.qr_full(A)

    elif isinstance(A, numpy.ndarray):
        return scipy.linalg.qr(A)

    else:
        raise NotImplementedError('don\'t know what to do with this instance')
# N number of cols of A
D, M, N = 2, 3, 3
P = M * N

# generate badly conditioned matrix A

A = UTPM(numpy.zeros((D, P, M, N)))
A.data[0, :] = numpy.random.rand(*(M, N))

for m in range(M):
    for n in range(N):
        p = m * N + n
        A.data[1, p, m, n] = 1.

cg = CGraph()
A = Function(A)
y = trace(inv(A))
cg.trace_off()

cg.independentFunctionList = [A]
cg.dependentFunctionList = [y]

ybar = y.x.zeros_like()
ybar.data[0, :] = 1.
cg.pullback([ybar])

# check gradient
g_forward = numpy.zeros(N * N)
g_reverse = numpy.zeros(N * N)

for m in range(M):
Beispiel #25
0
print('function evaluation =\n', logp(x, 3.5, sigma))

# forward mode with ALGOPY
utp = logp(x, mu, sigma).data[:, 0]
print(
    'function evaluation = %f\n1st directional derivative = %f\n2nd directional derivative = %f'
    % (utp[0], 1. * utp[1], 2. * utp[2]))

# finite differences solution:
print('finite differences derivative =\n',
      (logp(x, 3.5 + 10**-8, sigma) - logp(x, 3.5, sigma)) / 10**-8)

# trace function evaluation
cg = CGraph()
mu = Function(UTPM([[3.5], [1], [0]]))  #unknown variable
out = logp(x, mu, sigma)
cg.trace_off()
cg.independentFunctionList = [mu]
cg.dependentFunctionList = [out]
cg.plot(
    os.path.join(os.path.dirname(os.path.realpath(__file__)),
                 'posterior_log_probability_cgraph.png'))

# reverse mode with ALGOPY
outbar = UTPM([[1.], [0], [0]])
cg.pullback([outbar])

gradient = mu.xbar.data[0, 0]
Hess_vec = mu.xbar.data[1, 0]
Beispiel #26
0
"""
This example shows that most computations can be performed by numpy functions
on arrays of UTPM objects.

Just bear in mind that is much faster use UTPM instances of matrices than numpy.ndarrays
with UTPM elements.

"""

import numpy, os
from algopy import CGraph, Function, UTPM, dot, qr, eigh, inv

N, D, P = 2, 2, 1
cg = CGraph()
x = numpy.array([Function(UTPM(numpy.random.rand(*(D, P)))) for n in range(N)])
A = numpy.outer(x, x)
A = numpy.exp(A)
y = numpy.dot(A, x)

cg.independentFunctionList = list(x)
cg.dependentFunctionList = list(y)

cg.plot(os.path.join(os.path.dirname(__file__), 'numpy_dot_graph.svg'))
Beispiel #27
0
from algopy import CGraph, Function
cg = CGraph()
cg.trace_on()
x = Function(1)
y = Function(3)
z = x * y + x
cg.trace_off()
cg.independentFunctionList = [x, y]
cg.dependentFunctionList = [z]
print(cg)
cg.plot('example_tracer_cgraph.png')
# Eingangsgrößen
r = 2.0e-2  # m, Radius
i_hat = 20.0  # A, Strom
f = 1000.0  # Hz, Frequenz
n = 3  # Anzahl Perioden
n_p = 512  # Datenpunkte pro Periode

t = np.arange(n * n_p) / (n_p * f)  # Zeitvektor
current = i_hat * (np.sin(2 * np.pi * f * t) +
                   0.7 * np.sin(6 * np.pi * f * t + 1))  # Stromvorgabe
H = current / (2 * np.pi * r)  # Resultierende Feldvorgabe

graph = CGraph()
graph.trace_on()
x = Function([alpha, a, k, c, Msat])

# Parametervektor
p = {'alpha': x[0], 'a': x[1], 'k': x[2], 'c': x[3], 'm_sat': x[4]}

model = JilesAthertonModel.from_dict(p)
M = model.integrate_rk4(t, H)

H = H[::2]
t = t[::2]
B = mu_0 * (H + M)
dB_dt = np.zeros(np.size(B))
new = np.append([0.0], (B[1:] - B[0:-1]) / (t[1:] - t[0:-1]))

P = np.sum(0.5 * H * new)
# D - 1 is the degree of the Taylor polynomial
# P directional derivatives at once
# M number of rows of J1
# N number of cols of J1
# K number of rows of J2 (must be smaller than N)
D,P,M,N,K,Nx = 2,1,100,3,1,1


# METHOD 1: nullspace method
cg1 = CGraph()

J1 = Function(UTPM(numpy.random.rand(*(D,P,M,N))))
J2 = Function(UTPM(numpy.random.rand(*(D,P,K,N))))


Q,R = Function.qr_full(J2.T)
Q2 = Q[:,K:].T

J1_tilde = dot(J1,Q2.T)
Q,R = qr(J1_tilde)
V = solve(R.T, Q2)
C = dot(V.T,V)
cg1.trace_off()

cg1.independentFunctionList = [J1, J2]
cg1.dependentFunctionList = [C]

print('covariance matrix: C =\n',C)
print('check that Q2.T spans the nullspace of J2:\n', dot(J2,Q2.T))

# METHOD 2: image space method (potentially numerically unstable)
Beispiel #30
0
# create a CGraph instance that to store the computational trace
cg = CGraph()

# create an UTPM instance
D, N, M = 2, 3, 2
P = N

A = UTPM(numpy.zeros((D, P, M, N)))
x = UTPM(numpy.zeros((D, P, N, 1)))

x.data[0, :] = numpy.random.rand(N, 1)
A.data[0, :] = numpy.random.rand(M, N)

x.data[1, :, :, 0] = numpy.eye(P)

x = Function(x)
A = Function(A)

# wrap the UTPM instance in a Function instance to trace all operations
# that have x as an argument
# x = Function(x)

y = dot(A, x)

# define dependent and independent variables in the computational procedure
cg.independentFunctionList = [x, A]
cg.dependentFunctionList = [y]

# for such linear function we already know the Jacobian: df/dx = A
# y.data is a (D,P,N) array, i.e. we have to transpose to get the Jacobian
# Since the UTPM instrance is wrapped in a Function instance we have to access it
    M, N = J1.shape
    K, N = J2.shape
    Q, R = qr_full(J2.T)
    Q2 = Q[:, K:].T
    J1_tilde = dot(J1, Q2.T)
    Q, R = qr(J1_tilde)
    V = solve(R.T, Q2)
    return dot(V.T, V)


# dimensions of the involved matrices
D, P, M, N, K, Nx = 2, 1, 5, 3, 1, 1

# trace the function evaluation of METHOD 1: nullspace method
cg1 = CGraph()
J1 = Function(UTPM(numpy.random.rand(*(D, P, M, N))))
J2 = Function(UTPM(numpy.random.rand(*(D, P, K, N))))
C = eval_covariance_matrix_qr(J1, J2)
y = C[0, 0]
cg1.trace_off()
cg1.independentFunctionList = [J1, J2]
cg1.dependentFunctionList = [y]
print('covariance matrix: C =\n', C)

# trace the function evaluation of METHOD 2: naive method (potentially numerically unstable)
cg2 = CGraph()
J1 = Function(J1.x)
J2 = Function(J2.x)
C2 = eval_covariance_matrix_naive(J1, J2)
y = C2[0, 0]
cg2.trace_off()
import numpy
from algopy import CGraph, Function, UTPM, dot, qr, eigh, inv, solve

# first order derivatives, one directional derivative
# D - 1 is the degree of the Taylor polynomial
# P directional derivatives at once
# M number of rows of J1
# N number of cols of J1
# K number of rows of J2 (must be smaller than N)
D, P, M, N, K, Nx = 2, 1, 100, 3, 1, 1

# METHOD 1: nullspace method
cg1 = CGraph()

J1 = Function(UTPM(numpy.random.rand(*(D, P, M, N))))
J2 = Function(UTPM(numpy.random.rand(*(D, P, K, N))))

Q, R = Function.qr_full(J2.T)
Q2 = Q[:, K:].T

J1_tilde = dot(J1, Q2.T)
Q, R = qr(J1_tilde)
V = solve(R.T, Q2)
C = dot(V.T, V)
cg1.trace_off()

cg1.independentFunctionList = [J1, J2]
cg1.dependentFunctionList = [C]

print('covariance matrix: C =\n', C)
# create an UTPM instance
D, N, M = 2, 3, 2
P = 2 * N

x = UTPM(numpy.zeros((D, P, 2 * N, 1)))
x.data[0, :] = numpy.random.rand(2 * N, 1)
x.data[1, :, :, 0] = numpy.eye(P)
y = x[N:]
x = x[:N]

# wrap the UTPM instance in a Function instance to trace all operations
# that have x as an argument
# create a CGraph instance that to store the computational trace
cg = CGraph().trace_on()
x = Function(x)
y = Function(y)
z = f(x, y)
cg.trace_off()

# define dependent and independent variables in the computational procedure
cg.independentFunctionList = [x, y]
cg.dependentFunctionList = [z]

# Since the UTPM instrance is wrapped in a Function instance we have to access it
# by y.x. That means the Jacobian is
grad1 = z.x.data[1, :, 0]

print('forward gradient g(x) = \n', grad1)

# Now we want to compute the same Jacobian in the reverse mode of AD
Beispiel #34
0
def eval_g(x, y):
    """ some vector-valued function """
    retval = algopy.zeros(3, dtype=x)
    retval[0] = algopy.sin(x**2 + y)
    retval[1] = algopy.cos(x + y) - x
    retval[2] = algopy.sin(x)**2 + algopy.cos(x)**2
    return retval


# trace the function evaluation
# and store the computational graph in cg
cg = CGraph()
ax = 3.
ay = 5.
fx = Function(ax)
fy = Function(ay)
fz = eval_g(fx, fy)
cg.independentFunctionList = [fx, fy]
cg.dependentFunctionList = [fz]

# compute Taylor series
#
#  Jx( 1. + 2.*t + 3.*t**2 + 4.*t**3 + 5.*t**5,
#      6. + 7.*t + 8.*t**2 + 9.*t**3 + 10.*t**5 )
#  Jy( 1. + 2.*t + 3.*t**2 + 4.*t**3 + 5.*t**5,
#      6. + 7.*t + 8.*t**2 + 9.*t**3 + 10.*t**5 )
#
# where
#
# Jx = dg/dx