def search_step(f, x_k, alf, p_k):
    """
    This function performs an optimization step given a step length and step direction

    INPUTS:
        f < function > : objective function f(x) -> f
        x_k < tensor > : current best guess for f(x) minimum
        alf < float > : step length
        p_k < tensor > : step direction

    OUTPUTS:
        x_(k+1) < tensor > : new best guess for f(x) minimum
        f_(k+1) < tensor > : function evaluated at new best guess
    """
    x_k1 = x_k + alf*p_k
    f_k1 = f(x_k1)
    return x_k1, f_k1