Update function for a particle.

    Calculates and updates the velocity and position of a particle for a
    single iteration of the PSO algorithm. Social best particle is determined
    by the state.params['topology'] function.

    Args:
        state: cipy.algorithms.pso.State: The state of the PSO algorithm.
        nbest_topology: dict: Containing neighbourhood best index for each
            particle index.
        idx_particle: tuple: Tuple of the index of the particle and the
            particle itself.

    Returns:
        cipy.algorithms.pso.Particle: A new particle with the updated position
        and velocity.

def update_particle(position_update, velocity_update, state, nbest_topology,
                    idx_particle):
    """ Update function for a particle.

    Calculates and updates the velocity and position of a particle for a
    single iteration of the PSO algorithm. Social best particle is determined
    by the state.params['topology'] function.

    Args:
        state: cipy.algorithms.pso.State: The state of the PSO algorithm.
        nbest_topology: dict: Containing neighbourhood best index for each
            particle index.
        idx_particle: tuple: Tuple of the index of the particle and the
            particle itself.

    Returns:
        cipy.algorithms.pso.Particle: A new particle with the updated position
        and velocity.

    """
    (idx, particle) = idx_particle

    nbest = state.swarm[nbest_topology[idx]].best_position

    velocity = velocity_update(particle, nbest, state)
    position = position_update(particle.position, velocity)
    return particle._replace(position=position, velocity=velocity)