We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
multivariate normal density cannot handle vectors as it claims
It seems that if `x` and `mu` are vectors, the call to `tf.matrix_triangular_solve` would fail (as `d = x - mu` is rank 1). Worse, if `x` and `mu` are of different dimensionality (e.g. one a row, one a column vector) broadcasting happens and fails silently.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gpflow/models/gpr.py`
Content:
```
1 # Copyright 2016 James Hensman, Valentine Svensson, alexggmatthews, fujiisoup
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 
16 from __future__ import absolute_import
17 import tensorflow as tf
18 
19 from .. import likelihoods
20 from .. import settings
21 
22 from ..params import DataHolder
23 from ..decors import params_as_tensors
24 from ..decors import name_scope
25 from ..densities import multivariate_normal
26 
27 from .model import GPModel
28 
29 
30 class GPR(GPModel):
31     """
32     Gaussian Process Regression.
33 
34     This is a vanilla implementation of GP regression with a Gaussian
35     likelihood.  Multiple columns of Y are treated independently.
36 
37     The log likelihood i this models is sometimes referred to as the 'marginal log likelihood', and is given by
38 
39     .. math::
40 
41        \\log p(\\mathbf y \\,|\\, \\mathbf f) = \\mathcal N\\left(\\mathbf y\,|\, 0, \\mathbf K + \\sigma_n \\mathbf I\\right)
42     """
43     def __init__(self, X, Y, kern, mean_function=None, **kwargs):
44         """
45         X is a data matrix, size N x D
46         Y is a data matrix, size N x R
47         kern, mean_function are appropriate GPflow objects
48         """
49         likelihood = likelihoods.Gaussian()
50         X = DataHolder(X)
51         Y = DataHolder(Y)
52         GPModel.__init__(self, X, Y, kern, likelihood, mean_function, **kwargs)
53 
54     @name_scope('likelihood')
55     @params_as_tensors
56     def _build_likelihood(self):
57         """
58         Construct a tensorflow function to compute the likelihood.
59 
60             \log p(Y | theta).
61 
62         """
63         K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance
64         L = tf.cholesky(K)
65         m = self.mean_function(self.X)
66 
67         return multivariate_normal(self.Y, m, L)
68 
69     @name_scope('predict')
70     @params_as_tensors
71     def _build_predict(self, Xnew, full_cov=False):
72         """
73         Xnew is a data matrix, point at which we want to predict
74 
75         This method computes
76 
77             p(F* | Y )
78 
79         where F* are points on the GP at Xnew, Y are noisy observations at X.
80 
81         """
82         Kx = self.kern.K(self.X, Xnew)
83         K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance
84         L = tf.cholesky(K)
85         A = tf.matrix_triangular_solve(L, Kx, lower=True)
86         V = tf.matrix_triangular_solve(L, self.Y - self.mean_function(self.X))
87         fmean = tf.matmul(A, V, transpose_a=True) + self.mean_function(Xnew)
88         if full_cov:
89             fvar = self.kern.K(Xnew) - tf.matmul(A, A, transpose_a=True)
90             shape = tf.stack([1, 1, tf.shape(self.Y)[1]])
91             fvar = tf.tile(tf.expand_dims(fvar, 2), shape)
92         else:
93             fvar = self.kern.Kdiag(Xnew) - tf.reduce_sum(tf.square(A), 0)
94             fvar = tf.tile(tf.reshape(fvar, (-1, 1)), [1, tf.shape(self.Y)[1]])
95         return fmean, fvar
96
```

Path: `gpflow/densities.py`
Content:
```
1 # Copyright 2016 James Hensman, alexggmatthews
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 
16 import tensorflow as tf
17 import numpy as np
18 
19 
20 from . import settings
21 
22 
23 def gaussian(x, mu, var):
24     return -0.5 * (np.log(2 * np.pi) + tf.log(var) + tf.square(mu-x)/var)
25 
26 
27 def lognormal(x, mu, var):
28     lnx = tf.log(x)
29     return gaussian(lnx, mu, var) - lnx
30 
31 
32 def bernoulli(p, y):
33     return tf.log(tf.where(tf.equal(y, 1), p, 1-p))
34 
35 
36 def poisson(lamb, y):
37     return y * tf.log(lamb) - lamb - tf.lgamma(y + 1.)
38 
39 
40 def exponential(lamb, y):
41     return - y/lamb - tf.log(lamb)
42 
43 
44 def gamma(shape, scale, x):
45     return -shape * tf.log(scale) - tf.lgamma(shape)\
46         + (shape - 1.) * tf.log(x) - x / scale
47 
48 
49 def student_t(x, mean, scale, deg_free):
50     const = tf.lgamma(tf.cast((deg_free + 1.) * 0.5, settings.float_type))\
51         - tf.lgamma(tf.cast(deg_free * 0.5, settings.float_type))\
52         - 0.5*(tf.log(tf.square(scale)) + tf.cast(tf.log(deg_free), settings.float_type)
53                + np.log(np.pi))
54     const = tf.cast(const, settings.float_type)
55     return const - 0.5*(deg_free + 1.) * \
56         tf.log(1. + (1. / deg_free) * (tf.square((x - mean) / scale)))
57 
58 
59 def beta(alpha, beta, y):
60     # need to clip y, since log of 0 is nan...
61     y = tf.clip_by_value(y, 1e-6, 1-1e-6)
62     return (alpha - 1.) * tf.log(y) + (beta - 1.) * tf.log(1. - y) \
63         + tf.lgamma(alpha + beta)\
64         - tf.lgamma(alpha)\
65         - tf.lgamma(beta)
66 
67 
68 def laplace(mu, sigma, y):
69     return - tf.abs(mu - y) / sigma - tf.log(2. * sigma)
70 
71 
72 def multivariate_normal(x, mu, L):
73     """
74     L is the Cholesky decomposition of the covariance.
75 
76     x and mu are either vectors (ndim=1) or matrices. In the matrix case, we
77     assume independence over the *columns*: the number of rows must match the
78     size of L.
79     """
80     d = x - mu
81     alpha = tf.matrix_triangular_solve(L, d, lower=True)
82     num_col = 1 if tf.rank(x) == 1 else tf.shape(x)[1]
83     num_col = tf.cast(num_col, settings.float_type)
84     num_dims = tf.cast(tf.shape(x)[0], settings.float_type)
85     ret = - 0.5 * num_dims * num_col * np.log(2 * np.pi)
86     ret += - num_col * tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))
87     ret += - 0.5 * tf.reduce_sum(tf.square(alpha))
88     return ret
89
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gpflow/densities.py b/gpflow/densities.py
--- a/gpflow/densities.py
+++ b/gpflow/densities.py
@@ -71,18 +71,25 @@
 
 def multivariate_normal(x, mu, L):
     """
-    L is the Cholesky decomposition of the covariance.
-
-    x and mu are either vectors (ndim=1) or matrices. In the matrix case, we
-    assume independence over the *columns*: the number of rows must match the
-    size of L.
+    Computes the log-density of a multivariate normal.
+    :param x  : D or DxN sample(s) for which we want the density
+    :param mu : D or DxN mean(s) of the normal distribution
+    :param L  : DxD Cholesky decomposition of the covariance matrix
+    :return p : N vector of log densities for each of the N x's and/or mu's
+
+    x and mu are either vectors or matrices. If both are vectors ((N,) or (N,1)):
+    p[0] = log pdf(x) where x ~ N(mu, LL^T)
+    If at least one is a matrix, we assume independence over the *columns*:
+    the number of rows must match the size of L. Broadcasting behaviour:
+    p[n] = log pdf of:
+    x[n] ~ N(mu, LL^T) or x ~ N(mu[n], LL^T) or x[n] ~ N(mu[n], LL^T)
     """
+    x  = tf.cond(tf.rank(x)  < 2, lambda: x[:, None],  lambda: x)
+    mu = tf.cond(tf.rank(mu) < 2, lambda: mu[:, None], lambda: mu)
     d = x - mu
     alpha = tf.matrix_triangular_solve(L, d, lower=True)
-    num_col = 1 if tf.rank(x) == 1 else tf.shape(x)[1]
-    num_col = tf.cast(num_col, settings.float_type)
-    num_dims = tf.cast(tf.shape(x)[0], settings.float_type)
-    ret = - 0.5 * num_dims * num_col * np.log(2 * np.pi)
-    ret += - num_col * tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))
-    ret += - 0.5 * tf.reduce_sum(tf.square(alpha))
-    return ret
+    num_dims = tf.cast(tf.shape(d)[0], L.dtype)
+    p = - 0.5 * tf.reduce_sum(tf.square(alpha), 0)
+    p -= 0.5 * num_dims * np.log(2 * np.pi)
+    p -= tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))
+    return p
diff --git a/gpflow/models/gpr.py b/gpflow/models/gpr.py
--- a/gpflow/models/gpr.py
+++ b/gpflow/models/gpr.py
@@ -63,8 +63,9 @@
         K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance
         L = tf.cholesky(K)
         m = self.mean_function(self.X)
+        logpdf = multivariate_normal(self.Y, m, L)  # (R,) log-likelihoods for each independent dimension of Y
 
-        return multivariate_normal(self.Y, m, L)
+        return tf.reduce_sum(logpdf)
 
     @name_scope('predict')
     @params_as_tensors

{"golden_diff": "diff --git a/gpflow/densities.py b/gpflow/densities.py\n--- a/gpflow/densities.py\n+++ b/gpflow/densities.py\n@@ -71,18 +71,25 @@\n \n def multivariate_normal(x, mu, L):\n     \"\"\"\n-    L is the Cholesky decomposition of the covariance.\n-\n-    x and mu are either vectors (ndim=1) or matrices. In the matrix case, we\n-    assume independence over the *columns*: the number of rows must match the\n-    size of L.\n+    Computes the log-density of a multivariate normal.\n+    :param x  : D or DxN sample(s) for which we want the density\n+    :param mu : D or DxN mean(s) of the normal distribution\n+    :param L  : DxD Cholesky decomposition of the covariance matrix\n+    :return p : N vector of log densities for each of the N x's and/or mu's\n+\n+    x and mu are either vectors or matrices. If both are vectors ((N,) or (N,1)):\n+    p[0] = log pdf(x) where x ~ N(mu, LL^T)\n+    If at least one is a matrix, we assume independence over the *columns*:\n+    the number of rows must match the size of L. Broadcasting behaviour:\n+    p[n] = log pdf of:\n+    x[n] ~ N(mu, LL^T) or x ~ N(mu[n], LL^T) or x[n] ~ N(mu[n], LL^T)\n     \"\"\"\n+    x  = tf.cond(tf.rank(x)  < 2, lambda: x[:, None],  lambda: x)\n+    mu = tf.cond(tf.rank(mu) < 2, lambda: mu[:, None], lambda: mu)\n     d = x - mu\n     alpha = tf.matrix_triangular_solve(L, d, lower=True)\n-    num_col = 1 if tf.rank(x) == 1 else tf.shape(x)[1]\n-    num_col = tf.cast(num_col, settings.float_type)\n-    num_dims = tf.cast(tf.shape(x)[0], settings.float_type)\n-    ret = - 0.5 * num_dims * num_col * np.log(2 * np.pi)\n-    ret += - num_col * tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))\n-    ret += - 0.5 * tf.reduce_sum(tf.square(alpha))\n-    return ret\n+    num_dims = tf.cast(tf.shape(d)[0], L.dtype)\n+    p = - 0.5 * tf.reduce_sum(tf.square(alpha), 0)\n+    p -= 0.5 * num_dims * np.log(2 * np.pi)\n+    p -= tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))\n+    return p\ndiff --git a/gpflow/models/gpr.py b/gpflow/models/gpr.py\n--- a/gpflow/models/gpr.py\n+++ b/gpflow/models/gpr.py\n@@ -63,8 +63,9 @@\n         K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance\n         L = tf.cholesky(K)\n         m = self.mean_function(self.X)\n+        logpdf = multivariate_normal(self.Y, m, L)  # (R,) log-likelihoods for each independent dimension of Y\n \n-        return multivariate_normal(self.Y, m, L)\n+        return tf.reduce_sum(logpdf)\n \n     @name_scope('predict')\n     @params_as_tensors\n", "issue": "multivariate normal density cannot handle vectors as it claims\nIt seems that if `x` and `mu` are vectors, the call to `tf.matrix_triangular_solve` would fail (as `d = x - mu` is rank 1). Worse, if `x` and `mu` are of different dimensionality (e.g. one a row, one a column vector) broadcasting happens and fails silently.\n", "before_files": [{"content": "# Copyright 2016 James Hensman, Valentine Svensson, alexggmatthews, fujiisoup\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nfrom __future__ import absolute_import\nimport tensorflow as tf\n\nfrom .. import likelihoods\nfrom .. import settings\n\nfrom ..params import DataHolder\nfrom ..decors import params_as_tensors\nfrom ..decors import name_scope\nfrom ..densities import multivariate_normal\n\nfrom .model import GPModel\n\n\nclass GPR(GPModel):\n    \"\"\"\n    Gaussian Process Regression.\n\n    This is a vanilla implementation of GP regression with a Gaussian\n    likelihood.  Multiple columns of Y are treated independently.\n\n    The log likelihood i this models is sometimes referred to as the 'marginal log likelihood', and is given by\n\n    .. math::\n\n       \\\\log p(\\\\mathbf y \\\\,|\\\\, \\\\mathbf f) = \\\\mathcal N\\\\left(\\\\mathbf y\\,|\\, 0, \\\\mathbf K + \\\\sigma_n \\\\mathbf I\\\\right)\n    \"\"\"\n    def __init__(self, X, Y, kern, mean_function=None, **kwargs):\n        \"\"\"\n        X is a data matrix, size N x D\n        Y is a data matrix, size N x R\n        kern, mean_function are appropriate GPflow objects\n        \"\"\"\n        likelihood = likelihoods.Gaussian()\n        X = DataHolder(X)\n        Y = DataHolder(Y)\n        GPModel.__init__(self, X, Y, kern, likelihood, mean_function, **kwargs)\n\n    @name_scope('likelihood')\n    @params_as_tensors\n    def _build_likelihood(self):\n        \"\"\"\n        Construct a tensorflow function to compute the likelihood.\n\n            \\log p(Y | theta).\n\n        \"\"\"\n        K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance\n        L = tf.cholesky(K)\n        m = self.mean_function(self.X)\n\n        return multivariate_normal(self.Y, m, L)\n\n    @name_scope('predict')\n    @params_as_tensors\n    def _build_predict(self, Xnew, full_cov=False):\n        \"\"\"\n        Xnew is a data matrix, point at which we want to predict\n\n        This method computes\n\n            p(F* | Y )\n\n        where F* are points on the GP at Xnew, Y are noisy observations at X.\n\n        \"\"\"\n        Kx = self.kern.K(self.X, Xnew)\n        K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance\n        L = tf.cholesky(K)\n        A = tf.matrix_triangular_solve(L, Kx, lower=True)\n        V = tf.matrix_triangular_solve(L, self.Y - self.mean_function(self.X))\n        fmean = tf.matmul(A, V, transpose_a=True) + self.mean_function(Xnew)\n        if full_cov:\n            fvar = self.kern.K(Xnew) - tf.matmul(A, A, transpose_a=True)\n            shape = tf.stack([1, 1, tf.shape(self.Y)[1]])\n            fvar = tf.tile(tf.expand_dims(fvar, 2), shape)\n        else:\n            fvar = self.kern.Kdiag(Xnew) - tf.reduce_sum(tf.square(A), 0)\n            fvar = tf.tile(tf.reshape(fvar, (-1, 1)), [1, tf.shape(self.Y)[1]])\n        return fmean, fvar\n", "path": "gpflow/models/gpr.py"}, {"content": "# Copyright 2016 James Hensman, alexggmatthews\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nimport tensorflow as tf\nimport numpy as np\n\n\nfrom . import settings\n\n\ndef gaussian(x, mu, var):\n    return -0.5 * (np.log(2 * np.pi) + tf.log(var) + tf.square(mu-x)/var)\n\n\ndef lognormal(x, mu, var):\n    lnx = tf.log(x)\n    return gaussian(lnx, mu, var) - lnx\n\n\ndef bernoulli(p, y):\n    return tf.log(tf.where(tf.equal(y, 1), p, 1-p))\n\n\ndef poisson(lamb, y):\n    return y * tf.log(lamb) - lamb - tf.lgamma(y + 1.)\n\n\ndef exponential(lamb, y):\n    return - y/lamb - tf.log(lamb)\n\n\ndef gamma(shape, scale, x):\n    return -shape * tf.log(scale) - tf.lgamma(shape)\\\n        + (shape - 1.) * tf.log(x) - x / scale\n\n\ndef student_t(x, mean, scale, deg_free):\n    const = tf.lgamma(tf.cast((deg_free + 1.) * 0.5, settings.float_type))\\\n        - tf.lgamma(tf.cast(deg_free * 0.5, settings.float_type))\\\n        - 0.5*(tf.log(tf.square(scale)) + tf.cast(tf.log(deg_free), settings.float_type)\n               + np.log(np.pi))\n    const = tf.cast(const, settings.float_type)\n    return const - 0.5*(deg_free + 1.) * \\\n        tf.log(1. + (1. / deg_free) * (tf.square((x - mean) / scale)))\n\n\ndef beta(alpha, beta, y):\n    # need to clip y, since log of 0 is nan...\n    y = tf.clip_by_value(y, 1e-6, 1-1e-6)\n    return (alpha - 1.) * tf.log(y) + (beta - 1.) * tf.log(1. - y) \\\n        + tf.lgamma(alpha + beta)\\\n        - tf.lgamma(alpha)\\\n        - tf.lgamma(beta)\n\n\ndef laplace(mu, sigma, y):\n    return - tf.abs(mu - y) / sigma - tf.log(2. * sigma)\n\n\ndef multivariate_normal(x, mu, L):\n    \"\"\"\n    L is the Cholesky decomposition of the covariance.\n\n    x and mu are either vectors (ndim=1) or matrices. In the matrix case, we\n    assume independence over the *columns*: the number of rows must match the\n    size of L.\n    \"\"\"\n    d = x - mu\n    alpha = tf.matrix_triangular_solve(L, d, lower=True)\n    num_col = 1 if tf.rank(x) == 1 else tf.shape(x)[1]\n    num_col = tf.cast(num_col, settings.float_type)\n    num_dims = tf.cast(tf.shape(x)[0], settings.float_type)\n    ret = - 0.5 * num_dims * num_col * np.log(2 * np.pi)\n    ret += - num_col * tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))\n    ret += - 0.5 * tf.reduce_sum(tf.square(alpha))\n    return ret\n", "path": "gpflow/densities.py"}], "after_files": [{"content": "# Copyright 2016 James Hensman, Valentine Svensson, alexggmatthews, fujiisoup\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nfrom __future__ import absolute_import\nimport tensorflow as tf\n\nfrom .. import likelihoods\nfrom .. import settings\n\nfrom ..params import DataHolder\nfrom ..decors import params_as_tensors\nfrom ..decors import name_scope\nfrom ..densities import multivariate_normal\n\nfrom .model import GPModel\n\n\nclass GPR(GPModel):\n    \"\"\"\n    Gaussian Process Regression.\n\n    This is a vanilla implementation of GP regression with a Gaussian\n    likelihood.  Multiple columns of Y are treated independently.\n\n    The log likelihood i this models is sometimes referred to as the 'marginal log likelihood', and is given by\n\n    .. math::\n\n       \\\\log p(\\\\mathbf y \\\\,|\\\\, \\\\mathbf f) = \\\\mathcal N\\\\left(\\\\mathbf y\\,|\\, 0, \\\\mathbf K + \\\\sigma_n \\\\mathbf I\\\\right)\n    \"\"\"\n    def __init__(self, X, Y, kern, mean_function=None, **kwargs):\n        \"\"\"\n        X is a data matrix, size N x D\n        Y is a data matrix, size N x R\n        kern, mean_function are appropriate GPflow objects\n        \"\"\"\n        likelihood = likelihoods.Gaussian()\n        X = DataHolder(X)\n        Y = DataHolder(Y)\n        GPModel.__init__(self, X, Y, kern, likelihood, mean_function, **kwargs)\n\n    @name_scope('likelihood')\n    @params_as_tensors\n    def _build_likelihood(self):\n        \"\"\"\n        Construct a tensorflow function to compute the likelihood.\n\n            \\log p(Y | theta).\n\n        \"\"\"\n        K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance\n        L = tf.cholesky(K)\n        m = self.mean_function(self.X)\n        logpdf = multivariate_normal(self.Y, m, L)  # (R,) log-likelihoods for each independent dimension of Y\n\n        return tf.reduce_sum(logpdf)\n\n    @name_scope('predict')\n    @params_as_tensors\n    def _build_predict(self, Xnew, full_cov=False):\n        \"\"\"\n        Xnew is a data matrix, point at which we want to predict\n\n        This method computes\n\n            p(F* | Y )\n\n        where F* are points on the GP at Xnew, Y are noisy observations at X.\n\n        \"\"\"\n        Kx = self.kern.K(self.X, Xnew)\n        K = self.kern.K(self.X) + tf.eye(tf.shape(self.X)[0], dtype=settings.float_type) * self.likelihood.variance\n        L = tf.cholesky(K)\n        A = tf.matrix_triangular_solve(L, Kx, lower=True)\n        V = tf.matrix_triangular_solve(L, self.Y - self.mean_function(self.X))\n        fmean = tf.matmul(A, V, transpose_a=True) + self.mean_function(Xnew)\n        if full_cov:\n            fvar = self.kern.K(Xnew) - tf.matmul(A, A, transpose_a=True)\n            shape = tf.stack([1, 1, tf.shape(self.Y)[1]])\n            fvar = tf.tile(tf.expand_dims(fvar, 2), shape)\n        else:\n            fvar = self.kern.Kdiag(Xnew) - tf.reduce_sum(tf.square(A), 0)\n            fvar = tf.tile(tf.reshape(fvar, (-1, 1)), [1, tf.shape(self.Y)[1]])\n        return fmean, fvar\n", "path": "gpflow/models/gpr.py"}, {"content": "# Copyright 2016 James Hensman, alexggmatthews\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\nimport tensorflow as tf\nimport numpy as np\n\n\nfrom . import settings\n\n\ndef gaussian(x, mu, var):\n    return -0.5 * (np.log(2 * np.pi) + tf.log(var) + tf.square(mu-x)/var)\n\n\ndef lognormal(x, mu, var):\n    lnx = tf.log(x)\n    return gaussian(lnx, mu, var) - lnx\n\n\ndef bernoulli(p, y):\n    return tf.log(tf.where(tf.equal(y, 1), p, 1-p))\n\n\ndef poisson(lamb, y):\n    return y * tf.log(lamb) - lamb - tf.lgamma(y + 1.)\n\n\ndef exponential(lamb, y):\n    return - y/lamb - tf.log(lamb)\n\n\ndef gamma(shape, scale, x):\n    return -shape * tf.log(scale) - tf.lgamma(shape)\\\n        + (shape - 1.) * tf.log(x) - x / scale\n\n\ndef student_t(x, mean, scale, deg_free):\n    const = tf.lgamma(tf.cast((deg_free + 1.) * 0.5, settings.float_type))\\\n        - tf.lgamma(tf.cast(deg_free * 0.5, settings.float_type))\\\n        - 0.5*(tf.log(tf.square(scale)) + tf.cast(tf.log(deg_free), settings.float_type)\n               + np.log(np.pi))\n    const = tf.cast(const, settings.float_type)\n    return const - 0.5*(deg_free + 1.) * \\\n        tf.log(1. + (1. / deg_free) * (tf.square((x - mean) / scale)))\n\n\ndef beta(alpha, beta, y):\n    # need to clip y, since log of 0 is nan...\n    y = tf.clip_by_value(y, 1e-6, 1-1e-6)\n    return (alpha - 1.) * tf.log(y) + (beta - 1.) * tf.log(1. - y) \\\n        + tf.lgamma(alpha + beta)\\\n        - tf.lgamma(alpha)\\\n        - tf.lgamma(beta)\n\n\ndef laplace(mu, sigma, y):\n    return - tf.abs(mu - y) / sigma - tf.log(2. * sigma)\n\n\ndef multivariate_normal(x, mu, L):\n    \"\"\"\n    Computes the log-density of a multivariate normal.\n    :param x  : D or DxN sample(s) for which we want the density\n    :param mu : D or DxN mean(s) of the normal distribution\n    :param L  : DxD Cholesky decomposition of the covariance matrix\n    :return p : N vector of log densities for each of the N x's and/or mu's\n\n    x and mu are either vectors or matrices. If both are vectors ((N,) or (N,1)):\n    p[0] = log pdf(x) where x ~ N(mu, LL^T)\n    If at least one is a matrix, we assume independence over the *columns*:\n    the number of rows must match the size of L. Broadcasting behaviour:\n    p[n] = log pdf of:\n    x[n] ~ N(mu, LL^T) or x ~ N(mu[n], LL^T) or x[n] ~ N(mu[n], LL^T)\n    \"\"\"\n    x  = tf.cond(tf.rank(x)  < 2, lambda: x[:, None],  lambda: x)\n    mu = tf.cond(tf.rank(mu) < 2, lambda: mu[:, None], lambda: mu)\n    d = x - mu\n    alpha = tf.matrix_triangular_solve(L, d, lower=True)\n    num_dims = tf.cast(tf.shape(d)[0], L.dtype)\n    p = - 0.5 * tf.reduce_sum(tf.square(alpha), 0)\n    p -= 0.5 * num_dims * np.log(2 * np.pi)\n    p -= tf.reduce_sum(tf.log(tf.matrix_diag_part(L)))\n    return p\n", "path": "gpflow/densities.py"}]}