Example #1
0
 def test_cos(self):
     """tests if the cos function works"""
     a = (simplearray.array(10).fill_arange()+1)/100      
     b = cumath.cos(a)
     
     for i in range(10):
         self.assert_(abs(math.cos(a[i]) - b[i]) < 1e-2)         
def amplitude_compute_gpu(vector, atom_factors, frame):
    f_a_real = 0
    f_a_imag = 0
    f_frame = []
    f_factor = []
    for atom in frame:
        f_frame.append([atom[1], atom[2], atom[3]])
        for factors in atom_factors:
            if factors[0] == atom[4]:
                f_factor.append(factors[1])
    n_vector = numpy.asarray(vector)
    n_frame = numpy.asarray(f_frame)
    for i in range(0, len(n_frame)):
        gpu_vector = gpuarray.to_gpu(n_vector)
        gpu_frame = gpuarray.to_gpu(n_frame[i])
        gpu_result = gpuarray.dot(gpu_vector, gpu_frame)
        gpu_sin = gpumath.sin(gpu_result)
        gpu_cos = gpumath.cos(gpu_result)
        f_q = f_factor[i]
        f_a_real += f_q * gpu_cos
        f_a_imag += f_q * gpu_sin
    return f_a_real, f_a_imag
Example #3
0
def cuda_field(ab, krv, cartesian=True, bohren=True):
    '''Returns the field scattered by the particle at each coordinate

    Parameters
    ----------
    ab : numpy.ndarray
        Mie scattering coefficients
    krv : numpy.ndarray
        Reduced vector displacements of particle from image coordinates
    cartesian : bool
        If set, return field projected onto Cartesian coordinates.
        Otherwise, return polar projection.
    bohren : bool
        If set, use sign convention from Bohren and Huffman.
        Otherwise, use opposite sign convention.

    Returns
    -------
    field : numpy.ndarray
        [3, npts] array of complex vector values of the
        scattered field at each coordinate.
    '''

    nc = ab.shape[0]  # number of partial waves in sum

    # GEOMETRY
    # 1. particle displacement [pixel]
    # Note: The sign convention used here is appropriate
    # for illumination propagating in the -z direction.
    # This means that a particle forming an image in the
    # focal plane (z = 0) is located at positive z.
    # Accounting for this by flipping the axial coordinate
    # is equivalent to using a mirrored (left-handed)
    # coordinate system.
    kx = gpuarray.to_gpu(krv[:, 0]).astype(np.float32)
    ky = gpuarray.to_gpu(krv[:, 1]).astype(np.float32)
    kz = gpuarray.to_gpu(-krv[:, 2]).astype(np.float32)
    npts = len(kx)

    # 2. geometric factors
    krho = cumath.sqrt(kx * kx + ky * ky)
    cosphi = kx / krho
    sinphi = ky / krho

    kr = cumath.sqrt(krho * krho + kz * kz)
    costheta = kz / kr
    sintheta = krho / kr

    sinkr = cumath.sin(kr)
    coskr = cumath.cos(kr)

    # SPECIAL FUNCTIONS
    # starting points for recursive function evaluation ...
    # 1. Riccati-Bessel radial functions, page 478.
    # Particles above the focal plane create diverging waves
    # described by Eq. (4.13) for $h_n^{(1)}(kr)$. These have z > 0.
    # Those below the focal plane appear to be converging from the
    # perspective of the camera. They are descrinbed by Eq. (4.14)
    # for $h_n^{(2)}(kr)$, and have z < 0. We can select the
    # appropriate case by applying the correct sign of the imaginary
    # part of the starting functions...
    factor = 1.j * kz / abs(kz)
    if not bohren:
        factor *= -1.
    xi_nm2 = coskr + factor * sinkr  # \xi_{-1}(kr)
    xi_nm1 = sinkr - factor * coskr  # \xi_0(kr)

    # 2. Angular functions (4.47), page 95
    pi_nm1 = 0.  # \pi_0(\cos\theta)
    pi_n = 1.  # \pi_1(\cos\theta)

    # 3. Vector spherical harmonics: [r,theta,phi]
    mo1n = gpuarray.zeros([3, npts], dtype=np.complex64)
    ne1n = gpuarray.empty([3, npts], dtype=np.complex64)

    # storage for scattered field
    es = gpuarray.zeros([3, npts], dtype=np.complex64)

    # COMPUTE field by summing partial waves
    for n in range(1, nc):
        # upward recurrences ...
        # 4. Legendre factor (4.47)
        # Method described by Wiscombe (1980)
        swisc = pi_n * costheta
        twisc = swisc - pi_nm1
        tau_n = pi_nm1 - n * twisc  # -\tau_n(\cos\theta)

        # ... Riccati-Bessel function, page 478
        xi_n = (2. * n - 1.) * (xi_nm1 / kr) - xi_nm2  # \xi_n(kr)

        # ... Deirmendjian's derivative
        dn = (n * xi_n) / kr - xi_nm1

        # vector spherical harmonics (4.50)
        # mo1n[0, :] = 0.j           # no radial component
        mo1n[1, :] = pi_n * xi_n  # ... divided by cosphi/kr
        mo1n[2, :] = tau_n * xi_n  # ... divided by sinphi/kr

        # ... divided by cosphi sintheta/kr^2
        ne1n[0, :] = n * (n + 1.) * pi_n * xi_n
        ne1n[1, :] = tau_n * dn  # ... divided by cosphi/kr
        ne1n[2, :] = pi_n * dn  # ... divided by sinphi/kr

        # prefactor, page 93
        en = 1.j**n * (2. * n + 1.) / n / (n + 1.)

        # the scattered field in spherical coordinates (4.45)
        es += np.complex64(1.j * en * ab[n, 0]) * ne1n
        es -= np.complex64(en * ab[n, 1]) * mo1n

        # upward recurrences ...
        # ... angular functions (4.47)
        # Method described by Wiscombe (1980)
        pi_nm1 = pi_n
        pi_n = swisc + ((n + 1.) / n) * twisc

        # ... Riccati-Bessel function
        xi_nm2 = xi_nm1
        xi_nm1 = xi_n
    # n: multipole sum

    # geometric factors were divided out of the vector
    # spherical harmonics for accuracy and efficiency ...
    # ... put them back at the end.
    radialfactor = 1. / kr
    es[0, :] *= cosphi * sintheta * radialfactor**2
    es[1, :] *= cosphi * radialfactor
    es[2, :] *= sinphi * radialfactor

    # By default, the scattered wave is returned in spherical
    # coordinates.  Project components onto Cartesian coordinates.
    # Assumes that the incident wave propagates along z and
    # is linearly polarized along x
    if cartesian:
        ec = gpuarray.empty_like(es)

        ec[0, :] = es[0, :] * sintheta * cosphi
        ec[0, :] += es[1, :] * costheta * cosphi
        ec[0, :] -= es[2, :] * sinphi

        ec[1, :] = es[0, :] * sintheta * sinphi
        ec[1, :] += es[1, :] * costheta * sinphi
        ec[1, :] += es[2, :] * cosphi

        ec[2, :] = es[0, :] * costheta - es[1, :] * sintheta
        return ec.get()
    else:
        return es.get()
def random_normal(loc=0.0, scale=1.0, size=None):
    u1 = curandom.rand(size, dtype=numpy.float64)
    u2 = curandom.rand(size, dtype=numpy.float64)
    z1 = cumath.sqrt(-2.*cumath.log(u1))*cumath.cos(2.*numpy.pi*u2)
    return CUDAArray(scale*z1+loc)