예제 #1
0
 def prepL(self, maxL):
     if maxL not in self.lDict:
         latglq, longlq = psh.GLQGridCoord(maxL)
         thetaglq = latToTheta(latglq)
         phiglq = lonToPhi(longlq)
         nodes, weights = psh.SHGLQ(maxL)
         self.lDict[maxL] = (thetaglq, phiglq, nodes, weights)
     return self.lDict[maxL]
예제 #2
0
def prep_transforms(edgeLen, maxL, rMax):
    """
    Build harmonics tables.  This is expected to be called once per block.
    """
    fullChain = prep_chain(edgeLen, maxL, rMax)
    lDict = {}
    for _, _, l in fullChain:
        nodes, weights = psh.SHGLQ(l)
        lDict[l] = (nodes, weights)
    #print('##### Completed prep_rotations')
    return fullChain, lDict
예제 #3
0
def TimingAccuracyGLQC():
    # ---- input parameters ----
    maxdeg = 2800
    ls = np.arange(maxdeg + 1)
    beta = 1.5
    print('Gauss-Legendre quadrature (complex)')

    # ---- create mask to filter out m<=l ----
    mask = np.zeros((2, maxdeg + 1, maxdeg + 1), dtype=np.bool)
    mask[0, 0, 0] = True
    for l in ls:
        mask[:, l, :l + 1] = True
    mask[1, :, 0] = False

    # ---- create Gaussian powerlaw coefficients ----
    print('creating {:d} random coefficients'.format(2 * (maxdeg + 1) *
                                                     (maxdeg + 1)))
    cilm = np.zeros((2, maxdeg + 1, maxdeg + 1), dtype=np.complex)
    cilm.imag = np.random.normal(loc=0.,
                                 scale=1.,
                                 size=(2, maxdeg + 1, maxdeg + 1))
    cilm.real = np.random.normal(loc=0.,
                                 scale=1.,
                                 size=(2, maxdeg + 1, maxdeg + 1))

    old_power = shtools.SHPowerSpectrumC(cilm)
    new_power = 1. / (1. + ls)**beta  # initialize degrees > 0 to power-law
    cilm[:, :, :] *= np.sqrt(new_power / old_power)[None, :, None]
    cilm[~mask] = 0.

    # ---- time spherical harmonics transform for lmax set to increasing
    # ---- powers of 2 ----
    lmax = 2
    print('lmax    maxerror    rms        tprecompute    tinverse    tforward')
    while lmax <= maxdeg:
        # trim coefficients to lmax
        cilm_trim = cilm[:, :lmax + 1, :lmax + 1]
        mask_trim = mask[:, :lmax + 1, :lmax + 1]

        # precompute grid nodes and associated Legendre functions
        tstart = time.time()
        zeros, weights = shtools.SHGLQ(lmax)
        tend = time.time()
        tprecompute = tend - tstart

        # synthesis / inverse
        tstart = time.time()
        grid = shtools.MakeGridGLQC(cilm_trim, zeros)
        tend = time.time()
        tinverse = tend - tstart

        # analysis / forward
        tstart = time.time()
        cilm2_trim = shtools.SHExpandGLQC(grid, weights, zeros)
        tend = time.time()
        tforward = tend - tstart

        # compute error
        err = np.abs(cilm_trim[mask_trim] - cilm2_trim[mask_trim]) / \
            np.abs(cilm_trim[mask_trim])
        maxerr = err.max()
        rmserr = np.mean(err**2)

        print('{:4d}    {:1.2e}    {:1.2e}    {:1.1e}s       {:1.1e}s    '
              '{:1.1e}s'.format(lmax, maxerr, rmserr, tprecompute, tinverse,
                                tforward))
        lmax = lmax * 2
예제 #4
0
def ylms_to_samples(ylms, layer_list, n_chan):
    """
    Given a subrange of ylms, transform to images on the sphere
    
    input:
      images: dimensions (batch_sz, N_BALL_SAMPS, n_chan)
      layer_list: python list of integer layer numbers
      n_chan: number of channels in the input
    
    returns:
      rslt: dimensions (blk_sz, hrm_samps, n_chan)
        where hrm_samps is the sum over layer_list of (2 * (l+1) * (l+1))
    """
    edge_len = 2 * RAD_PIXELS + 1
    r_max = 0.5 * float(edge_len + 1)
    full_chain = prep_chain(edge_len, MAX_L, r_max)
    l_dict = {}
    for _, _, l in full_chain:
        nodes, weights = psh.SHGLQ(l)
        l_dict[l] = (nodes, weights)
    tot_hrm_sz = 0
    for l in layer_list:
        tot_hrm_sz += np.prod(hrm_dims_from_l(l))
    #print('tot_hrm_sz:', tot_hrm_sz)
    #print('keys: ', l_dict.keys())

    def this_op(ylms):
        #print('ylms shape: ', ylms.shape)
        assert n_chan == ylms.shape[-1], 'Got the wrong number of channels'
        batch_sz, hrm_blk_sz = ylms.shape[:-1]
        rslt = np.zeros((batch_sz, N_BALL_SAMPS, n_chan))
        for idx_batch in range(batch_sz):
            samp_offset = 0
            hrm_offset = 0
            for _, _, l in full_chain:
                samp_dim1, samp_dim2 = dims_from_l(l)
                samp_blk_sz = samp_dim1 * samp_dim2
                if l in layer_list:
                    hrm_dim1, hrm_dim2, hrm_dim3 = hrm_dims_from_l(l)
                    hrm_blk_sz = hrm_dim1 * hrm_dim2 * hrm_dim3
                    #print('hrm_blk_sz:', hrm_blk_sz)
                    for idx_chan in range(n_chan):
                        hrm_blk = ylms[idx_batch,
                                       hrm_offset:hrm_offset + hrm_blk_sz,
                                       idx_chan]
                        nodes, weights = l_dict[l]
                        samp_blk = psh.MakeGridGLQ(
                            tf.reshape(hrm_blk,
                                       [hrm_dim1, hrm_dim2, hrm_dim3]), nodes)
                        #print('samp_blk shape: ', samp_blk.shape)
                        rslt[idx_batch, samp_offset:samp_offset + samp_blk_sz,
                             idx_chan] = samp_blk.flat
                    hrm_offset += hrm_blk_sz
                samp_offset += samp_blk_sz
        return rslt

    rslt = tf.py_function(this_op, [ylms],
                          dtypes.float32,
                          name="ylms_to_samples")
    #with tf.control_dependencies([tf.print('rslt: ', rslt)]):
    rslt = tf.reshape(rslt, [-1, N_BALL_SAMPS, n_chan])
    return rslt
예제 #5
0
def samples_to_ylms(images, layer_list, n_chan):
    """
    Given a collection of samples on the sphere, transform the layers specified
    by layer_list to Ylms.  Note that layer_list is specifying the radii to be
    transformed.  All l values within those layers are included in the output Ylms.
    
    input:
      images: dimensions (batch_sz, N_BALL_SAMPS, n_chan)
      layer_list: python list of integer layer numbers
      n_chan: number of channels in the input
    
    returns:
      rslt: dimensions (blk_sz, hrm_samps, n_chan)
        where hrm_samps is the sum over layer_list of (2 * (l+1) * (l+1))
    """
    edge_len = 2 * RAD_PIXELS + 1
    r_max = 0.5 * float(edge_len + 1)
    full_chain = prep_chain(edge_len, MAX_L, r_max)
    l_dict = {}
    for _, _, l in full_chain:
        nodes, weights = psh.SHGLQ(l)
        l_dict[l] = (nodes, weights)
    tot_hrm_sz = 0
    for l in layer_list:
        tot_hrm_sz += np.prod(hrm_dims_from_l(l))
    #print('tot_hrm_sz:', tot_hrm_sz)
    #print('keys: ', l_dict.keys())

    def this_op(images):
        print('images shape: ', images.shape)
        assert n_chan == images.shape[-1], 'Got the wrong number of channels'
        batch_sz, blk_sz = images.shape[:-1]
        rslt = np.zeros((batch_sz, tot_hrm_sz, n_chan))
        for idx_batch in range(batch_sz):
            samp_offset = 0
            hrm_offset = 0
            for _, _, l in full_chain:
                samp_dim1, samp_dim2 = dims_from_l(l)
                samp_blk_sz = samp_dim1 * samp_dim2
                if l in layer_list:
                    hrm_blk_sz = np.prod(hrm_dims_from_l(l))
                    #print('hrm_blk_sz:', hrm_blk_sz)
                    for idx_chan in range(n_chan):
                        samp_blk = images[idx_batch, samp_offset:samp_offset +
                                          samp_blk_sz, idx_chan]
                        nodes, weights = l_dict[l]
                        hrm_blk = psh.SHExpandGLQ(
                            tf.reshape(samp_blk, [samp_dim1, samp_dim2]),
                            weights, nodes)
                        #print('hrm_blk shape: ', hrm_blk.shape)

                        rslt[idx_batch, hrm_offset:hrm_offset + hrm_blk_sz,
                             idx_chan] = hrm_blk.flat
                    hrm_offset += hrm_blk_sz
                samp_offset += samp_blk_sz
        return rslt

    rslt = tf.py_function(this_op, [images],
                          dtypes.float32,
                          name="samples_to_ylms")
    #with tf.control_dependencies([tf.print('rslt: ', rslt)]):
    rslt = tf.reshape(rslt, [-1, tot_hrm_sz, n_chan])
    return rslt