lenstronomy.LensModel.Profiles.numerical_deflections — lenstronomy 1.8.2 documentation

# Source code for lenstronomy.LensModel.Profiles.numerical_deflections

    __author__ = 'dgilman'

    # this file contains a class to compute lensing quantities with a pre-computed grid of deflection angles, up to
    # a normalization factor. The user passes in a pointer to this pre-computed grid, and the lensing funcitons
    # interpolate it to compute deflection angles and the hessian

    import numpy as np
    from lenstronomy.LensModel.Profiles.base_profile import LensProfileBase

    __all__ = ['NumericalAlpha']

    class NumericalAlpha(LensProfileBase):

        def __init__(self, custom_class):

            """
            :param custom_class: a user-defined class that contains the following attributes

            1) custom_class.deflections: a numpy array of length N; stores pre-computed deflection angles
            2) custom_class.params: numpy array shape (N,P), where P is the number of parameters

            custom_class should also contain a call method:

            custom_class(x, y, **args)
            - converts an (x,y) coordinate, and the specific function arguments, into a deflection angle

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

            Example: For a cored cNFW profile

            class CustomClass(object):

                def __init__(self, deflection_array, x_nfw, beta)

                    self.deflections = deflection_array
                    self.params = np.column_stack((x_nfw, beta))
                    self.param_names = ['x', 'beta']

                def __call__(x, y, Rs, r_core, norm):

                    R = np.sqrt(x ** 2 + y ** 2)

                    X = R * Rs ** -1
                    beta = r_core * Rs ** -1

                    defangle = interpolate(X, beta)

                    return norm*defangle

                def interpolate(x_nfw, beta):
                    The user should code up a way to interpolate between values
                    return ~some interpolating function(x_nfw, beta)~

            %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
            Note: This returns an *** un-normalized deflection angle ***
            It is up to the user to rescale the results according to whatever normalization is appropriate

            """

            self._interp = custom_class
            super(NumericalAlpha, self).__init__()

        def function(self, x, y,center_x = 0, center_y = 0, **kwargs):

            raise Exception('no potential for this class.')

        def derivatives(self, x, y, center_x=0, center_y=0, **kwargs):

            """
            returns df/dx and df/dy (un-normalized!!!) interpolated from the numerical deflection table
            """

            assert 'norm' in kwargs.keys(), "key word arguments must contain 'norm', " \
                                            "the normalization of deflection angle in units of arcsec."

            x_ = x - center_x
            y_ = y - center_y
            f_x, f_y = self._interp(x_, y_, **kwargs)

            return f_x, f_y

        def hessian(self, x, y, center_x=0, center_y=0, **kwargs):
            """
            returns Hessian matrix of function d^2f/dx^2, d^2/dxdy, d^2/dydx, d^f/dy^2
            (un-normalized!!!) interpolated from the numerical deflection table
            """

            diff = 1e-6
            alpha_ra, alpha_dec = self.derivatives(x, y, center_x=center_x, center_y=center_y, **kwargs)

            alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, center_x=center_x, center_y=center_y, **kwargs)
            alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, center_x=center_x, center_y=center_y, **kwargs)

            dalpha_rara = (alpha_ra_dx - alpha_ra) / diff
            dalpha_radec = (alpha_ra_dy - alpha_ra) / diff
            dalpha_decra = (alpha_dec_dx - alpha_dec) / diff
            dalpha_decdec = (alpha_dec_dy - alpha_dec) / diff

            f_xx = dalpha_rara
            f_yy = dalpha_decdec
            f_xy = dalpha_radec
            f_yx = dalpha_decra

            return f_xx, f_xy, f_yx, f_yy