Ejemplo n.º 1
0
def _o(x0, m, n):
    """Overlap function between |nx> = m and |nx'> = n under translation in the x
       direction with the amplitude x0.

       Keeping the name indecently short, as this function should not be called
       from outside the module.

    Args:
        x0: translation amplitude.

        m, n: principal quantum numbers for harmonic oscillator states
              to compute overlap between. Note that only the relevant numbers
              (i.e. the ones in x direction without spin) are considered.

    Returns:
        The overlap amplitude, which is always real.
"""
    x0_ = x0 / np.sqrt(2)
    ax02 = abs(x0_)**2
    if m >= n:
        L = genlaguerre(n, m - n)
        return (sqrt(1 / rising_factorial(n + 1, m - n)) * (x0_**(m - n)) *
                exp(-ax02 / 2) * L(ax02))
    else:
        L = genlaguerre(m, n - m)
        return (sqrt(1 / rising_factorial(m + 1, n - m)) * ((-x0_)**(n - m)) *
                exp(-ax02 / 2) * L(ax02))
Ejemplo n.º 2
0
def genlaguerre_array( size ):
    height = size
    width = size
    ret = [ [ 0 for a in range(width) ] for n in range(height) ]
    for a in range(width):
        ret[0][a] = genlaguerre(0,a)
        ret[1][a] = genlaguerre(1,a)
        for n in range(2,height):
            ret[n][a] = ((2*(n-1)+a+1-poly1d([1,0]))*ret[n-1][a] - \
                             (n-1+a)*ret[n-2][a] ) /n
    return ret
Ejemplo n.º 3
0
def derivTy(z, y, x, t):
    r_w_z_2_1 = (y**2 + x**2) / w1(z)**2
    r_w_z_2_2 = ((z + pos(t))**2 + y**2) / w2(x)**2
    lag_1 = eval_genlaguerre(p, l, 2 * r_w_z_2_1)
    lag_2 = eval_genlaguerre(p, l, 2 * r_w_z_2_2)

    return (w0 / w1(z))**2 * (2 * r_w_z_2_1)**(l - 1) * np.exp(
        -2 * r_w_z_2_1) * lag_1 * (4 * y / w1(z)**2) * (
            (l - 2 * r_w_z_2_1) * lag_1 + 4 * r_w_z_2_1 *
            np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2_1)
        ) + (w0 / w2(x))**2 * (2 * r_w_z_2_2)**(l - 1) * np.exp(
            -2 * r_w_z_2_2) * lag_2 * (4 * y / w2(x)**2) * (
                (l - 2 * r_w_z_2_2) * lag_2 + 4 * r_w_z_2_2 *
                np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2_2))
Ejemplo n.º 4
0
def derivTz(z, y, x, t):
    r_w_z_2_1 = (y**2 + x**2) / w1(z)**2
    r_w_z_2_2 = ((z + pos(t))**2 + y**2) / w2(x)**2
    lag_1 = eval_genlaguerre(p, l, 2 * r_w_z_2_1)
    lag_2 = eval_genlaguerre(p, l, 2 * r_w_z_2_2)

    return np.exp(-2 * r_w_z_2_1) * lag_1 * 2 * (
        2 * r_w_z_2_1)**l * la1**2 * z / np.pi**2 / w1(z)**4 * (
            (-(1 + l) + 2 * r_w_z_2_1) * lag_1 - 4 * r_w_z_2_1 *
            np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2_1)
        ) + (w0 / w2(x))**2 * (2 * r_w_z_2_2)**(l - 1) * np.exp(
            -2 * r_w_z_2_2) * lag_2 * (4 * (z + pos(t)) / w2(x)**2) * (
                (l - 2 * r_w_z_2_2) * lag_2 + 4 * r_w_z_2_2 *
                np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2_2))
Ejemplo n.º 5
0
def _wigner_laguerre(rho, xvec, yvec, g, parallel):
    """
    Using Laguerre polynomials from scipy to evaluate the Wigner function for
    the density matrices :math:`|m><n|`, :math:`W_{mn}`. The total Wigner
    function is calculated as :math:`W = \sum_{mn} \\rho_{mn} W_{mn}`.
    """

    M = np.prod(rho.shape[0])
    X, Y = meshgrid(xvec, yvec)
    A = 0.5 * g * (X + 1.0j * Y)
    W = zeros(np.shape(A))

    # compute wigner functions for density matrices |m><n| and
    # weight by all the elements in the density matrix
    B = 4 * abs(A) ** 2
    if sp.isspmatrix_csr(rho.data):
        # for compress sparse row matrices
        if parallel:
            iterator = (
                (m, rho, A, B) for m in range(len(rho.data.indptr) - 1))
            W1_out = parfor(_par_wig_eval, iterator)
            W += sum(W1_out)
        else:
            for m in range(len(rho.data.indptr) - 1):
                for jj in range(rho.data.indptr[m], rho.data.indptr[m + 1]):
                    n = rho.data.indices[jj]

                    if m == n:
                        W += real(rho[m, m] * (-1) ** m * genlaguerre(m, 0)(B))

                    elif n > m:
                        W += 2.0 * real(rho[m, n] * (-1) ** m *
                                        (2 * A) ** (n - m) *
                                        sqrt(factorial(m) / factorial(n)) *
                                        genlaguerre(m, n - m)(B))
    else:
        # for dense density matrices
        B = 4 * abs(A) ** 2
        for m in range(M):
            if abs(rho[m, m]) > 0.0:
                W += real(rho[m, m] * (-1) ** m * genlaguerre(m, 0)(B))
            for n in range(m + 1, M):
                if abs(rho[m, n]) > 0.0:
                    W += 2.0 * real(rho[m, n] * (-1) ** m *
                                    (2 * A) ** (n - m) *
                                    sqrt(factorial(m) / factorial(n)) *
                                    genlaguerre(m, n - m)(B))

    return 0.5 * W * g ** 2 * np.exp(-B / 2) / pi
Ejemplo n.º 6
0
def GaussLaguerre(p, l, A, w0, Fin):
    """
    Fout = GaussLaguerre(p, l, A, w0, Fin)

    :ref:`Substitutes a Laguerre-Gauss mode (beam waist) in the field. <GaussLaguerre>`

        :math:`F_{p,l}(x,y,z=0) = A \\left(\\frac{\\rho}{2}\\right)^{\\frac{|l|}{2} }L^p_l\\left(\\rho\\right)e^{-\\frac{\\rho}{2}}\\cos(l\\theta)`,
        
        with :math:`\\rho=\\frac{2(x^2+y^2)}{w_0^2}`

    Args::
        
        p, l: mode indices
        A: Amplitude
        w0: Guaussian spot size parameter in the beam waist (1/e amplitude point)
        Fin: input field
        
    Returns::
    
        Fout: output field (N x N square array of complex numbers).            
        
    Reference::
    
        A. Siegman, "Lasers", p. 642

    """

    Fout = Field.copy(Fin)
    R, Phi = Fout.mgrid_polar
    w02 = w0 * w0
    la = abs(l)
    rho = 2 * R * R / w02
    Fout.field = A * rho**(la / 2) * genlaguerre(p, la)(rho) * _np.exp(
        -rho / 2) * _np.cos(l * Phi)
    return Fout
Ejemplo n.º 7
0
def polar_shapelets_refregier(N, M, beta):

    """
    Return callable function for normalized generalized Laguerre polynomials with separated 
    exp(-1j*M*phi) to Cos (M>0) and Sin (M<0) and ordinary radial part for M == 0
    """
    coeff_1, coeff_2, coeff_3 = coeff(N, M, beta)
    gen_laguerre = special.genlaguerre(n=(N-np.abs(M))/2, alpha=np.abs(M))
    
    if (M > 0):
        laguer_N_M = lambda x, phi: coeff_1 * coeff_2 \
                * x**(np.abs(M)) \
                * gen_laguerre(x**2/beta**2) \
                * np.exp(-x**2/2./beta**2) \
                * coeff_3 * np.cos(M*phi) 
    elif (M < 0):
        laguer_N_M = lambda x, phi: coeff_1 * coeff_2 \
                * x**(np.abs(M)) \
                * gen_laguerre(x**2/beta**2) \
                * np.exp(-x**2/2./beta**2) \
                * coeff_3 * np.sin(M*phi)
    elif (M == 0):
        laguer_N_M = lambda x, phi: coeff_1 * coeff_2 \
                * x**(np.abs(M)) \
                * gen_laguerre(x**2/beta**2) \
                * np.exp(-x**2/2./beta**2)
    
    return laguer_N_M
Ejemplo n.º 8
0
 def lambda_gen():
     return lambda r: (np.sqrt(
         (2 * Z_ind * A / (n * au))**3 * factorial(n - l - 1) /
         (2 * n * factorial(n + l))) * np.exp(-Z_ind * r * A / (n * au)) *
                       (2 * Z_ind * r * A /
                        (n * au))**l * sc.genlaguerre(n - l - 1, l * 2 + 1)
                       (2 * Z_ind * r * A / (n * au)))
Ejemplo n.º 9
0
def hyd3d(n, l, r, Z=1):
    """Analytical 3D hydrogenoid eigenfunctions and eigenenergies, normalized numerically."""
    reduced_radius = Z * r / n
    aux = special.genlaguerre(n - l - 1, 2 * l + 1)(2 * reduced_radius)
    unl = reduced_radius**(l + 1) * np.exp(-reduced_radius) * aux
    Enl = -Z**2 / 2 / n**2
    return unl / np.sqrt(integrate.simps(unl**2, r)), Enl
Ejemplo n.º 10
0
def brainsuite_shore_basis(radial_order, zeta, gtab, tau=1 / (4 * np.pi**2)):
    """Calculate the brainsuite shore basis functions."""

    # If deltas are defined, use them
    try:
        qvals = gtab.qvals
    except TypeError:
        qvals = np.sqrt(gtab.bvals / (4 * np.pi**2 * tau))

    qvals[gtab.b0s_mask] = 0
    bvecs = gtab.bvecs
    qgradients = qvals[:, None] * bvecs

    r, theta, phi = cart2sphere(qgradients[:, 0], qgradients[:, 1], qgradients[:, 2])
    theta[np.isnan(theta)] = 0

    # Angular part of the basis - Spherical harmonics
    S, Z, L = real_sym_sh_brainsuite(radial_order, theta, phi)
    Snew = []
    R = []
    for n in range(radial_order + 1):
        for l in range(0, n + 1, 2):
            Snew.append(S[:, L == l])
            for m in range(-l, l + 1):
                # Radial part
                R.append(genlaguerre(n - l, l + 0.5)(r ** 2 / zeta) *
                         np.exp(- r ** 2 / (2.0 * zeta)) *
                         _kappa(zeta, n, l) *
                         (r ** 2 / zeta) ** (l / 2))
    R = np.column_stack(R)
    Snew = np.column_stack(Snew)
    Sh = R * Snew
    return Sh
Ejemplo n.º 11
0
def shore_phi_matrix(radial_order, mu, q):
    '''Computed the Q matrix completely without separation into
    mu-depenent / -independent. See shore_Q_mu_independent for help.
    '''
    qval, theta, phi = cart2sphere(q[:, 0], q[:, 1], q[:, 2])
    theta[np.isnan(theta)] = 0

    ind_mat = shore_index_matrix(radial_order)

    n_elem = ind_mat.shape[0]
    n_qgrad = q.shape[0]
    M = np.zeros((n_qgrad, n_elem))

    counter = 0
    for n in range(0, radial_order + 1, 2):
        for j in range(1, 2 + n / 2):
            l = n + 2 - 2 * j
            const = (-1) ** (l / 2) * np.sqrt(4.0 * np.pi) *\
                (2 * np.pi ** 2 * mu ** 2 * qval ** 2) ** (l / 2) *\
                np.exp(-2 * np.pi ** 2 * mu ** 2 * qval ** 2) *\
                genlaguerre(j - 1, l + 0.5)(4 * np.pi ** 2 * mu ** 2 *
                                            qval ** 2)
            for m in range(-l, l + 1):
                M[:, counter] = const * real_sph_harm(m, l, theta, phi)
                counter += 1
    return M
Ejemplo n.º 12
0
	def LandauLevelSpinor(self, B , n , x , y ,type=1):
		# Symmetric Gauge 
		def energy(n):
			return np.sqrt( (self.mass*self.c**2)**2 + 2*B*self.c*self.hBar*n  )

		K = B*( (self.X-x)**2 + (self.Y-y)**2)/( 4.*self.c*self.hBar )
		
		psi1 = np.exp(-K)*( energy(n) + self.mass*self.c**2  )*laguerre(n)( 2*K ) 

		psi3 = np.exp(-K)*( energy(n) - self.mass*self.c**2  )*laguerre(n)( 2*K ) 

		if n>0:
			psi2 = 1j*np.exp(-K)*( self.X-x + 1j*(self.Y-y) )*genlaguerre(n-1,1)( 2*K )

		else: 
			psi2 = 0.*K		

		psi4 = psi2	

		if type==1:
			spinor = np.array([ psi1 , 0*psi2 , 0*psi3 , psi4  ])

		elif type ==2:
			spinor = np.array([ 0*psi1 , psi2 , psi3 , 0*psi4  ])

		else :
			print 'Error: type spinor must be 1 or 2'

		norm = self.Norm(spinor)

       		spinor /= norm 

		return spinor
Ejemplo n.º 13
0
def _par_wig_eval(args):
    """
    Private function for calculating terms of Laguerre Wigner function in parfor.
    """
    m,rho,A,B=args
    W1 = zeros(shape(A))
    for jj in range(rho.data.indptr[m], rho.data.indptr[m+1]):        
        n = rho.data.indices[jj]

        if m == n:
            W1 += real(rho[m,m] * (-1)**m * genlaguerre(m,0)(B))

        elif n > m:
            W1 += 2.0 * real(rho[m,n] * (-1)**m * (2*A)**(n-m) * \
                 sqrt(factorial(m)/factorial(n)) * genlaguerre(m,n-m)(B))
    return W1
Ejemplo n.º 14
0
def shore_psi_matrix(radial_order, mu, rgrad):
    """Computes the K matrix without optimization.
    """

    r, theta, phi = cart2sphere(rgrad[:, 0], rgrad[:, 1], rgrad[:, 2])
    theta[np.isnan(theta)] = 0

    ind_mat = shore_index_matrix(radial_order)

    n_elem = ind_mat.shape[0]
    n_rgrad = rgrad.shape[0]
    K = np.zeros((n_rgrad, n_elem))

    counter = 0
    for n in range(0, radial_order + 1, 2):
        for j in range(1, 2 + n / 2):
            l = n + 2 - 2 * j
            const = (-1) ** (j - 1) * \
                    (np.sqrt(2) * np.pi * mu ** 3) ** (-1) *\
                    (r ** 2 / (2 * mu ** 2)) ** (l / 2) *\
                np.exp(- r ** 2 / (2 * mu ** 2)) *\
                genlaguerre(j - 1, l + 0.5)(r ** 2 / mu ** 2)
            for m in range(-l, l + 1):
                K[:, counter] = const * real_sph_harm(m, l, theta, phi)
                counter += 1

    return K
Ejemplo n.º 15
0
def matrix(radial_order, angular_order, zeta, gtab, tau=1 / (4 * np.pi**2)):
    assert (radial_order >= angular_order)

    NGRADS = len(gtab.bvals)

    q = np.sqrt(gtab.bvals / (4 * np.pi**2 * tau))
    q[gtab.bvals < 40] = 0

    qgradients = q[:, None] * gtab.bvecs

    # r, theta, phi
    rtp = cart_to_sphere(qgradients)
    rsqrz = rtp[:, 0]**2 / zeta
    angles = rtp[:, 1:]

    sh = esh.matrix(angular_order, angles)

    size = get_size(radial_order, angular_order)
    M = np.zeros((NGRADS, size))

    counter = 0
    for l in range(0, angular_order + 1, 2):
        for n in range(l, (radial_order + l) // 2 + 1):
            c = genlaguerre(n - l, l + 0.5)(rsqrz) * np.exp(
                -rsqrz / 2.0) * _kappa(zeta, n, l) * rsqrz**(l / 2)
            for m in range(-l, l + 1):
                M[:, counter] = sh[:, esh.index(l, m)] * c
                counter += 1
    return M
Ejemplo n.º 16
0
def prepare_for_matrix(radial_order,
                       angular_order,
                       zeta,
                       gtab,
                       tau=1 / (4 * np.pi**2)):
    assert (radial_order >= angular_order)

    NGRADS = len(gtab.bvals)

    q = np.sqrt(gtab.bvals / (4 * np.pi**2 * tau))
    q[gtab.bvals < 40] = 0

    qgradients = q[:, None] * gtab.bvecs

    # r, theta, phi
    rtp = cart_to_sphere(qgradients)
    rsqrz = rtp[:, 0]**2 / zeta
    angles = rtp[:, 1:]

    sh = esh.matrix(angular_order, angles)

    size = get_size(radial_order, angular_order)
    # M = np.zeros((NGRADS, size))

    f_radial = np.zeros((NGRADS, angular_order + 1, radial_order + 1))
    for l in range(0, angular_order + 1, 2):
        for n in range(l, (radial_order + l) // 2 + 1):
            c = genlaguerre(n - l, l + 0.5)(rsqrz) * np.exp(
                -rsqrz / 2.0) * _kappa(zeta, n, l) * rsqrz**(l / 2)
            f_radial[:, l, n] = c

    return (radial_order, angular_order, zeta, tau, size, f_radial)
Ejemplo n.º 17
0
def hydrogen_phi_nlm(r, n, l, m, exact_factorial=False):
    '''
    The radial part of the normalized hydrogen wavefunction,
    multiplied by the radial coordinate `r`.
    
    - Considered only the electron mass, 
    instead of the reduced mass concept, which includes proton.
    - The atomic unit is used.
    '''

    _a_0_star = 1.0  # the reduced Bohr radius

    for quantum_number in (n, l, m):
        assert isinstance(quantum_number, Integral)
    assert isinstance(exact_factorial, bool)
    assert (n >= 1) and (l >= 0) and (m <= l) and (m >= -l)

    _n, _l, _m = n, l, m

    _r = r
    _rho = 2.0 * _r / (_n * _a_0_star)
    _constant = np.sqrt((2.0 / (_n * _a_0_star)) *
                        factorial(_n - _l - 1, exact=exact_factorial) /
                        (2.0 * _n * factorial(_n + _l, exact=exact_factorial)))
    _result = np.exp(-_rho * 0.5)
    _result *= np.power(_rho, _l + 1)  # `_l+1` due to multiplied `r`
    _result *= genlaguerre(_n - _l - 1, 2 * _l + 1, monic=False)(_rho)
    _result *= _constant

    return _result
Ejemplo n.º 18
0
def SHOREmatrix_pdf(radial_order, zeta, rtab):
    """Compute the SHORE matrix"

    Parameters
    ----------
    radial_order : unsigned int,
        Radial Order
    zeta : unsigned int,
        scale factor
    rtab : array, shape (N,3)
        r-space points in which calculates the pdf
    """

    r, theta, phi = cart2sphere(rtab[:, 0], rtab[:, 1], rtab[:, 2])
    theta[np.isnan(theta)] = 0

    psi = np.zeros(
        (r.shape[0], (radial_order + 1) * ((radial_order + 1) / 2) * (2 * radial_order + 1)))
    counter = 0
    for n in range(radial_order + 1):
        for l in range(0, n + 1, 2):
            for m in range(-l, l + 1):
                psi[:, counter] = real_sph_harm(m, l, theta, phi) * \
                    genlaguerre(n - l, l + 0.5)(4 * np.pi ** 2 * zeta * r ** 2 ) *\
                    np.exp(-2 * np.pi ** 2 * zeta * r ** 2) *\
                    __kappa_pdf(zeta, n, l) *\
                    (4 * np.pi ** 2 * zeta * r ** 2) ** (l / 2) * \
                    (-1) ** (n - l / 2)
                counter += 1
    return psi[:, 0:counter]
Ejemplo n.º 19
0
def derivTy(z, y, x):
    r_w_z_2 = (y**2 + x**2) / w(z)**2
    lag = eval_genlaguerre(p, l, 2 * r_w_z_2)
    return (w0 / w(z))**2 * (2 * r_w_z_2)**(l - 1) * np.exp(
        -2 * r_w_z_2) * lag * (4 * y / w(z)**2) * (
            (l - 2 * r_w_z_2) * lag + 4 * r_w_z_2 *
            np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2))
Ejemplo n.º 20
0
def wigner_mat(disps, d):
    """
    Construct the matrix M such that M(alpha)*vec(rho) = Wigner(alpha)
    The matrix M will be of dimension (N, d^2) where N is the number of
    displacements and d is the maximum photon number.

    Here vec(rho) deconstructs rho into a basis of d^2 hermitian operators.
    The first d elements of vec(rho) are the diagonal elements of rho, the
    next d*(d-1)/2 elements are the real parts of the upper triangle,
    and the last d*(d-1)/2 elements are the imaginary parts of the upper triangle.

    Elements of M are then M(a, (i, j)) = <j|D(-a) P D(a) |i> with displacement
    operator D and parity operator P.

    See http://dx.doi.org/10.1103/PhysRev.177.1882, esp. eq. 7.15
    """
    n_disp = len(disps)
    n_offd = (d * (d - 1)) // 2
    dm = np.zeros((n_disp, d * d))
    A = disps
    B = 4 * abs(A) ** 2
    i = 0
    for m in range(d):
        dm[:, m] = np.real((-1) ** m * genlaguerre(m, 0)(B))
        for n in range(m + 1, d):
            off_d = 2.0*(-1)**m * (2*A)**(n-m) * sqrt(factorial(m)/float(factorial(n))) * genlaguerre(m, n-m)(B)
            dm[:, d + i] = off_d.real
            dm[:, d + n_offd + i] = -off_d.imag
            i += 1
    dm = np.einsum('ij,i->ij', dm, np.exp(-B / 2))
    return dm
Ejemplo n.º 21
0
def derivTz(z, y, x):
    r_w_z_2 = (y**2 + x**2) / w(z)**2
    lag = eval_genlaguerre(p, l, 2 * r_w_z_2)
    return np.exp(-2 * r_w_z_2) * lag * 2 * (
        2 * r_w_z_2)**l * la**2 * z / np.pi**2 / w(z)**4 * (
            (-(1 + l) + 2 * r_w_z_2) * lag - 4 * r_w_z_2 *
            np.polyval(np.polyder(genlaguerre(p, l)), 2 * r_w_z_2))
Ejemplo n.º 22
0
def transitionAmplitude(eta, n, m):
    eta2 = eta * eta
    nl = min(n, m)
    ng = max(n, m)
    d = abs(n - m)
    return exp(-eta2 / 2) * pow(eta, d) * genlaguerre(nl, d)(eta2) / sqrt(
        factorialRatio(ng, nl)) if n >= 0 and m >= 0 else 0
Ejemplo n.º 23
0
def calc_mode(modes, idx, degenerate_mode, R, TH, a, alpha):
    m = modes.m[idx]
    l = modes.l[idx]

    aR2 = alpha * R.ravel()**2

    phase = m * TH.ravel()
    psi = 0

    # Non-zero transverse component
    if degenerate_mode == 'sin':
        # two pi/2 rotated degenerate modes for m < 0
        psi = np.pi / 2 if m[idx] < 0 else 0
        phase_mult = np.cos(phase + psi)

    elif degenerate_mode == 'exp':
        # noticably faster than writing exp(1j*phase)
        phase_mult = np.cos(phase) + 1j * np.sin(phase)

    amplitude = np.exp(-aR2 / 2) * aR2**(np.abs(m) / 2) * genlaguerre(
        l - 1, np.abs(m))(aR2)

    Et = phase_mult * amplitude
    mode = Et.astype(np.complex64)
    mode /= np.sqrt(np.sum(np.abs(mode)**2))
    return mode
Ejemplo n.º 24
0
	def LandauLevelSpinor(self, B , n , x , y ,type=1):
		# Symmetric Gauge 
		def energy(n):
			return np.sqrt( (self.mass*self.c**2)**2 + 2*B*self.c*self.hBar*n  )

		K = B*( (self.X-x)**2 + (self.Y-y)**2)/( 4.*self.c*self.hBar )
		
		psi1 = np.exp(-K)*( energy(n) + self.mass*self.c**2  )*laguerre(n)( 2*K ) 

		psi3 = np.exp(-K)*( energy(n) - self.mass*self.c**2  )*laguerre(n)( 2*K ) 

		if n>0:
			psi2 = 1j*np.exp(-K)*( self.X-x + 1j*(self.Y-y) )*genlaguerre(n-1,1)( 2*K )

		else: 
			psi2 = 0.*K		

		psi4 = psi2	

		if type==1:
			spinor = np.array([ psi1 , 0*psi2 , 0*psi3 , psi4  ])

		elif type ==2:
			spinor = np.array([ 0*psi1 , psi2 , psi3 , 0*psi4  ])

		else :
			print 'Error: type spinor must be 1 or 2'

		norm = self.Norm(spinor)

       		spinor /= norm 

		return spinor
Ejemplo n.º 25
0
def Morse_wavefunction(r, re=2, v=1, alpha=1, A=68.8885):
    # default parameters Morse oscillator 1. 10.1016/j.jms.2022.111621
    y = A * np.exp(-alpha * (r - re))
    beta = A - 2 * v - 1
    Nv = np.sqrt(alpha * beta * np.math.factorial(v) / gamma(A - v))
    wf = Nv * np.exp(-y / 2) * y**(beta / 2) * genlaguerre(v, beta)(y)
    return wf
Ejemplo n.º 26
0
def lgaus(xx, yy, width):
    order = 4
    lorder = 0
    width *= xx.shape[0] * 100
    r = np.sqrt(xx**2 + yy**2)
    laguerre = special.genlaguerre(order, lorder)
    return 1 * (r**lorder) * laguerre(2 * r**2 / width**2) * np.exp(
        -r**2 / width**2) * np.exp(1j * lorder * math.pi)  #replace 1 by phi
Ejemplo n.º 27
0
Archivo: wigner.py Proyecto: maij/qutip
def _par_wig_eval(args):
    """
    Private function for calculating terms of Laguerre Wigner function
    using parfor.
    """
    m, rho, A, B = args
    W1 = zeros(np.shape(A))
    for jj in range(rho.data.indptr[m], rho.data.indptr[m + 1]):
        n = rho.data.indices[jj]

        if m == n:
            W1 += real(rho[m, m] * (-1)**m * genlaguerre(m, 0)(B))

        elif n > m:
            W1 += 2.0 * real(rho[m, n] * (-1)**m * (2 * A)**(n - m) * sqrt(
                factorial(m) / factorial(n)) * genlaguerre(m, n - m)(B))
    return W1
Ejemplo n.º 28
0
def radial_wave_function(r, n):
    const1 = np.sqrt(
        ((2 / (n * a_0))**3) * (np.math.factorial(n - l - 1) /
                                (2 * n * np.math.factorial(n + l))))
    const2 = genlaguerre(n - l - 1, 2 * l + 1)(2 * r / (n * a_0))
    expon = np.exp(-r / (n * a_0))
    other = ((2 * r) / (n * 1_0))**l
    return const1 * expon * other * const2
def radial_wave_function_prob(r, theta = 0, phi = 0, n=3 ):
    const1 = np.sqrt(((2/(n*a_0))**3)*(np.math.factorial(n-l-1)/(2*n*np.math.factorial(n+l))))
    const2 = genlaguerre(n-l-1, 2*l+1)(2*r/(n*a_0))
    expon = np.exp(-r/(n*a_0))
    other = ((2*r)/(n*1_0))**l
    #f_lm = np.sqrt(np.math.factorial((2*l + 1)*(l-m))/(4*np.pi*np.math.factorial(l+m)))*lpmv(m, l, theta)
    #g_m = np.exp(m*phi)
    return ((4*np.pi*(r**2))*(const1*expon*other*const2)**2)
Ejemplo n.º 30
0
def compute_e0(shorefit):
    signal_0 = 0

    for n in range(int(shorefit.model.radial_order / 2) + 1):
        signal_0 += shorefit.shore_coeff[n] * (genlaguerre(n, 0.5)(0) *
        ((factorial(n)) / (2 * np.pi * (shorefit.model.zeta ** 1.5) * gamma(n + 1.5))) ** 0.5)

    return signal_0
Ejemplo n.º 31
0
def polar_shapelets_berry(N,M, beta):

    coeff = coeff_berry(N,M,beta)
    gen_laguerre = special.genlaguerre(n = (N-np.abs(M))/2, alpha = np.abs(M))

    laguer_N_M = lambda r, phi: coeff * (r/beta)**(np.abs(M)) * np.exp(-(r**2/beta**2)/2.) * gen_laguerre(r**2/beta**2) * np.exp(-1j*M*phi)
    
    return laguer_N_M
Ejemplo n.º 32
0
def polar_shapelets_radial(N, M, beta):

    coeff_1, coeff_2, coeff_3 = coeff(N, M, beta)
    gen_laguerre = special.genlaguerre(n=(N-np.abs(M))/2, alpha=np.abs(M))

    laguer_N_M = lambda x: coeff_1 *coeff_2 * x**(np.abs(M)) \
            * gen_laguerre(x**2/beta**2) * np.exp(-x**2/(2*beta**2))
    return laguer_N_M
Ejemplo n.º 33
0
 def calc_psi_z(self, v, z):
     alpha = 2 * (self.lam - v) - 1
     psi = (z**(self.lam - v - 0.5) * np.exp(-z / 2) *
            genlaguerre(v, alpha)(z))
     Nv = np.sqrt(
         factorial(v) * (2 * self.lam - 2 * v - 1) /
         gamma(2 * self.lam - v))
     return Nv * psi
Ejemplo n.º 34
0
def compute_e0(shorefit):
    signal_0 = 0

    for n in range(int(shorefit.model.radial_order / 2) + 1):
        signal_0 += shorefit.shore_coeff[n] * (genlaguerre(n, 0.5)(0) * (
            (factorial(n)) /
            (2 * np.pi * (shorefit.model.zeta**1.5) * gamma(n + 1.5)))**0.5)

    return signal_0
Ejemplo n.º 35
0
    def tabulate_laguerre(self):
	"""
	tabulate_laguerre()

	Evaluates all relevant Laguerre polynomials in all the quadrature 
	points. Sets the table as a class/instance variable.

	Notes
	-----
	The first axis is the m axis. The index is order/2, 
	i.e. only even ms are included.
	The second axis is the nu axis. The index gives the degree.
	The third axis is the x axis. The polynomials are evaluated in the 
	nodes of the [2 + m_max + nu_max] order Gauss Laguerre 
	quadrature formula.
	"""
	#Shorthand for useful parameters. For convenience.
	m_max = self.config.m_max
	nu_max = self.config.nu_max
	X = self.quadrature_object.nodes
	
	#Initiate array.
	laguerre_table = zeros([
	    2 * m_max + 1, 
	    m_max + nu_max + 3, 
	    self.rule_order])

	for i, order in enumerate(range(0, 2 * m_max + 1, 2)):
	    for j, degree in enumerate(range(nu_max + m_max + 3)):
		#Alternative 1 #TODO 
		#Warning: This method is unstable for high degree/order.
#		laguerre_table[i,j,:] = genlaguerre(degree, order)(X)
		#-------------
		#Alternative 2
		#More stable, but sloooow, 
		#and (as of yet) only for m = 0.
		#TODO Could probably be more effective.
		if order == 0:
		    for k, x in enumerate(X):
			p1 = 1.0
			p2 = 0.0
			
			#Loop the recurrence relation to get the Laguerre polynomial 
			#evaluated at x.
			for l in range(1, degree + 1):
			    p3 = p2
			    p2 = p1
			    p1 = ((2 * l - 1 - x) * p2 - (l - 1) * p3)/l

			laguerre_table[i,j,k] = p1
		else:
		    laguerre_table[i,j,:] = genlaguerre(degree, order)(X)
		#---------------


	self.laguerre_table = laguerre_table
def polar_shapelets_real(N, M, beta):

    coeff_1, coeff_2 = Coeff(N, M, beta)
    gen_laguerre = special.genlaguerre(n=(N - np.abs(M)) / 2, alpha=np.abs(M))

    Laguer_N_M = lambda x, phi: coeff_1 * coeff_2 * x**(np.abs(
        M)) * gen_laguerre(x**2 / beta**2) * np.exp(
            -x**2 / 2. / beta**2) * np.exp(-1j * M * phi).real

    return Laguer_N_M
Ejemplo n.º 37
0
def gen_lg_pattern(l, p, aux_mat, scale):
	"""
	Generate phase pattern for LG_{lp} modes, returns a matrix
	with dimension size x size.
	The width is assumed to be ''scale''*2 waist radii. 
	"""
	if l == p == 0:
		return np.zeros_like(aux_mat[0])
	rr = aux_mat[2] * scale
	phi = np.arctan2(aux_mat[0],aux_mat[1])
	L = genlaguerre(p, l)
	return -l*phi + np.pi*theta(-L(2*rr**2))
Ejemplo n.º 38
0
 def gen_R_nl(n, l, nu):
     """
     Generates a radial eigenfunction for the Spherical
     Harmonic Oscillator. Used to speed up calculations.
     """
     norm = sp.sqrt(
                     sp.sqrt(2*nu**3/sp.pi)*
                     2**(n + 2*l + 3)*factorial(n, exact=True)*
                     nu**l/factorial2(2*n + 2*l + 1, exact=True)
                   )
     laguerre = genlaguerre(n, l + .5)
     def R_nl(r):
         return norm * r**l * sp.exp(-nu * r**2) * laguerre(2*nu*r**2)
     return R_nl
Ejemplo n.º 39
0
 def rtop_pdf(self):
     r""" Calculates the analytical return to origin probability from the pdf. 
     """
     rtop = 0
     c = self._shore_coef
     counter = 0
     for n in range(self.radial_order + 1):
         for l in range(0, n + 1, 2):
             for m in range(-l, l + 1):
                 if l == 0:
                     rtop += c[counter] * (-1) ** n * \
                         ((4 * np.pi ** 2 * self.zeta ** 1.5 * factorial(n)) / (gamma(n + 1.5))) ** 0.5 * \
                         genlaguerre(n, 0.5)(0)
                 counter += 1
     return rtop
Ejemplo n.º 40
0
    def rtop_pdf(self):
        r""" Calculates the analytical return to origin probability (RTOP)
        from the pdf [1]_.

        References
        ----------
        .. [1] Ozarslan E. et. al, "Mean apparent propagator (MAP) MRI: A novel
        diffusion imaging method for mapping tissue microstructure",
        NeuroImage, 2013.
        """
        rtop = 0
        c = self._shore_coef
        for n in range(int(self.radial_order / 2) + 1):
            rtop += c[n] * (-1) ** n * \
                ((4 * np.pi ** 2 * self.zeta ** 1.5 * factorial(n)) / (gamma(n + 1.5))) ** 0.5 * \
                genlaguerre(n, 0.5)(0)

        return np.clip(rtop, 0, rtop.max())
Ejemplo n.º 41
0
    def evaluate_U(self, xi_grid, m, nu):
	"""
	result = evaluate_U(xi_grid, m, nu):

	Evaluates U on a grid. U is the basis function for the xi coordinate.
	U is defined in eq. (7) in Kamta2005.

	Parameters
	----------
	xi_grid : 1D float array, the xi values for which one wants to
	    evaluate U.
	m : integer, the angular momentum projection quantum number.
	nu : integer, some sort of quantum number associated with U.

	Returns
	-------
	result : 1D complex array, the result of the evaluation. 
	"""
	#Eq. (7) in Kamta2005.
	#---------------------
	
	alpha = self.config.alpha
	m = abs(m)

	#Normalization factor, N^m_nu.
	N = self.find_N(m, nu)
	
	#Exponential factor.
	exponential_factor = exp(-alpha * (xi_grid - 1))
	
	#Generalized/associated Laguerre polynomial. 
	#   L^a_b(x) => genlaguerre(b,a)(x)
	#   Warning! Not reliable results for higher orders.
	laguerre_factor = genlaguerre(nu - m, 2*m)(2*alpha * (xi_grid - 1))
	

	
	#All together now.
	result = N * exponential_factor * (xi_grid**2 - 1)**(m/2.) * laguerre_factor
	
	return result 
Ejemplo n.º 42
0
def hydrogenic_radial(n,l,r, Z=1):
  """
  r assumed to be in units of Bohr
  """
  from scipy.misc import factorial
  from scipy.special import genlaguerre

  # Messiah's L's are different from ours, so this norm is incorrect
  #N = (2.0 / n**2) * np.sqrt(factorial(n-l-1) / factorial(n+l)**3)

  # correct norm:
  N = (2.0/n**2) * np.sqrt(factorial(n-l-1) / factorial(n+l))
  x = 2.0 * r * Z / n

  #L = laguerre(n-l-1, 2*l+1, x)
  L = genlaguerre(n-l-1, 2*l+1)(x)
  F = x**l * np.exp(-x/2.0) * L

  R = Z**(1.5) *  F * N

  return R
Ejemplo n.º 43
0
def SHOREmatrix(radial_order, zeta, gtab, tau=1 / (4 * np.pi ** 2)):
    """Compute the SHORE matrix"

    Parameters
    ----------
    radial_order : unsigned int,
        Radial Order
    zeta : unsigned int,
        scale factor
    gtab : GradientTable,
        Gradient directions and bvalues container class
    tau : float,
        diffusion time. By default the value that makes q=sqrt(b).

    """

    qvals = np.sqrt(gtab.bvals / (4 * np.pi ** 2 * tau))
    bvecs = gtab.bvecs

    qgradients = qvals[:, None] * bvecs

    r, theta, phi = cart2sphere(
        qgradients[:, 0], qgradients[:, 1], qgradients[:, 2])
    theta[np.isnan(theta)] = 0

    M = np.zeros(
        (r.shape[0], (radial_order + 1) * ((radial_order + 1) / 2) * (2 * radial_order + 1)))

    counter = 0
    for n in range(radial_order + 1):
        for l in range(0, n + 1, 2):
            for m in range(-l, l + 1):
                M[:, counter] = real_sph_harm(m, l, theta, phi) * \
                    genlaguerre(n - l, l + 0.5)(r ** 2 / float(zeta)) * \
                    np.exp(- r ** 2 / (2.0 * zeta)) * \
                    __kappa(zeta, n, l) * \
                    (r ** 2 / float(zeta)) ** (l / 2)
                counter += 1
    return M[:, 0:counter]
Ejemplo n.º 44
0
    def fit(self, data):
        Lshore = l_shore(self.radial_order)
        Nshore = n_shore(self.radial_order)
        # Generate the SHORE basis
        M = self.cache_get('shore_matrix', key=self.gtab)
        if M is None:
            M = shore_matrix(self.radial_order,  self.zeta, self.gtab, self.tau)
            self.cache_set('shore_matrix', self.gtab, M)

        # Compute the signal coefficients in SHORE basis
        pseudoInv = np.dot(np.linalg.inv(np.dot(M.T, M) + self.lambdaN * Nshore + self.lambdaL * Lshore), M.T)
        coef = np.dot(pseudoInv, data)

        signal_0 = 0

        for n in range(int(self.radial_order / 2) + 1):
            signal_0 += coef[n] * genlaguerre(n, 0.5)(0) * \
                ((factorial(n)) / (2 * np.pi * (self.zeta ** 1.5) * gamma(n + 1.5))) ** 0.5

        coef = coef / signal_0

        return ShoreFit(self, coef)
Ejemplo n.º 45
0
def shore_matrix_pdf(radial_order, zeta, rtab):
    r"""Compute the SHORE propagator matrix [1]_"

    Parameters
    ----------
    radial_order : unsigned int,
        an even integer that represent the order of the basis
    zeta : unsigned int,
        scale factor
    rtab : array, shape (N,3)
        real space points in which calculates the pdf

    References
    ----------
    .. [1] Merlet S. et. al, "Continuous diffusion signal, EAP and
    ODF estimation via Compressive Sensing in diffusion MRI", Medical
    Image Analysis, 2013.
    """

    r, theta, phi = cart2sphere(rtab[:, 0], rtab[:, 1], rtab[:, 2])
    theta[np.isnan(theta)] = 0
    F = radial_order / 2
    n_c = int(np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)))
    psi = np.zeros((r.shape[0], n_c))
    counter = 0
    for l in range(0, radial_order + 1, 2):
        for n in range(l, int((radial_order + l) / 2) + 1):
            for m in range(-l, l + 1):
                psi[:, counter] = real_sph_harm(m, l, theta, phi) * \
                    genlaguerre(n - l, l + 0.5)(4 * np.pi ** 2 *
                                                zeta * r ** 2) *\
                    np.exp(-2 * np.pi ** 2 * zeta * r ** 2) *\
                    _kappa_pdf(zeta, n, l) *\
                    (4 * np.pi ** 2 * zeta * r ** 2) ** (l / 2) * \
                    (-1) ** (n - l / 2)
                counter += 1
    return psi
def test_d_U():
    """
    When caluculating the matrix elements for the electronic hamiltonian, 
    or more specifically in eq. (A6) in Kamta2005, the differentiation of U 
    makes an appearance. Analytical formulas for dU and d2U are shown in the
    note A_6.pdf in the Documentation folder. This method checks the validity 
    of these formulas, using numerical differentiation for comparison.
    """
    basis = psc_basis.PSC_basis(m = 6, nu = 6, mu = 5, R = 2.0, beta = 0.8, theta= pi/6.)
    
    dxi = .05
    #An extra point, since one will be lost.
    xi = r_[1:10 + 2 * dxi:dxi]
    m = abs(4)
    nu = 5
    alpha = basis.config.alpha
    
    #Alternative variable.
    X = 2 * alpha * (xi - 1)    
    
    #Evaluation of U.
    U_num = basis.evaluate_U(xi, m, nu)

    #Analytical U
    U = basis.find_N(m,nu) * exp(-alpha * (xi - 1)) * (xi**2 - 1)**(abs(m)/2.) * genlaguerre(nu - abs(m), 2 * abs(m))(2 * alpha * (xi - 1))
    
    #single diff.
    #-------------------------------------------------------
    #Numerical differentiation.
    dU_num = (U_num[2:] - U_num[:-2])/(2. * dxi)

    L_0 = genlaguerre(nu - abs(m) + 0, 2 * abs(m))(2. * alpha * (xi-1))
    L_1 = genlaguerre(nu - abs(m) + 1, 2 * abs(m))(2. * alpha * (xi-1))
    L_2 = genlaguerre(nu - abs(m) + 2, 2 * abs(m))(2. * alpha * (xi-1))
    N = basis.find_N(m,nu)



    #Analytical differentiation, 2nd formula.
    dU = N * exp(- alpha * (xi - 1.)) * (xi**2. - 1.)**(abs(m)/2.) * (
	(alpha - abs(m)/(xi**2. - 1.) - (nu + 1.)/(xi-1)) * L_0 
	+ (nu - abs(m) + 1)/(xi - 1.) * L_1)


    #Analytical differentiation, X formula.
    dU_X = N * exp(-0.5 * X) * (X/(2* alpha))**(abs(m)/2.) * (X/(2* alpha) + 2)**(abs(m)/2.) * (
	(alpha - 4* alpha**2 * abs(m)/(X*(X + 4*alpha)) - 2* alpha*(nu + 1.)/X) * L_0 
	+ 2 * alpha * (nu - abs(m) + 1)/X * L_1)

    
    #double diff.
    #------------------------------------------------------
    #Numerical differentiation.
    d2U_num = (U_num[2:] - 2*U_num[1:-1] + U_num[:-2])/(dxi**2)
    
    #Diff of this : N * exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * [
    #	(alpha - m/(xi**2 - 1) - (nu + 1)/(xi - 1)) * L_0	
    #	+ (nu - m + 1)/(xi-1) * L_1
    #	]

#    #Analytical differentiation.
#    d2U = N * exp(-alpha * (xi - 1)) * (xi**2 - 1)**(m/2.) * (
#	( 
#	    alpha * (  
#		alpha
#		+ m * xi / (xi**2 - 1)
#		- (nu + m + 1) / (xi - 1))
#	    - m * ( 
#		alpha / (xi**2 - 1)
#		- ((nu + 3) * (xi + 1) - 2 + m)/(xi**2 - 1)**2)
#	    - (nu + 1) * ( 
#		alpha  / (xi - 1)
#		+ (m - 1)/(xi - 1)**2
#		- m / ((xi**2 - 1)*(xi - 1))
#		- (nu + m + 1) / (xi - 1)**2)
#	) * L_0 
#	+
#	(
#	    (nu - m + 1) * ( 
#	    alpha / (xi - 1)
#	    - m/((xi**2 - 1) * (xi - 1))
#	    - (nu + 1) / (xi - 1)**2
#	    + alpha  / (xi - 1)
#	    + (m - 1)/(xi - 1)**2
#	    - m / ((xi**2 - 1)*(xi - 1))
#	    - (nu + m + 2) / (xi - 1)**2 )
#	) * L_1
#	+ 
#	(
#	(nu - m + 1) * (nu - m + 2) / (xi - 1)**2	
#	) * L_2
#	)

    #Analytical differentiation.
    d2U_simplified = N * exp(-alpha * (xi - 1)) * (xi**2 - 1)**(m/2.) * (
	( 
	    (  
		alpha**2
		+ alpha * m / (xi + 1)
		- alpha * (2 * nu + m + 2) / (xi - 1))
	    + m * (m - 2)/ (xi**2 - 1)**2 
	    + (nu + 1) * (nu + 2) / (xi - 1)**2
	    + 2 * m * (nu + 2) / ((xi**2 - 1)*(xi - 1))
	) * L_0 
	+
	(
	    2 * (nu - m + 1) * ( 
	      alpha / (xi - 1)
	    - (nu + 2) / (xi - 1)**2
	    - m / ((xi**2 - 1)*(xi - 1)))
	) * L_1
	+ 
	(
	(nu - m + 1) * (nu - m + 2) / (xi - 1)**2	
	) * L_2
	)

    d2U_X = N * exp(-X/2) * (X/(2*alpha))**(m/2.) *(X/(2*alpha) + 2)**(m/2.) * (
	( 
	      
		alpha**2
		+ 2* alpha**2 * m / (X + 4*alpha)
		- 2 * alpha**2 * (2 * nu + m + 2) / X
	    + 16 * alpha**4 * m * (m - 2)/ (X**2* (X + 4*alpha)**2) 
	    + 4 * alpha**2 * (nu + 1) * (nu + 2) / X**2
	    + 16 * alpha**3 * m * (nu + 2) / (X**2*(X + 4*alpha))
	) * L_0 
	+
	(
	    4 * alpha * (nu - m + 1) * ( 
	      alpha / X
	    - 2 * alpha * (nu + 2) / X**2
	    - 4 * alpha**2 * m / (X**2 * (X + 4 * alpha)))
	) * L_1
	+ 
	(
	4 * alpha **2 * (nu - m + 1) * (nu - m + 2) / X**2	
	) * L_2
	)



    #Plotting result.
    figure()
    plot(X[1:-1], dU_num, X[1:-1], dU[1:-1], X[1:-1], dU_X[1:-1])
    show()

    figure()
    plot(X[1:-1], d2U_num, X[1:-1], d2U_X[1:-1], X[1:-1], d2U_simplified[1:-1] )
    show()
Ejemplo n.º 47
0
def R(n, l, r):
    assert n > l
    a0 = 0.3
    return (2 * r / n / a0) ** l * exp(-r / n / a0) * genlaguerre(n - l - 1, 2 * l + 1)(2 * r / n / a0)
Ejemplo n.º 48
0
def R_nl(n, l, nu, r):
    norm = sp.sqrt(
        sp.sqrt(2 * nu ** 3 / sp.pi) * 2 ** (n + 2 * l + 3) * factorial(n) * nu ** l / factorial2(2 * n + 2 * l + 1)
    )
    lagge = genlaguerre(n, l + 0.5)(2 * nu * r ** 2)
    return norm * r ** l * sp.e ** (-nu * r ** 2) * lagge
Ejemplo n.º 49
0
    def fit(self, data):

        Lshore = l_shore(self.radial_order)
        Nshore = n_shore(self.radial_order)
        # Generate the SHORE basis
        M = self.cache_get('shore_matrix', key=self.gtab)
        if M is None:
            M = shore_matrix(self.radial_order,  self.zeta, self.gtab, self.tau)
            self.cache_set('shore_matrix', self.gtab, M)

        MpseudoInv = self.cache_get('shore_matrix_reg_pinv', key=self.gtab)
        if MpseudoInv is None:
            MpseudoInv = np.dot(np.linalg.inv(np.dot(M.T, M) + self.lambdaN * Nshore + self.lambdaL * Lshore), M.T)
            self.cache_set('shore_matrix_reg_pinv', self.gtab, MpseudoInv)

        # Compute the signal coefficients in SHORE basis
        if not self.constrain_e0:
            coef = np.dot(MpseudoInv, data)

            signal_0 = 0

            for n in range(int(self.radial_order / 2) + 1):
                signal_0 += (
                    coef[n] * (genlaguerre(n, 0.5)(0) * (
                        (factorial(n)) / (2 * np.pi * (self.zeta ** 1.5) * gamma(n + 1.5))
                    ) ** 0.5)
                )

            coef = coef / signal_0
        else:
            data = data / data[self.gtab.b0s_mask].mean()

            if cvxopt is not None:  # If cvxopt is not available use scipy (~100 times slower)
                M0 = M[self.gtab.b0s_mask, :]
                M0_mean = M0.mean(0)[None, :]
                Mprime = np.r_[M0_mean, M[~self.gtab.b0s_mask, :]]
                Q = cvxopt.matrix(np.ascontiguousarray(
                    np.dot(Mprime.T, Mprime)
                    + self.lambdaN * Nshore + self.lambdaL * Lshore
                ))

                data_b0 = data[self.gtab.b0s_mask].mean()
                data_single_b0 = np.r_[data_b0, data[~self.gtab.b0s_mask]] / data_b0
                p = cvxopt.matrix(np.ascontiguousarray(
                    -1 * np.dot(Mprime.T, data_single_b0))
                )

                cvxopt.solvers.options['show_progress'] = False

                G = None
                h = None

                A = cvxopt.matrix(np.ascontiguousarray(M0_mean))
                b = cvxopt.matrix(np.array([1.]))

                sol = cvxopt.solvers.qp(Q, p, G, h, A, b)

                if sol['status'] != 'optimal':
                    warn('Optimization did not find a solution')

                coef = np.array(sol['x'])[:, 0]
            else:
                raise ValueError('CVXOPT package needed to enforce constraints')

        return ShoreFit(self, coef)
Ejemplo n.º 50
0
def test_shore_metrics():
    gtab = get_gtab_taiwan_dsi()
    mevals = np.array(([0.0015, 0.0003, 0.0003],
                       [0.0015, 0.0003, 0.0003]))
    angl = [(0, 0), (60, 0)]
    S, sticks = MultiTensor(gtab, mevals, S0=100.0, angles=angl,
                            fractions=[50, 50], snr=None)

    # test shore_indices
    n = 7
    l = 6
    m = -4
    radial_order, c = shore_order(n, l, m)
    n2, l2, m2 = shore_indices(radial_order, c)
    assert_equal(n, n2)
    assert_equal(l, l2)
    assert_equal(m, m2)

    radial_order = 6
    c = 41
    n, l, m = shore_indices(radial_order, c)
    radial_order2, c2 = shore_order(n, l, m)
    assert_equal(radial_order, radial_order2)
    assert_equal(c, c2)

    # since we are testing without noise we can use higher order and lower lambdas, with respect to the default.
    radial_order = 8
    zeta = 700
    lambdaN = 1e-12
    lambdaL = 1e-12
    asm = ShoreModel(gtab, radial_order=radial_order,
                     zeta=zeta, lambdaN=lambdaN, lambdaL=lambdaL)
    asmfit = asm.fit(S)
    c_shore = asmfit.shore_coeff

    cmat = shore_matrix(radial_order, zeta, gtab)
    S_reconst = np.dot(cmat, c_shore)

    # test the signal reconstruction
    S = S / S[0]
    nmse_signal = np.sqrt(np.sum((S - S_reconst) ** 2)) / (S.sum())
    assert_almost_equal(nmse_signal, 0.0, 4)

    # test if the analytical integral of the pdf is equal to one
    integral = 0
    for n in range(int((radial_order)/2 +1)):
        integral += c_shore[n] * (np.pi**(-1.5) * zeta **(-1.5) * genlaguerre(n,0.5)(0)) ** 0.5

    assert_almost_equal(integral, 1.0, 10)

    # test if the integral of the pdf calculated on a discrete grid is equal to one
    pdf_discrete = asmfit.pdf_grid(17, 40e-3)
    integral = pdf_discrete.sum()
    assert_almost_equal(integral, 1.0, 1)

    # compare the shore pdf with the ground truth multi_tensor pdf

    sphere = get_sphere('symmetric724')
    v = sphere.vertices
    radius = 10e-3
    pdf_shore = asmfit.pdf(v * radius)
    pdf_mt = multi_tensor_pdf(v * radius, mevals=mevals,
                              angles=angl, fractions= [50, 50])
    nmse_pdf = np.sqrt(np.sum((pdf_mt - pdf_shore) ** 2)) / (pdf_mt.sum())
    assert_almost_equal(nmse_pdf, 0.0, 2)

    # compare the shore rtop with the ground truth multi_tensor rtop
    rtop_shore_signal = asmfit.rtop_signal()
    rtop_shore_pdf = asmfit.rtop_pdf()
    assert_almost_equal(rtop_shore_signal, rtop_shore_pdf, 9)
    rtop_mt = multi_tensor_rtop([.5, .5], mevals=mevals)
    assert_equal(rtop_mt / rtop_shore_signal <1.10 and rtop_mt / rtop_shore_signal > 0.95, True)

    # compare the shore msd with the ground truth multi_tensor msd
    msd_mt = multi_tensor_msd([.5, .5], mevals=mevals)
    msd_shore = asmfit.msd()
    assert_equal(msd_mt / msd_shore < 1.05 and msd_mt / msd_shore > 0.95, True)
Ejemplo n.º 51
0
def shore_matrix(radial_order, zeta, gtab, tau=1 / (4 * np.pi ** 2)):
    r"""Compute the SHORE matrix for modified Merlet's 3D-SHORE [1]_

    ..math::
            :nowrap:
                \begin{equation}
                    \textbf{E}(q\textbf{u})=\sum_{l=0, even}^{N_{max}}
                                            \sum_{n=l}^{(N_{max}+l)/2}
                                            \sum_{m=-l}^l c_{nlm}
                                            \phi_{nlm}(q\textbf{u})
                \end{equation}

    where $\phi_{nlm}$ is
    ..math::
            :nowrap:
                \begin{equation}
                    \phi_{nlm}^{SHORE}(q\textbf{u})=\Biggl[\dfrac{2(n-l)!}
                        {\zeta^{3/2} \Gamma(n+3/2)} \Biggr]^{1/2}
                        \Biggl(\dfrac{q^2}{\zeta}\Biggr)^{l/2}
                        exp\Biggl(\dfrac{-q^2}{2\zeta}\Biggr)
                        L^{l+1/2}_{n-l} \Biggl(\dfrac{q^2}{\zeta}\Biggr)
                        Y_l^m(\textbf{u}).
                \end{equation}

    Parameters
    ----------
    radial_order : unsigned int,
        an even integer that represent the order of the basis
    zeta : unsigned int,
        scale factor
    gtab : GradientTable,
        gradient directions and bvalues container class
    tau : float,
        diffusion time. By default the value that makes q=sqrt(b).

    References
    ----------
    .. [1] Merlet S. et. al, "Continuous diffusion signal, EAP and
    ODF estimation via Compressive Sensing in diffusion MRI", Medical
    Image Analysis, 2013.

    """

    qvals = np.sqrt(gtab.bvals / (4 * np.pi ** 2 * tau))
    qvals[gtab.b0s_mask] = 0
    bvecs = gtab.bvecs

    qgradients = qvals[:, None] * bvecs

    r, theta, phi = cart2sphere(qgradients[:, 0], qgradients[:, 1],
                                qgradients[:, 2])
    theta[np.isnan(theta)] = 0
    F = radial_order / 2
    n_c = int(np.round(1 / 6.0 * (F + 1) * (F + 2) * (4 * F + 3)))
    M = np.zeros((r.shape[0], n_c))

    counter = 0
    for l in range(0, radial_order + 1, 2):
        for n in range(l, int((radial_order + l) / 2) + 1):
            for m in range(-l, l + 1):
                M[:, counter] = real_sph_harm(m, l, theta, phi) * \
                    genlaguerre(n - l, l + 0.5)(r ** 2 / zeta) * \
                    np.exp(- r ** 2 / (2.0 * zeta)) * \
                    _kappa(zeta, n, l) * \
                    (r ** 2 / zeta) ** (l / 2)
                counter += 1
    return M
Ejemplo n.º 52
0
    def fit(self, data):

        Lshore = l_shore(self.radial_order)
        Nshore = n_shore(self.radial_order)
        # Generate the SHORE basis
        M = self.cache_get('shore_matrix', key=self.gtab)
        if M is None:
            M = shore_matrix(
                self.radial_order,  self.zeta, self.gtab, self.tau)
            self.cache_set('shore_matrix', self.gtab, M)

        MpseudoInv = self.cache_get('shore_matrix_reg_pinv', key=self.gtab)
        if MpseudoInv is None:
            MpseudoInv = np.dot(
                np.linalg.inv(np.dot(M.T, M) + self.lambdaN * Nshore +
                              self.lambdaL * Lshore), M.T)
            self.cache_set('shore_matrix_reg_pinv', self.gtab, MpseudoInv)

        # Compute the signal coefficients in SHORE basis
        if not self.constrain_e0:
            coef = np.dot(MpseudoInv, data)

            signal_0 = 0

            for n in range(int(self.radial_order / 2) + 1):
                signal_0 += (
                    coef[n] * (genlaguerre(n, 0.5)(0) * (
                        (factorial(n)) /
                        (2 * np.pi * (self.zeta ** 1.5) * gamma(n + 1.5))
                    ) ** 0.5)
                )

            coef = coef / signal_0
        else:
            data_norm = data / data[self.gtab.b0s_mask].mean()
            M0 = M[self.gtab.b0s_mask, :]

            c = cvxpy.Variable(M.shape[1])
            design_matrix = cvxpy.Constant(M)
            objective = cvxpy.Minimize(
                cvxpy.sum_squares(design_matrix * c - data_norm) +
                self.lambdaN * cvxpy.quad_form(c, Nshore) +
                self.lambdaL * cvxpy.quad_form(c, Lshore)
            )

            if not self.positive_constraint:
                constraints = [M0[0] * c == 1]
            else:
                lg = int(np.floor(self.pos_grid ** 3 / 2))
                v, t = create_rspace(self.pos_grid, self.pos_radius)
                psi = self.cache_get(
                    'shore_matrix_positive_constraint',
                    key=(self.pos_grid, self.pos_radius)
                )
                if psi is None:
                    psi = shore_matrix_pdf(
                        self.radial_order, self.zeta, t[:lg])
                    self.cache_set(
                        'shore_matrix_positive_constraint',
                        (self.pos_grid, self.pos_radius), psi)
                constraints = [M0[0] * c == 1., psi * c > 1e-3]
            prob = cvxpy.Problem(objective, constraints)
            try:
                prob.solve(solver=self.cvxpy_solver)
                coef = np.asarray(c.value).squeeze()
            except:
                warn('Optimization did not find a solution')
                coef = np.zeros(M.shape[1])
        return ShoreFit(self, coef)
Ejemplo n.º 53
0
def transitionAmplitude(eta, n, m):
    eta2 = eta*eta
    nl = min(n, m)
    ng = max(n, m)
    d = abs(n-m)
    return exp(-eta2/2) * pow(eta, d) * genlaguerre(nl, d)(eta2) / sqrt( factorialRatio(ng, nl ) ) if n>=0 and m>=0 else 0
def test_L0():
    basis = psc_basis.PSC_basis(m = 6, nu = 6, mu = 5, R = 2.0, beta = 0.8, theta= pi/6.)
    dxi = .05
    #An extra point, since one will be lost.
    xi = r_[1:10 + 2 * dxi:dxi]
    m = abs(4)
    nu = 5
    alpha = basis.config.alpha
    N = basis.find_N(m,nu)


    L_0 = genlaguerre(nu - abs(m) + 0, 2 * abs(m))(2. * alpha * (xi-1))
    L_1 = genlaguerre(nu - abs(m) + 1, 2 * abs(m))(2. * alpha * (xi-1))
    L_2 = genlaguerre(nu - abs(m) + 2, 2 * abs(m))(2. * alpha * (xi-1))

    
    
    #Part 1 : exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * alpha * L_0
    #----------------------------------------------------------
    #Numerical expression.
    U_num = exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * alpha * L_0

    #Numerical differentiation.
    dU_num = (U_num[2:] - U_num[:-2])/(2. * dxi)

    #Analytical differentiation.
    dU = exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (
	(  alpha**2
	+ alpha * m * xi / (xi**2 - 1)
	- alpha * (nu + m + 1) / (xi - 1)
	) * L_0 
	+
	( alpha * (nu - m + 1) / (xi - 1)
	) * L_1
	)
    #OK!
    #----------------------------------------------------------	

    #Part 2 :  - exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * m/(xi**2 - 1) * L_0
    #----------------------------------------------------------
    #Numerical expression.
    U_num = - exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * m/(xi**2 - 1) * L_0

    #Numerical differentiation.
    dU_num += (U_num[2:] - U_num[:-2])/(2. * dxi)

    #Analytical differentiation.
#    dU = - m * exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (
#	(
#	- alpha / (xi**2 - 1)
#	+ 2 * (m/2. - 1) * xi / (xi**2 - 1)**2
#	- (nu + m + 1 - 2* alpha * (xi - 1))/((xi**2 - 1) * (xi - 1))
#	) * L_0
#	+
#	(nu - m + 1)/((xi**2 - 1) * (xi - 1)) * L_1
#	)
   #Analytical differentiation, simplified.
    dU += - m * exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (
	(
	+ alpha / (xi**2 - 1)
	- ((nu + 3) * (xi + 1) - 2 + m)/(xi**2 - 1)**2
	) * L_0
	+
	(nu - m + 1)/((xi**2 - 1) * (xi - 1)) * L_1
	)
    #OK!
    #----------------------------------------------------------

    #Part 3 :  - exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (nu + 1)/(xi-1) * L_0
    #----------------------------------------------------------
    #Numerical expression.
    U_num = - exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (nu + 1)/(xi-1) * L_0

    #Numerical differentiation.
    dU_num += (U_num[2:] - U_num[:-2])/(2. * dxi)

   #Analytical differentiation.
    dU += - (nu + 1) * exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2.) * (
	(
	+ alpha  / (xi - 1)
	+ (m - 1)/(xi - 1)**2
	- m / ((xi**2 - 1)*(xi - 1))
	- (nu + m + 1) / (xi - 1)**2 
	) * L_0
	+ (nu - m + 1) / (xi - 1)**2 * L_1
	)
    #OK!
    #----------------------------------------------------------
    
    #Part 4 :  exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (nu - m + 1)/(xi-1) * L_1
    #----------------------------------------------------------
    #Numerical expression.
    U_num = exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2) * (nu -m + 1)/(xi-1) * L_1

    #Numerical differentiation.
    dU_num += (U_num[2:] - U_num[:-2])/(2. * dxi)

   #Analytical differentiation.
    dU += (nu - m + 1) * exp(-alpha*(xi - 1)) * (xi**2 - 1)**(m/2.) * (
	(
	+ alpha  / (xi - 1)
	+ (m - 1)/(xi - 1)**2
	- m / ((xi**2 - 1)*(xi - 1))
	- (nu + m + 2) / (xi - 1)**2 
	) * L_1
	+ (nu - m + 2) / (xi - 1)**2 * L_2
	)
    #OK!
    #----------------------------------------------------------

    #Analytical differentiation.
    d2U = N * exp(-alpha * (xi - 1)) * (xi**2 - 1)**(m/2.) * (
	( 
	    alpha * (  
		alpha
		+ m * xi / (xi**2 - 1)
		- (nu + m + 1) / (xi - 1))
	    - m * ( 
		alpha / (xi**2 - 1)
		- ((nu + 3) * (xi + 1) - 2 + m)/(xi**2 - 1)**2)
	    - (nu + 1) * ( 
		alpha  / (xi - 1)
		+ (m - 1)/(xi - 1)**2
		- m / ((xi**2 - 1)*(xi - 1))
		- (nu + m + 1) / (xi - 1)**2)
	) * L_0 
	+
	(
	    (nu - m + 1) * ( 
	    alpha / (xi - 1)
	    - m/((xi**2 - 1) * (xi - 1))
	    - (nu + 1) / (xi - 1)**2
	    + alpha  / (xi - 1)
	    + (m - 1)/(xi - 1)**2
	    - m / ((xi**2 - 1)*(xi - 1))
	    - (nu + m + 2) / (xi - 1)**2 )
	) * L_1
	+ 
	(
	(nu - m + 1) *(nu - m + 2) / (xi - 1)**2	
	) * L_2
	)




    #Plotting result.
    figure()
    plot(xi[1:-1], N * dU_num, xi[1:-1], N * dU[1:-1],xi[1:-1], d2U[1:-1] )
    show()
Ejemplo n.º 55
0
Archivo: shore.py Proyecto: MPDean/dipy
    def fit(self, data):

        Lshore = l_shore(self.radial_order)
        Nshore = n_shore(self.radial_order)
        # Generate the SHORE basis
        M = self.cache_get('shore_matrix', key=self.gtab)
        if M is None:
            M = shore_matrix(
                self.radial_order,  self.zeta, self.gtab, self.tau)
            self.cache_set('shore_matrix', self.gtab, M)

        MpseudoInv = self.cache_get('shore_matrix_reg_pinv', key=self.gtab)
        if MpseudoInv is None:
            MpseudoInv = np.dot(
                np.linalg.inv(np.dot(M.T, M) + self.lambdaN * Nshore + self.lambdaL * Lshore), M.T)
            self.cache_set('shore_matrix_reg_pinv', self.gtab, MpseudoInv)

        # Compute the signal coefficients in SHORE basis
        if not self.constrain_e0:
            coef = np.dot(MpseudoInv, data)

            signal_0 = 0

            for n in range(int(self.radial_order / 2) + 1):
                signal_0 += (
                    coef[n] * (genlaguerre(n, 0.5)(0) * (
                        (factorial(n)) /
                        (2 * np.pi * (self.zeta ** 1.5) * gamma(n + 1.5))
                    ) ** 0.5)
                )

            coef = coef / signal_0
        else:
            data = data / data[self.gtab.b0s_mask].mean()

            # If cvxopt is not available, bail (scipy is ~100 times slower)
            if not have_cvxopt:
                raise ValueError(
                    'CVXOPT package needed to enforce constraints')
            w_s = "The implementation of SHORE depends on CVXOPT "
            w_s += " (http://cvxopt.org/). This software is licensed "
            w_s += "under the GPL (see: http://cvxopt.org/copyright.html) "
            w_s += " and you may be subject to this license when using SHORE."
            warn(w_s)
            M0 = M[self.gtab.b0s_mask, :]
            M0_mean = M0.mean(0)[None, :]
            Mprime = np.r_[M0_mean, M[~self.gtab.b0s_mask, :]]
            Q = cvxopt.matrix(np.ascontiguousarray(
                np.dot(Mprime.T, Mprime)
                + self.lambdaN * Nshore + self.lambdaL * Lshore
            ))

            data_b0 = data[self.gtab.b0s_mask].mean()
            data_single_b0 = np.r_[
                data_b0, data[~self.gtab.b0s_mask]] / data_b0
            p = cvxopt.matrix(np.ascontiguousarray(
                -1 * np.dot(Mprime.T, data_single_b0))
            )

            cvxopt.solvers.options['show_progress'] = False

            if not(self.positive_constraint):
                G = None
                h = None
            else:
                lg = int(np.floor(self.pos_grid ** 3 / 2))
                G = self.cache_get(
                    'shore_matrix_positive_constraint', key=(self.pos_grid, self.pos_radius))
                if G is None:
                    v, t = create_rspace(self.pos_grid, self.pos_radius)

                    psi = shore_matrix_pdf(
                        self.radial_order, self.zeta, t[:lg])
                    G = cvxopt.matrix(-1 * psi)
                    self.cache_set(
                        'shore_matrix_positive_constraint', (self.pos_grid, self.pos_radius), G)
                h = cvxopt.matrix((1e-10) * np.ones((lg)), (lg, 1))

            A = cvxopt.matrix(np.ascontiguousarray(M0_mean))
            b = cvxopt.matrix(np.array([1.]))
            sol = cvxopt.solvers.qp(Q, p, G, h, A, b)

            if sol['status'] != 'optimal':
                warn('Optimization did not find a solution')

            coef = np.array(sol['x'])[:, 0]

        return ShoreFit(self, coef)
Ejemplo n.º 56
0
def laguerre(n0,m0):
    """Return a generalized Laguerre polynomial L^(|m|)_((n-|m|)/2)(x)"""
    l0=special.genlaguerre(n=(n0-np.abs(m0))/2,alpha=np.abs(m0))
    return l0