menpo/menpo — pull request #301 by jabooth (2014-05-03 19:36:29+00:00)
Title: as_vector() always a non-writable view on data

In the past we have run into performance issues (#207) with the behaviour of `as_vector()` being a copy of the data vectorized. Whilst this did keep us fairly safe from bugs, we need to address the memory issues that arise from making expensive copies all the time.

This PR solves this issue by making all `as_vector()` vectors views (non-copies of the data).

This change is a little worrying as if a user was to make a change to the vectorized version of the data this would change the original data

```python
v = pointcloud.as_vector() # v is a view on pointcloud.points
... # v passed around a little
v += 1 # whoops! 1 added to every (X, Y, Z) value in pointcloud
```

to prevent this, we now set the [WRITEABLE flag](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.flags.html) on the vector we return to you to be false..

```python
v = pointcloud.as_vector() # v is non-WRITEABLE view on pointcloud.points
... # v passed around a little
v += 1 # raises ValueError - can't change WRITEABLE=False numpy arrays!
```

how should you manipulate `v` if that's what you want?

```python
v = pointcloud.as_vector().copy() # a 'safe' vector, go nuts
```

note that the fact that v is a view works both ways - **if you only hold onto an as_vector() of an object and it changes, the vector will change from under you**

```python
v = pointcloud.as_vector() # v is non-WRITEABLE view on pointcloud.points
... # v passed around a little
pointcloud.points += 1 # v changes and we can't really defend against this
```

because of this, care should be taken when using the vectorized interface. If in doubt, stick a `.copy()` on the end.