def encode_and_deriv(self, x):
    ls_mat = np.atleast_2d(np.diag((1 / self.length_scale)))
    scaled_x = (x @ ls_mat)
    fdata = np.exp(((1j * self.phase_matrix) @ scaled_x.T))
    data = np.fft.ifft(fdata, axis=0).real
    ddata = np.fft.ifft((((1j * np.stack([np.diag(fdata[:, j]) for j in range(x.shape[0])])) @ self.phase_matrix) @ ls_mat), axis=0).real
    return (data.T, ddata.T)
def encode_and_deriv(self, x):
    ls_mat = np.atleast_2d(np.diag((1 / self.length_scale)))
    scaled_x = (x @ ls_mat)
    fdata = np.exp(((1j * self.phase_matrix) @ scaled_x.T))
    data = np.fft.ifft(fdata, axis=0).real
    ddata = np.fft.ifft((((1j * np.stack([np.diag(fdata[:, j]) for j in range(x.shape[0])])) @ self.phase_matrix) @ ls_mat), axis=0).real
    return (data.T, ddata.T)