'Efficient matrix-vector multiply with the BFGS matrices.
This calculation is described in Section (4) of [1].
Parameters
x : ndarray
An array with shape (n,) or (n,1).
Returns
y : ndarray
The matrix-vector product'

def _matvec(self, x):

    (s, y, n_corrs, rho) = (self.sk, self.yk, self.n_corrs, self.rho)
    q = np.array(x, dtype=self.dtype, copy=True)
    if ((q.ndim == 2) and (q.shape[1] == 1)):
        q = q.reshape((-1))
    alpha = np.zeros(n_corrs)
    for i in range((n_corrs - 1), (-1), (-1)):
        alpha[i] = (rho[i] * np.dot(s[i], q))
        q = (q - (alpha[i] * y[i]))
    r = q
    for i in range(n_corrs):
        beta = (rho[i] * np.dot(y[i], r))
        r = (r + (s[i] * (alpha[i] - beta)))
    return r
