gzhong's picture
Upload folder using huggingface_hub
7718235 verified
import math
import numpy as np
from sklearn.gaussian_process.kernels import Hyperparameter
from skopt.learning.gaussian_process.kernels import Matern
from model import _delta_hamiltonian
class EVMaternKernel(Matern):
"""Representation: int vector of sequence len."""
def __init__(self, couplings_model, **kwargs):
super().__init__(**kwargs)
self.couplings_model = couplings_model
self.J = couplings_model.J_ij
self.h = couplings_model.h_i
@property
def hyperparameter_length_scale(self):
return Hyperparameter(
"length_scale", "numeric", "fixed")
def seq2rep(self, seqs):
reps = np.zeros((len(seqs), len(seqs[0])), dtype=int)
for i, s in enumerate(seqs):
reps[i] = [self.couplings_model.alphabet_map[x] for x in s]
return reps
def dist(self, X, Y):
dists = np.zeros((X.shape[0], Y.shape[0]))
for i in range(X.shape[0]):
for j in range(Y.shape[0]):
pos = []
subs = []
for l in range(X.shape[1]):
if X[i, l] != Y[j, l]:
pos.append(l)
subs.append(Y[j, l])
dists[i, j] += np.abs(
self.h[l, X[i, l]] - self.h[l, Y[j, l]])
return dists
def __call__(self, X, Y=None, eval_gradient=False):
"""Return the kernel k(X, Y) and optionally its gradient.
Parameters
----------
X : ndarray of shape (n_samples_X, n_features)
Left argument of the returned kernel k(X, Y)
Y : ndarray of shape (n_samples_Y, n_features), default=None
Right argument of the returned kernel k(X, Y). If None, k(X, X)
if evaluated instead.
eval_gradient : bool, default=False
Determines whether the gradient with respect to the log of
the kernel hyperparameter is computed.
Only supported when Y is None.
Returns
-------
K : ndarray of shape (n_samples_X, n_samples_Y)
Kernel k(X, Y)
K_gradient : ndarray of shape (n_samples_X, n_samples_X, n_dims), \
optional
The gradient of the kernel k(X, X) with respect to the log of the
hyperparameter of the kernel. Only returned when `eval_gradient`
is True.
"""
X = np.atleast_2d(X)
if Y is None:
dists = self.dist(X, X)
else:
dists = self.dist(X, Y)
if eval_gradient:
raise ValueError(
"Gradient can only be evaluated when Y is None.")
dists /= self.length_scale ** 2
if self.nu == 0.5:
K = np.exp(-dists)
elif self.nu == 1.5:
K = dists * math.sqrt(3)
K = (1. + K) * np.exp(-K)
elif self.nu == 2.5:
K = dists * math.sqrt(5)
K = (1. + K + K ** 2 / 3.0) * np.exp(-K)
elif self.nu == np.inf:
K = np.exp(-dists ** 2 / 2.0)
else: # general case; expensive to evaluate
K = dists
K[K == 0.0] += np.finfo(float).eps # strict zeros result in nan
tmp = (math.sqrt(2 * self.nu) * K)
K.fill((2 ** (1. - self.nu)) / gamma(self.nu))
K *= tmp ** self.nu
K *= kv(self.nu, tmp)
if eval_gradient:
if self.hyperparameter_length_scale.fixed:
# Hyperparameter l kept fixed
K_gradient = np.empty((X.shape[0], X.shape[0], 0))
return K, K_gradient
else:
raise NotImplementedError
else:
return K
def gradient_x(self, x, X_train):
raise NotImplementedError