2

I would like to improve the speed of my code by computing a function once on a numpy array instead of a for loop is over a function of this python library. If I have a function as following:

import numpy as np
import galsim
from math import *
M200=1e14
conc=6.9
def func(M200, conc):
    halo_z=0.2
    halo_pos =[1200., 3769.7]
    halo_pos = galsim.PositionD(x=halo_pos_arcsec[0],y=halo_pos_arcsec[1])
    nfw      = galsim.NFWHalo(mass=M200, conc=conc, redshift=halo_z,halo_pos=halo_pos, omega_m = 0.3, omega_lam =0.7)
    for i in range(len(shear_z)):
       shear_pos=galsim.PositionD(x=pos_arcsec[i,0],y=pos_arcsec[i,1])
       model_g1, model_g2  = nfw.getShear(pos=self.shear_pos, z_s=shear_z[i])
    l=np.sum(model_g1-model_g2)/sqrt(np.pi)
    return l

While pos_arcsec is a two-dimensional array of 24000x2 and shear_z is a 1D array with 24000 elements as well. The main problem is that I want to calculate this function on a grid where M200=np.arange(13., 16., 0.01) and conc = np.arange(3, 10, 0.01). I don't know how to broadcast this function to be estimated for this two dimensional array over M200 and conc. It takes a lot to run the code. I am looking for the best approaches to speed up these calculations.

6
  • What do you mean by 'broadcast this function'? Commented May 9, 2015 at 14:17
  • How would it look like with a for loop? I assume 0 and 1 are the variable ones. Commented May 9, 2015 at 14:33
  • What's the for-loop iterating through? Share the for-loop code? Commented May 9, 2015 at 15:32
  • @Tichodroma I explained why I needed broadcasting in the new update! Commented May 9, 2015 at 15:54
  • @PascalvKooten that is my original problem!! Commented May 9, 2015 at 16:12

2 Answers 2

2

This here should work when pos is an array of shape (n,2)

import numpy as np

def f(pos, z):
    r=np.sqrt(pos[...,0]**2+pos[...,1]**2)
    return np.log(r)*(z+1)

Example:

z = np.arange(10)
pos = np.arange(20).reshape(10,2)

f(pos,z)
# array([  0.        ,   2.56494936,   5.5703581 ,   8.88530251,
#         12.44183436,  16.1944881 ,  20.11171117,  24.17053133,
#         28.35353608,  32.64709419])
Sign up to request clarification or add additional context in comments.

Comments

2

Use numpy.linalg.norm

If you have an array:

import numpy as np
import numpy.linalg as la

a = np.array([[3, 4], [5, 12], [7, 24]])

then you can determine the magnitude of the resulting vector (sqrt(a^2 + b^2)) by

b = np.sqrt(la.norm(a, axis=1)

>>> print b
array([  5.,  15.  25.])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.