def test_hermevander(self): # check for 1d x x = np.arange(3) v = herme.hermevander(x, 3) assert_(v.shape == (3, 4)) for i in range(4): coef = [0] * i + [1] assert_almost_equal(v[..., i], herme.hermeval(x, coef)) # check for 2d x x = np.array([[1, 2], [3, 4], [5, 6]]) v = herme.hermevander(x, 3) assert_(v.shape == (3, 2, 4)) for i in range(4): coef = [0] * i + [1] assert_almost_equal(v[..., i], herme.hermeval(x, coef))
def test_hermevander(self) : # check for 1d x x = np.arange(3) v = herme.hermevander(x, 3) assert_(v.shape == (3,4)) for i in range(4) : coef = [0]*i + [1] assert_almost_equal(v[...,i], herme.hermeval(x, coef)) # check for 2d x x = np.array([[1,2],[3,4],[5,6]]) v = herme.hermevander(x, 3) assert_(v.shape == (3,2,4)) for i in range(4) : coef = [0]*i + [1] assert_almost_equal(v[...,i], herme.hermeval(x, coef))
def test_100(self): x, w = herme.hermegauss(100) # test orthogonality. Note that the results need to be normalized, # otherwise the huge values that can arise from fast growing # functions like Laguerre can be very confusing. v = herme.hermevander(x, 99) vv = np.dot(v.T * w, v) vd = 1 / np.sqrt(vv.diagonal()) vv = vd[:, None] * vv * vd assert_almost_equal(vv, np.eye(100)) # check that the integral of 1 is correct tgt = np.sqrt(2 * np.pi) assert_almost_equal(w.sum(), tgt)
def test_100(self): x, w = herme.hermegauss(100) # test orthogonality. Note that the results need to be normalized, # otherwise the huge values that can arise from fast growing # functions like Laguerre can be very confusing. v = herme.hermevander(x, 99) vv = np.dot(v.T * w, v) vd = 1/np.sqrt(vv.diagonal()) vv = vd[:,None] * vv * vd assert_almost_equal(vv, np.eye(100)) # check that the integral of 1 is correct tgt = np.sqrt(2*np.pi) assert_almost_equal(w.sum(), tgt)
def calc_pgh(ispec, wavelengths, psfparams): ''' Calculate the pixelated Gauss Hermite for all wavelengths of a single spectrum ispec : integer spectrum number wavelengths : array of wavelengths to evaluate psfparams : dictionary of PSF parameters returned by evalcoeffs returns pGHx, pGHy where pGHx[ghdeg+1, nwave, nbinsx] contains the pixel-integrated Gauss-Hermite polynomial for all degrees at all wavelengths across nbinsx bins spaning the PSF spot, and similarly for pGHy. The core PSF will then be evaluated as PSFcore = sum_ij c_ij outer(pGHy[j], pGHx[i]) ''' #- shorthand p = psfparams #- spot size (ny,nx) nx = p['HSIZEX'] ny = p['HSIZEY'] nwave = len(wavelengths) # print('Spot size (ny,nx) = {},{}'.format(ny, nx)) # print('nwave = {}'.format(nwave)) #- x and y edges of bins that span the center of the PSF spot xedges = np.repeat(np.arange(nx + 1) - nx // 2, nwave).reshape(nx + 1, nwave) yedges = np.repeat(np.arange(ny + 1) - ny // 2, nwave).reshape(ny + 1, nwave) #- Shift to be relative to the PSF center at 0 and normalize #- by the PSF sigma (GHSIGX, GHSIGY) #- xedges[nx+1, nwave] #- yedges[ny+1, nwave] xedges = ((xedges - p['X'][ispec] % 1) / p['GHSIGX'][ispec]) yedges = ((yedges - p['Y'][ispec] % 1) / p['GHSIGY'][ispec]) # print('xedges.shape = {}'.format(xedges.shape)) # print('yedges.shape = {}'.format(yedges.shape)) #- Degree of the Gauss-Hermite polynomials ghdegx = p['GHDEGX'] ghdegy = p['GHDEGY'] #- Evaluate the Hermite polynomials at the pixel edges #- HVx[ghdegx+1, nwave, nx+1] #- HVy[ghdegy+1, nwave, ny+1] HVx = He.hermevander(xedges, ghdegx).T HVy = He.hermevander(yedges, ghdegy).T # print('HVx.shape = {}'.format(HVx.shape)) # print('HVy.shape = {}'.format(HVy.shape)) #- Evaluate the Gaussians at the pixel edges #- Gx[nwave, nx+1] #- Gy[nwave, ny+1] Gx = np.exp(-0.5 * xedges**2).T / np.sqrt(2. * np.pi) # (nwave, nedges) Gy = np.exp(-0.5 * yedges**2).T / np.sqrt(2. * np.pi) # print('Gx.shape = {}'.format(Gx.shape)) # print('Gy.shape = {}'.format(Gy.shape)) #- Combine into Gauss*Hermite GHx = HVx * Gx GHy = HVy * Gy #- Integrate over the pixels using the relationship # Integral{ H_k(x) exp(-0.5 x^2) dx} = -H_{k-1}(x) exp(-0.5 x^2) + const #- pGHx[ghdegx+1, nwave, nx] #- pGHy[ghdegy+1, nwave, ny] pGHx = np.zeros((ghdegx + 1, nwave, nx)) pGHy = np.zeros((ghdegy + 1, nwave, ny)) pGHx[0] = 0.5 * np.diff(scipy.special.erf(xedges / np.sqrt(2.)).T) pGHy[0] = 0.5 * np.diff(scipy.special.erf(yedges / np.sqrt(2.)).T) pGHx[1:] = GHx[:ghdegx, :, 0:nx] - GHx[:ghdegx, :, 1:nx + 1] pGHy[1:] = GHy[:ghdegy, :, 0:ny] - GHy[:ghdegy, :, 1:ny + 1] # print('pGHx.shape = {}'.format(pGHx.shape)) # print('pGHy.shape = {}'.format(pGHy.shape)) return pGHx, pGHy