Accelerate AffinityPropagation.

Accelerate AffinityPropagation for large inputs using standard tricks (in-place operations and out parameters) to avoid extra allocations.

Basic tests (see below, not in the PR) on datasets for 1000 points in 2D show ~10-20% increase in
speed.

```
import numpy as np
from sklearn.cluster import AffinityPropagation

N = 100
M = 5
np.random.seed(0)
data = np.concatenate(
    [np.random.random((N, 2)) + i for i in range(M)] +
    [np.random.random((N * M, 2)) * M])
print(AffinityPropagation().fit_predict(data))
```
This is still using memory copy right? What about using the following instead?

```python
np.maximum(tmp, 0, out=tmp)
```