def Gram_matrix(self, F, F1, F2, lower, upper):
assert self.input_dim == <NUM_LIT:1><EOL>def L(x, i):<EOL><INDENT>return(<NUM_LIT> / self.lengthscale ** <NUM_LIT:2> * F[i](x) + <NUM_LIT:2> * np.sqrt(<NUM_LIT:3>) / self.lengthscale * F1[i](x) + F2[i](x))<EOL><DEDENT>n = F.shape[<NUM_LIT:0>]<EOL>G = np.zeros((n, n))<EOL>for i in range(n):<EOL><INDENT>for j in range(i, n):<EOL><INDENT>G[i, j] = G[j, i] = integrate.quad(lambda x : L(x, i) * L(x, j), lower, upper)[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>Flower = np.array([f(lower) for f in F])[:, None]<EOL>F1lower = np.array([f(lower) for f in F1])[:, None]<EOL>return(self.lengthscale ** <NUM_LIT:3> / (<NUM_LIT>*np.sqrt(<NUM_LIT:3>) * self.variance) * G + <NUM_LIT:1.> / self.variance * np.dot(Flower, Flower.T) + self.lengthscale ** <NUM_LIT:2> / (<NUM_LIT>*self.variance) * np.dot(F1lower, F1lower.T))<EOL>
Return the Gram matrix of the vector of functions F with respect to the
RKHS norm. The use of this function is limited to input_dim=1.

:param F: vector of functions
:type F: np.array
:param F1: vector of derivatives of F
:type F1: np.array
:param F2: vector of second derivatives of F
:type F2: np.array
:param lower,upper: boundaries of the input domain
:type lower,upper: floats