Example #1
0
def v2dcosine_transform(f, s1, s2, args=(), m=20, ng=20, shanks_ind=None):
    """Cosine transform of f(x, y) at transform variable s1, s2

    Vectorised 2d cosine transform.

    Parameters
    ----------
    f : function or method
        Function to apply 2D cosine trasnform to.  f is called with
        f(x, y, *args).
    s1, s2 : 1d array
        Transformation variables. A grid of points will be made.
    args : tuple, optional
        Arguments to pass to f.
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the cos function, default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration. Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        default=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        value of transform at s

    Notes
    -----
    Careful with singularities.  Because there is no way to increase the
    integration points at a particular sport the infinite behaviur may not be
    captured well. For example x**-0.5 should transform to sqrt(pi/2*w) but
    due to the sinularity at x=0 it does not converge well even using ng=100.



    """

    #dims of array:
    # 0 or i dim is each of the 1st transform coordinate s1
    # 1 or j dim is each integration inteval corresponding to s1, a1, b1
    # 2 or k dim is each gauss point in interval a1, b1
    # 3 or l dim is each of the 2nd transform coordinate s2
    # 4 or m dim is each integration interval corresponding to s2, a2, b2
    # 5 or n dim is each gauss point in interval a2, b2

    # 5 dim will be summed to get integral of each interval a2, b2
    # 4 dim will be summed to get shanks'ed to give transform at each s2 coord
    # 2 dim will be summed to get integral of each interval a1, b1
    # 1 dim will be summed to get shanks'ed to give transform at each s1 coord


    si = np.atleast_1d(s1)
    sl = np.atleast_1d(s2)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)
    xn_, wn = xk_, wk

    # integration intervals
    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = (2 * np.arange(m) + 1) * np.pi/2

    aj = am = zeros[0:-1]
    bj = bm = zeros[1:]

    si = si[:, None, None, None, None, None]

    aj = aj[None, :, None, None, None, None]
    bj = bj[None, :, None, None, None, None]

    xk_ = xk_[None, None, :, None, None, None]
    wk = wk[None, None, :, None, None, None]

    aij = aj / si
    bij = bj / si

    bmaij = (bij - aij) / 2 # b minus a
    bpaij = (aij + bij) /2 # b plus a


    sl = sl[ None, None, None, :, None, None]
    am = am[None, None, None, None, :, None]
    bm = bm[None, None, None, None, :, None]

    xn_ = xn_[None, None, None, None, None, :]
    wn = wn[None, None, None, None, None, :]

    alm = am / sl
    blm = bm / sl

    bmalm = (blm - alm) / 2 # b minus a
    bpalm = (alm + blm) /2 # b plus a


    xijk = bmaij * xk_ + bpaij # xj_ are in [-1, 1] so need to transform to [a, b]

    xlmn = bmalm * xn_ + bpalm

    fijklmn=f(xijk, xlmn, *args)
    fijklmn*=np.cos(si*xijk)
    fijklmn*=np.cos(sl*xlmn)

    fijklmn*=wk
    fijklmn*=wn

    fijklmn*=bmaij#[:,:,0,:,:,:]
    fijklmn*=bmalm#[:,:,:,:,:,0]

    igral = np.sum(fijklmn, axis=5)

    if shanks_ind is None:
        igral = igral.sum(axis=4)
    else:
        #extrapolate
        igral.cumsum(axis=4 , out=igral)
        igral= np.apply_along_axis(shanks, 4, igral, shanks_ind)

    igral = np.sum(igral, axis=2)

    if shanks_ind is None:
        igral = igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1 , out=igral)
        igral= np.apply_along_axis(shanks, 1, igral, shanks_ind)

    return igral
Example #2
0
def vcosine_transform(f, s, args=(), m=20, ng=20, shanks_ind=None):
    """Cosine transform of f(x) at transform variable s

    This is a vectorized cosine transform.

    Parameters
    ----------
    f : function or method
        Function to apply cosine trasnform to.  f is called with
        f(x, *args).
    s : 1d array
        Coordinate(s) to evaluate transform at.
    args : tuple, optional
        arguments to pass to f
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the cos function, Default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration., Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        Default shanks_ind=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        Value of transform at s

    Notes
    -----
    Careful with singularities.  Because there is no way to increase the
    integration points at a particular spot the infinite behaviur may not be
    captured well. For example x**-0.5 should transform to sqrt(pi/2*w) but
    due to the sinularity at x=0 it does not converge well even using ng=100.



    """


    si = np.atleast_1d(s)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)

    # integration intervals

    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = (2 * np.arange(m) + 1) * np.pi/2

    aj = zeros[0:-1]
    bj = zeros[1:]

    #dims of array:
    # 0 or i dim is each transform coordinate
    # 1 or j dim is each integration interval
    # 2 or k dim is each integration point

    # 2 dim will be summed to get integral of each interval
    # 1 dim will be summed or shanks'ed to give transform at each coord
    #

    si = si[:, np.newaxis, np.newaxis]

    aj = aj[np.newaxis, :, np.newaxis]
    bj = bj[np.newaxis, :, np.newaxis]

    xk_ = xk_[np.newaxis, np.newaxis, :]

    wk = wk[np.newaxis, np.newaxis, :]


    aij = aj / si
    bij = bj / si

    bma = (bij - aij) / 2 # b minus a
    bpa = (aij + bij) /2 # b plus a


    xijk = bma * xk_ + bpa # xj_ are in [-1, 1] so need to transform to [a, b]

    fijk = f(xijk, *args)
    fijk *= np.cos(si * xijk)
#    fijk *= xijk

    igral = bma[:,:,0] * np.sum(fijk * wk, axis=2)



    if shanks_ind is None:
        return igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1 , out=igral)
        return shanks(igral, shanks_ind)
Example #3
0
def vhankel_transform(f, r, args=(), order=0, m=20, ng=20, shanks_ind=None):
    """Hankel transform of f(r)

    This is a vectorised Hankel transform

    Parameters
    ----------
    f : function or method
        Function to apply hankel trasnform to.  f is called with
        f(s, *args).
    r : 1d array
        Coordinate(s) to evaluate transform at.
    args : tuple, optional
        Arguments to pass to f, default args=().
    order : integer, optional
        Order of hankel transform. Default order=0.
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the bessel function.
        Default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration. Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        Default shanks_ind=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        Value of transform at r.

    Notes
    -----
    The Hankel Transform of order :math:`\\nu` is given by:

    .. math:: F_\\nu(s)=\mathcal{H}_\\nu\\{f(r)\\} =
                \\int_0^{\\infty}rf(r)J_\\nu(sr)\\,\\mathrm{d}r

    Provided :math:`\\nu\\gt1/2` the inverse hankel transform is the same as
    the normal transform:

    .. math:: f(r)=\mathcal{H}_{\\nu}^{-1}\\{F_{\\nu}(s)\\} =
                \\int_0^{\\infty}sF_\\nu(s)J_\\nu(sr)\\,\\mathrm{d}s


    Note that because this implementation does not allow for input of
    extra point to break up the integration inteval, there is no way to
    account for singularities and other oscillations.  If you need this control
    then see the HankelTransform class which is not vectorized but provides a
    few more options.


    See Also
    --------
    HankelTransform : Non vectorised Hankel transform.


    References
    ----------
    .. [1] Piessens, Robert. 2000. 'Chapter 9 The Hankel Transform'. In The
           Transforms and Applications Handbook, edited by Alexander
           D. Poularikas, 2nd edition. Boca Raton, USA: CRC Press.


    """


    ri = np.atleast_1d(r)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)

    # integration intervals
    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = jn_zeros(order, m)

    aj = zeros[0:-1]
    bj = zeros[1:]


    ri = ri[:, np.newaxis, np.newaxis]

    aj = aj[np.newaxis, :, np.newaxis]
    bj = bj[np.newaxis, :, np.newaxis]

    xk_ = xk_[np.newaxis, np.newaxis, :]

    wk = wk[np.newaxis, np.newaxis, :]


    aij = aj / ri
    bij = bj / ri

    bma = (bij - aij) / 2 # b minus a
    bpa = (aij + bij) /2 # b plus a


    xijk = bma * xk_ + bpa # xj_ are in [-1, 1] so need to transform to [a, b]

    fijk = f(xijk, *args)
    fijk *= jn(order, ri * xijk)
    fijk *= xijk

    igral = bma[:,:,0] * np.sum(fijk * wk, axis=2)



    if shanks_ind is None:
        return igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1 , out=igral)
        return shanks(igral, shanks_ind)
Example #4
0
def v2dcosine_transform(f, s1, s2, args=(), m=20, ng=20, shanks_ind=None):
    """Cosine transform of f(x, y) at transform variable s1, s2

    Vectorised 2d cosine transform.

    Parameters
    ----------
    f : function or method
        Function to apply 2D cosine trasnform to.  f is called with
        f(x, y, *args).
    s1, s2 : 1d array
        Transformation variables. A grid of points will be made.
    args : tuple, optional
        Arguments to pass to f.
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the cos function, default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration. Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        default=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        value of transform at s

    Notes
    -----
    Careful with singularities.  Because there is no way to increase the
    integration points at a particular sport the infinite behaviur may not be
    captured well. For example x**-0.5 should transform to sqrt(pi/2*w) but
    due to the sinularity at x=0 it does not converge well even using ng=100.



    """

    #dims of array:
    # 0 or i dim is each of the 1st transform coordinate s1
    # 1 or j dim is each integration inteval corresponding to s1, a1, b1
    # 2 or k dim is each gauss point in interval a1, b1
    # 3 or l dim is each of the 2nd transform coordinate s2
    # 4 or m dim is each integration interval corresponding to s2, a2, b2
    # 5 or n dim is each gauss point in interval a2, b2

    # 5 dim will be summed to get integral of each interval a2, b2
    # 4 dim will be summed to get shanks'ed to give transform at each s2 coord
    # 2 dim will be summed to get integral of each interval a1, b1
    # 1 dim will be summed to get shanks'ed to give transform at each s1 coord

    si = np.atleast_1d(s1)
    sl = np.atleast_1d(s2)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)
    xn_, wn = xk_, wk

    # integration intervals
    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = (2 * np.arange(m) + 1) * np.pi / 2

    aj = am = zeros[0:-1]
    bj = bm = zeros[1:]

    si = si[:, None, None, None, None, None]

    aj = aj[None, :, None, None, None, None]
    bj = bj[None, :, None, None, None, None]

    xk_ = xk_[None, None, :, None, None, None]
    wk = wk[None, None, :, None, None, None]

    aij = aj / si
    bij = bj / si

    bmaij = (bij - aij) / 2  # b minus a
    bpaij = (aij + bij) / 2  # b plus a

    sl = sl[None, None, None, :, None, None]
    am = am[None, None, None, None, :, None]
    bm = bm[None, None, None, None, :, None]

    xn_ = xn_[None, None, None, None, None, :]
    wn = wn[None, None, None, None, None, :]

    alm = am / sl
    blm = bm / sl

    bmalm = (blm - alm) / 2  # b minus a
    bpalm = (alm + blm) / 2  # b plus a

    xijk = bmaij * xk_ + bpaij  # xj_ are in [-1, 1] so need to transform to [a, b]

    xlmn = bmalm * xn_ + bpalm

    fijklmn = f(xijk, xlmn, *args)
    fijklmn *= np.cos(si * xijk)
    fijklmn *= np.cos(sl * xlmn)

    fijklmn *= wk
    fijklmn *= wn

    fijklmn *= bmaij  #[:,:,0,:,:,:]
    fijklmn *= bmalm  #[:,:,:,:,:,0]

    igral = np.sum(fijklmn, axis=5)

    if shanks_ind is None:
        igral = igral.sum(axis=4)
    else:
        #extrapolate
        igral.cumsum(axis=4, out=igral)
        igral = np.apply_along_axis(shanks, 4, igral, shanks_ind)

    igral = np.sum(igral, axis=2)

    if shanks_ind is None:
        igral = igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1, out=igral)
        igral = np.apply_along_axis(shanks, 1, igral, shanks_ind)

    return igral
Example #5
0
def vcosine_transform(f, s, args=(), m=20, ng=20, shanks_ind=None):
    """Cosine transform of f(x) at transform variable s

    This is a vectorized cosine transform.

    Parameters
    ----------
    f : function or method
        Function to apply cosine trasnform to.  f is called with
        f(x, *args).
    s : 1d array
        Coordinate(s) to evaluate transform at.
    args : tuple, optional
        arguments to pass to f
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the cos function, Default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration., Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        Default shanks_ind=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        Value of transform at s

    Notes
    -----
    Careful with singularities.  Because there is no way to increase the
    integration points at a particular spot the infinite behaviur may not be
    captured well. For example x**-0.5 should transform to sqrt(pi/2*w) but
    due to the sinularity at x=0 it does not converge well even using ng=100.



    """

    si = np.atleast_1d(s)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)

    # integration intervals

    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = (2 * np.arange(m) + 1) * np.pi / 2

    aj = zeros[0:-1]
    bj = zeros[1:]

    #dims of array:
    # 0 or i dim is each transform coordinate
    # 1 or j dim is each integration interval
    # 2 or k dim is each integration point

    # 2 dim will be summed to get integral of each interval
    # 1 dim will be summed or shanks'ed to give transform at each coord
    #

    si = si[:, np.newaxis, np.newaxis]

    aj = aj[np.newaxis, :, np.newaxis]
    bj = bj[np.newaxis, :, np.newaxis]

    xk_ = xk_[np.newaxis, np.newaxis, :]

    wk = wk[np.newaxis, np.newaxis, :]

    aij = aj / si
    bij = bj / si

    bma = (bij - aij) / 2  # b minus a
    bpa = (aij + bij) / 2  # b plus a

    xijk = bma * xk_ + bpa  # xj_ are in [-1, 1] so need to transform to [a, b]

    fijk = f(xijk, *args)
    fijk *= np.cos(si * xijk)
    #    fijk *= xijk

    igral = bma[:, :, 0] * np.sum(fijk * wk, axis=2)

    if shanks_ind is None:
        return igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1, out=igral)
        return shanks(igral, shanks_ind)
Example #6
0
def vhankel_transform(f, r, args=(), order=0, m=20, ng=20, shanks_ind=None):
    """Hankel transform of f(r)

    This is a vectorised Hankel transform

    Parameters
    ----------
    f : function or method
        Function to apply hankel trasnform to.  f is called with
        f(s, *args).
    r : 1d array
        Coordinate(s) to evaluate transform at.
    args : tuple, optional
        Arguments to pass to f, default args=().
    order : integer, optional
        Order of hankel transform. Default order=0.
    m : int, optional
        Number of segments to break the integration interval into.  Each
        segment will be between the zeros of the bessel function.
        Default m=20.
    ng : [2-20, 32, 64, 100], optional
        Number of gauss points to use in integration. Default ng=20.
    shanks_ind : int, optional
        Start position of intervals to start shanks extrapolation.
        Default shanks_ind=None i.e. no extrapolation.
        Be careful when using shanks extrapolation; make sure you only begin
        to use it after the intgrand is well behaved.

    Returns
    -------
    f : 1d array of float
        Value of transform at r.

    Notes
    -----
    The Hankel Transform of order :math:`\\nu` is given by:

    .. math:: F_\\nu(s)=\mathcal{H}_\\nu\\{f(r)\\} =
                \\int_0^{\\infty}rf(r)J_\\nu(sr)\\,\\mathrm{d}r

    Provided :math:`\\nu\\gt1/2` the inverse hankel transform is the same as
    the normal transform:

    .. math:: f(r)=\mathcal{H}_{\\nu}^{-1}\\{F_{\\nu}(s)\\} =
                \\int_0^{\\infty}sF_\\nu(s)J_\\nu(sr)\\,\\mathrm{d}s


    Note that because this implementation does not allow for input of
    extra point to break up the integration inteval, there is no way to
    account for singularities and other oscillations.  If you need this control
    then see the HankelTransform class which is not vectorized but provides a
    few more options.


    See Also
    --------
    HankelTransform : Non vectorised Hankel transform.


    References
    ----------
    .. [1] Piessens, Robert. 2000. 'Chapter 9 The Hankel Transform'. In The
           Transforms and Applications Handbook, edited by Alexander
           D. Poularikas, 2nd edition. Boca Raton, USA: CRC Press.


    """

    ri = np.atleast_1d(r)

    xk_, wk = gauss_legendre_abscissae_and_weights(ng)

    # integration intervals
    zeros = np.zeros(m + 1, dtype=float)
    zeros[1:] = jn_zeros(order, m)

    aj = zeros[0:-1]
    bj = zeros[1:]

    ri = ri[:, np.newaxis, np.newaxis]

    aj = aj[np.newaxis, :, np.newaxis]
    bj = bj[np.newaxis, :, np.newaxis]

    xk_ = xk_[np.newaxis, np.newaxis, :]

    wk = wk[np.newaxis, np.newaxis, :]

    aij = aj / ri
    bij = bj / ri

    bma = (bij - aij) / 2  # b minus a
    bpa = (aij + bij) / 2  # b plus a

    xijk = bma * xk_ + bpa  # xj_ are in [-1, 1] so need to transform to [a, b]

    fijk = f(xijk, *args)
    fijk *= jn(order, ri * xijk)
    fijk *= xijk

    igral = bma[:, :, 0] * np.sum(fijk * wk, axis=2)

    if shanks_ind is None:
        return igral.sum(axis=1)
    else:
        #extrapolate
        igral.cumsum(axis=1, out=igral)
        return shanks(igral, shanks_ind)