def parallelNelderMeadWorker(objFunc,simplex,f_vals,j,P,opt_params):
    '''
    A worker process for the parallel Nelder-Mead algorithm.  Updates one point
    in the simplex, returning its function value as well.  Should basically
    never be called directly, only by parallelNelderMead().

    Parameters
    ----------
    objFunc : function
        The function to be minimized; takes a single 1D array as input.
    simplex : numpy.array
        The current simplex for minimization; simplex[k,:] is an input for objFunc.
    f_vals : numpy.array
        The values of the objective function at each point of the simplex:
        f_vals[k] = objFunc(simplex[k,:])
    j : int
        Index of the point in the simplex to update: simplex[j,:]
    P : int
        Degree of parallelization of the algorithm.
    opt_params : numpy.array
        Three element array with parameters for reflection, contraction, expansion.

    Returns
    -------
    new_point : numpy.array
        An updated point for the simplex; might be the same as simplex[j,:].
    new_val : float
        The value of the objective function at the new point: objFunc(new_point).
    evals : int
        Number of evaluations of objFunc by this worker.
    '''
    # Unpack the input parameters
    alpha = opt_params[0] # reflection parameter
    beta = opt_params[1] # contraction parameter
    gamma = opt_params[2] # expansion parameter
    my_point = simplex[j,:] # vertex to update
    my_val = f_vals[j] # value at the vertex to update
    best_val = f_vals[0] # best value in the vertex
    next_val = f_vals[j-1] # next best point in the simplex
    evals = 0

    # Calculate the centroid of the "good" simplex points
    N = simplex.shape[0] # number of points in simplex
    centroid = np.mean(simplex[0:(N-P),:],axis=0)

    # Calculate the reflection point and its function value
    r_point = centroid + alpha*(centroid - my_point)
    r_val = objFunc(r_point)
    evals += 1

    # Case 1: the reflection point is better than best point
    if r_val < best_val:
        e_point = r_point + gamma*(r_point - centroid)
        e_val = objFunc(e_point) # Calculate expansion point
        evals += 1
        if e_val < r_val:
            new_point = e_point
            new_val = e_val
        else:
            new_point = r_point
            new_val = r_val
    # Case 2: the reflection point is better than the next best point
    elif r_val < next_val:
        new_point = r_point # Report reflection point
        new_val = r_val
    # Case 3: the reflection point is worse than the next best point
    else:
        if r_val < my_val:
            temp_point = r_point # Check whether reflection or original point
            temp_val = r_val     # is better and use it temporarily
        else:
            temp_point = my_point
            temp_val = my_val
        c_point = beta*(centroid + temp_point)
        c_val = objFunc(c_point) # Calculate contraction point
        evals += 1
        if c_val < temp_val:
            new_point = c_point
            new_val = c_val   # Check whether the contraction point is better
        else:
            new_point = temp_point
            new_val = temp_val

    # Return the outputs
    return new_point, new_val, evals