<p dir="ltr">Thanks! I am traveling right now so will look at this as soon as I am back, but this looks promising. Much appreciated.<br>
</p>
<br><div class="gmail_quote">On Fri, 30 Jan 2015 15:40 Glynn Clements <<a href="mailto:glynn@gclements.plus.com">glynn@gclements.plus.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Paulo van Breugel wrote:<br>
<br>
> I would like to compute a raster layer with for each raster cell the<br>
> mahalanobis distance to the centre of the environmental space formed by all<br>
> reference data points (raster cells). In R this can be done as explained<br>
> here [1].<br>
><br>
> . I would like to do this using python only (no dependency on R). I came up<br>
> with the following, which works, but is very slow. I guess this is because<br>
> it loops over every raster cell to compute the mahalanobis distance? Any<br>
> idea how this can be done faster (I am very new to python, so bear with me<br>
> if I am making stupid mistakes)<br>
<br>
The main speed-up will come from "inlining" distance.mahalanobis(),<br>
which is essentially:<br>
<br>
    delta = u - v<br>
    m = np.dot(np.dot(delta, VI), delta)<br>
    return np.sqrt(m)<br>
<br>
np.dot(v, m) is equivalent to np.sum(v * m,axis=0), and np.dot(u,v) is<br>
equivalent to np.sum(u * v), so the second line above is equivalent to<br>
<br>
    m = np.sum(np.sum(delta[:,None] * VI * delta[None,:], axis=-1), axis=-1)<br>
<br>
Thus, delta can be extended from a 1-D array to 3-D, changing the<br>
result from a scalar to a 2-D array. The calculation of stat_mah then<br>
becomes:<br>
<br>
    VI = np.linalg.inv(covar)<br>
    delta = dat_ref - stat_mean[:,None,None]<br>
    m = np.sum(np.sum(delta[:,:,:,<u></u>None] * delta[:,:,None,:] * VI[None,None,:,:],axis=-1),<u></u>axis=-1)<br>
    stat_mah = np.sqrt(m)<br>
<br>
This moves the loops from Python into C, which usually results in a<br>
significant speed increase.<br>
<br>
--<br>
Glynn Clements <<a href="mailto:glynn@gclements.plus.com" target="_blank">glynn@gclements.plus.com</a>><br>
</blockquote></div>