Example #1
0
def fi_iso2d(shape, k0, n=1., betay=0, betamax=BETAMAX):
    fmat = f_iso2d(shape, k0, n, betay, betamax)
    if isinstance(fmat, tuple):
        out = (inv(f) for f in fmat)
        return tuple(out)
    else:
        return inv(fmat)
Example #2
0
def _reflect2d(fvec_in, fmat_in, rmat, fmat_out, fvec_out=None):
    """Transmits/reflects field vector using 4x4 method.
    
    This functions takes a field vector that describes the input field and
    computes the output transmited field and also updates the input field 
    with the reflected waves.
    """

    fmat_ini = inv(fmat_in)

    avec = dotmv(fmat_ini, fvec_in)

    a = np.zeros(avec.shape, avec.dtype)
    a[..., 0::2] = avec[..., 0::2]

    if fvec_out is not None:
        fmat_outi = inv(fmat_out)
        bvec = dotmv(fmat_outi, fvec_out)
        a[..., 1::2] = bvec[..., 1::2]
    else:
        bvec = np.zeros_like(avec)

    av = a.reshape(a.shape[:-2] + (a.shape[-2] * a.shape[-1], ))
    out = dotmv(rmat, av).reshape(a.shape)

    avec[..., 1::2] = out[..., 1::2]
    bvec[..., ::2] = out[..., ::2]

    dotmv(fmat_in, avec, out=fvec_in)
    return dotmv(fmat_out, bvec, out=out)
Example #3
0
def alphaEEi(beta, phi, epsv, epsa, mode=+1, out=None):
    if out is None:
        alpha, E = alphaE(beta, phi, epsv, epsa, mode=mode)
        return alpha, E, inv(E)
    else:
        alpha, E, Ei = out
        alpha, E = alphaE(beta, phi, epsv, epsa, mode=mode, out=(alpha, E))
        Ei = inv(E, out=Ei)
        return alpha, E, Ei
Example #4
0
def Eti_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None):
    A = E_mat(fin, mode=mode, copy=False)
    Ai = inv(A, out=out)
    St, Sr = S_mat(fin,
                   fout,
                   fini=fini,
                   overwrite_fin=overwrite_fin,
                   mode=mode)
    Sti = inv(St, out=St)
    return dotmm(Sti, Ai, out=Ai)
Example #5
0
def Etri_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1, out=None):
    out1, out2 = out if out is not None else (None, None)
    A = E_mat(fin, mode=mode, copy=False)
    Ai = inv(A, out=out1)
    St, Sr = S_mat(fin,
                   fout,
                   fini=fini,
                   overwrite_fin=overwrite_fin,
                   mode=mode)
    Sti = inv(St, out=St)
    ei = dotmm(Sti, Ai, out=Ai)
    return ei, dotmm(Sr, ei, out=out2)
Example #6
0
def transmission_mat(fin, fout, fini=None, mode=+1, out=None):
    A, B = S_mat(fin, fout, fini=fini, mode=mode)
    if mode == +1:
        A1 = fin[..., ::2, ::2]
        A2 = fout[..., ::2, ::2]
    elif mode == -1:
        A1 = fin[..., 1::2, 1::2]
        A2 = fout[..., 1::2, 1::2]
    else:
        raise ValueError("Unknown propagation mode.")
    Ai = inv(A, out=out)
    A1i = inv(A1)
    return dotmm(dotmm(A2, Ai, out=Ai), A1i, out=Ai)
Example #7
0
def transmit(fvec_in,
             cmat,
             fmatin=None,
             fmatout=None,
             fmatini=None,
             fmatouti=None,
             fvec_out=None):
    """Transmits field vector using 4x4 method.
    
    This functions takes a field vector that describes the input field and
    computes the output transmited field and also updates the input field 
    with the reflected waves.
    """
    b = np.broadcast(fvec_in[..., None], cmat, fmatin, fmatout)

    if fmatini is None:
        if fmatin is None:
            fmatin = f_iso(1, 0, 0)
        fmatini = inv(fmatin)
    if fmatin is None:
        fmatin = inv(fmatini)
    if fmatouti is None:
        if fmatout is None:
            fmatout = fmatin
            fmatouti = fmatini
        else:
            fmatouti = inv(fmatout)
    if fmatout is None:
        fmatout = inv(fmatouti)

    smat = system_mat(cmat, fmatini=fmatini, fmatout=fmatout)

    avec = dotmv(fmatini, fvec_in)
    a = np.zeros(b.shape[:-1], avec.dtype)
    a[..., 0::2] = avec[..., 0::2]
    avec = a.copy()  #so that it broadcasts

    if fvec_out is not None:
        bvec = dotmv(fmatouti, fvec_out)
        a[..., 1::2] = bvec[..., 1::2]
    else:
        bvec = np.zeros_like(avec)

    r = reflection_mat(smat)
    out = dotmv(r, a, out=fvec_out)

    avec[..., 1::2] = out[..., 1::2]
    bvec[..., ::2] = out[..., ::2]

    dotmv(fmatin, avec, out=fvec_in)
    return dotmv(fmatout, bvec, out=out)
Example #8
0
def _transfer_ray_4x4_1_windows(windows, field, wavenumbers, layer, dmat1, dmat2, betas, phis,
                    nsteps = 1, out = None,
                    betamax = BETAMAX):
        
    d, epsv, epsa = layer

    kd = wavenumbers*d 
    
    if out is None:
        out = np.zeros_like(field)

    for j in range(nsteps):
        field = dotmf(dmat1,field)
        for window, beta, phi in zip(windows, betas, phis):
            alpha, f = alphaf(beta,phi,epsv,epsa)
            p = phasem(alpha,kd[...,None,None])
            
            e = E_mat(f, mode = None)
            ei = inv(e)
            
            f = field * window
            
            
            f = ifft2(f, out = f)
            f = dotmdmf(e,p,ei,f, out = f)  
            f = fft2(field, out = f)
            out += f
            
        out = dotmf(dmat2,out, out = out)
                  
    return out
Example #9
0
def jonesmat4x4(jmat, fmat, out=None):
    """Returns a 4x4 jones matrix for applying in eigenframe.
    
    Numpy broadcasting rules apply.
    
    Parameters
    ----------
    jmat : (...,2,2) array
        A 2x2 jones matrix in the eigenframe. Any of matrices in :mod:`dtmm.jones` 
        can be used.
    fmat : (...,4,4) array
        A field matrix array of the isotropic medium.
    out : ndarray, optional
        Output array   
        
    Returns
    -------
    jmat : (...,4,4) array
        A 4x4 matrix for field vector manipulation in the eigenframe.  
        
    See Also
    --------
    ray_jonesmat4x4 : for applying the jones matrix in the laboratory frame.
    """
    fmat = normalize_f(fmat)
    fmati = inv(fmat)
    pmat = as4x4(jmat)
    m = dotmm(fmat, dotmm(pmat, fmati, out=out), out=out)
    return m
Example #10
0
def _transfer_ray_4x4_1(field,
                        wavenumbers,
                        layer,
                        dmat1,
                        dmat2,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        betamax=BETAMAX,
                        out=None):

    d, epsv, epsa = layer

    kd = wavenumbers * d

    alpha, f = alphaf(beta, phi, epsv, epsa)
    p = phasem(alpha, kd[..., None, None])

    e = E_mat(f, mode=None)
    ei = inv(e)

    for j in range(nsteps):
        field = dotmf(dmat1, field, out=out)
        field = ifft2(field, out=field)
        field = dotmdmf(e, p, ei, field, out=field)
        field = fft2(field, out=field)
        field = dotmf(dmat2, field, out=out)

    return field
Example #11
0
def polarizer4x4(jones, fmat, out=None):
    """Returns a polarizer matrix from a given jones vector and field matrix. 
    
    Numpy broadcasting rules apply.
    
    Parameters
    ----------
    jones : array_like
        A length two array describing the jones vector. Jones vector should
        be normalized.
    fmat : array_like
        A field matrix array of the medium.
    out : ndarray, optional
        Output array
    
    Examples
    --------
    >>> f = f_iso(n = 1.) 
    >>> jvec = dtmm.jones.jonesvec((1,0)) 
    >>> pol_mat = polarizer4x4(jvec, f) #x polarizer matrix
    
    """
    jonesmat = polarizer2x2(jones)
    fmat = normalize_f(fmat)
    fmati = inv(fmat)
    pmat = as4x4(jonesmat)
    m = dotmm(fmat, dotmm(pmat, fmati, out=out), out=out)
    return m
Example #12
0
def system_mat(cmat, fmatin=None, fmatout=None, fmatini=None, out=None):
    """Computes a system matrix from a characteristic matrix Fin-1.C.Fout"""
    if fmatini is None:
        if fmatin is None:
            fmatin = f_iso(1, 0, 0)
        fmatini = inv(fmatin)
    if fmatout is None:
        fmatout = fmatin
    out = dotmm(fmatini, cmat, out=out)
    return dotmm(out, fmatout, out=out)
Example #13
0
def projection_mat(fmat, fmati=None, mode=+1):
    if fmati is None:
        fmati = inv(fmat)
    diag = np.zeros(fmat.shape[:-1], fmat.dtype)
    if mode == 1:
        diag[..., 0::2] = 1.
    elif mode == -1:
        diag[..., 1::2] = 1.
    else:
        raise ValueError("Unknown propagation mode.")
    return dotmdm(fmat, diag, fmati)
Example #14
0
def E2H_mat(fmat, mode=+1, out=None):
    if mode == +1:
        A = fmat[..., ::2, ::2]
        B = fmat[..., 1::2, ::2]
    elif mode == -1:
        A = fmat[..., ::2, 1::2]
        B = fmat[..., 1::2, 1::2]
    else:
        raise ValueError("Unknown propagation mode.")
    Ai = inv(A, out=out)
    return dotmm(B, Ai, out=Ai)
Example #15
0
def Epn_correction_matrix(beta,
                          phi,
                          ks,
                          d=1.,
                          epsv=(1, 1, 1),
                          epsa=(0, 0, 0.),
                          out=None):
    alpha, f = alphaf(beta, phi, epsv, epsa)
    kd = -np.asarray(ks) * d
    pmat = phase_mat(alpha, kd[..., None, None])
    e = E_mat(f, mode=None)
    ei = inv(e)
    return dotmdm(e, pmat, ei, out=out)
Example #16
0
def S_mat(fin, fout, fini=None, overwrite_fin=False, mode=+1):
    if overwrite_fin == True:
        out = fin
    else:
        out = None
    if fini is None:
        fini = inv(fin, out=out)
    S = dotmm(fini, fout, out=out)
    if mode == +1:
        return S[..., ::2, ::2], S[..., 1::2, 0::2]
    elif mode == -1:
        return S[..., 1::2, 1::2], S[..., 0::2, 1::2]
    else:
        raise ValueError("Unknown propagation mode.")
Example #17
0
def alphaffi(beta, phi, epsv, epsa, out=None):
    """Computes alpha and field arrays (eigen values and eigen vectors arrays)
    and inverse of the field array. See :func:`alphaf` for details
    
    Broadcasting rules apply.
       
    Returns
    -------
    alpha, field, ifield  : (ndarray, ndarray, ndarray)
        Eigen values and eigen vectors arrays and its inverse
        
    This is equivalent to
    
    >>> alpha,field = alphaf(0,0, [2,2,2], [0.,0.,0.])
    >>> ifield = inv(field)
    """
    if out is not None:
        a, f, fi = out
        _alphaf(beta, phi, epsv, epsa, out=(a, f))
        inv(f, fi)
    else:
        a, f = _alphaf(beta, phi, epsv, epsa)
        fi = inv(f)
    return a, f, fi
Example #18
0
def reflection_mat(smat, out=None):
    """Computes a 4x4 reflection matrix.
    """
    m1 = np.zeros_like(smat)
    m2 = np.zeros_like(smat)
    m1[..., 1, 1] = 1.
    m1[..., 3, 3] = 1.
    m1[..., :, 0] = -smat[..., :, 0]
    m1[..., :, 2] = -smat[..., :, 2]
    m2[..., 0, 0] = -1.
    m2[..., 2, 2] = -1.
    m2[..., :, 1] = smat[..., :, 1]
    m2[..., :, 3] = smat[..., :, 3]
    m1 = inv(m1)
    return dotmm(m1, m2, out=out)
Example #19
0
def _layer_mat3d(k0, d, epsv, epsa, mask, betas, phis, indices, method):
    n = len(betas)
    kd = k0 * d  #/2.
    shape = epsv.shape[-3], epsv.shape[-2]
    if method.startswith("2x2"):
        out = np.empty(shape=(n, n, 2, 2), dtype=CDTYPE)
    else:
        out = np.empty(shape=(n, n, 4, 4), dtype=CDTYPE)

    for j, (beta, phi) in enumerate(zip(betas, phis)):
        if method.startswith("2x2"):
            alpha, fmat = alphaf(beta, phi, epsv, epsa)
            f = tmm.E_mat(fmat, mode=+1, copy=False)
            fi = inv(f)
            pmat = phase_mat(alpha[..., ::2], kd)
        else:
            alpha, f, fi = alphaffi(beta, phi, epsv, epsa)
            pmat = phase_mat(alpha, -kd)
            if method == "4x4_1":
                pmat[..., 1::2] = 0.
            if method != "4x4":
                raise ValueError("Unsupported method.")

        wave = eigenwave(shape, indices[j, 0], indices[j, 1], amplitude=1.)

        m = dotmdm(f, pmat, fi)
        mw = m * wave[..., None, None]

        mf = mfft2(mw, overwrite_x=True)

        #dd = np.linspace(0,1.,10)*d

        # dmat = 0.

        # for dm in dd:

        #     dmat = dmat + second_field_diffraction_matrix(shape, -k0, beta, phi,dm,
        #                                   epsv = (1.5,1.5,1.5),
        #                             epsa = (0.,0.,0.), betamax = 1.4) /len(dd)

        # mf = dotmm(dmat,mf)

        mf = mf[mask, ...]

        out[:, j, :, :] = mf

    return out
Example #20
0
def _transfer_ray_4x4_2(field,
                        wavenumbers,
                        layer,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        dmatpn=None,
                        out=None,
                        tmpdata=None):
    _out = {} if tmpdata is None else tmpdata

    d, epsv, epsa = layer

    if dmatpn is None:
        kd = wavenumbers * d
    else:
        dmatp, dmatn = dmatpn
        kd = wavenumbers * d / 2

    alpha, f, fi = alphaffi(beta, phi, epsv, epsa, out=_out.get("affi"))

    p = phasem(alpha, kd[..., None, None], out=_out.get("p"))
    if tmpdata is not None:
        tmpdata["affi"] = (alpha, f, fi)
        tmpdata["p"] = p

    if dmatpn is not None:
        e = E_mat(f, mode=None)
        ei = inv(e, out=_out.get("ei"))
        if tmpdata is not None:
            tmpdata["ei"] = ei

    for j in range(nsteps):
        if dmatpn is None:
            field = dotmdmf(f, p, fi, field, out=out)
        else:
            field = dotmdmf(e, p, fi, field, out=out)
            diffract(field[..., 0::2, :, :], dmatp, out=field[..., 0::2, :, :])
            diffract(field[..., 1::2, :, :], dmatn, out=field[..., 1::2, :, :])
            field = dotmdmf(f, p, ei, field, out=field)

    return field
Example #21
0
def second_Epn_diffraction_matrix(shape,
                                  ks,
                                  d=1.,
                                  epsv=(1, 1, 1),
                                  epsa=(0, 0, 0.),
                                  betamax=BETAMAX,
                                  out=None):
    ks = np.asarray(ks, dtype=FDTYPE)
    epsv = np.asarray(epsv, dtype=CDTYPE)
    epsa = np.asarray(epsa, dtype=FDTYPE)
    alpha, f = diffraction_alphaf(shape,
                                  ks,
                                  epsv=epsv,
                                  epsa=epsa,
                                  betamax=betamax)
    kd = ks * d
    e = E_mat(f, mode=None)
    ei = inv(e)
    pmat = phase_mat(alpha, kd[..., None, None])
    return dotmdm(f, pmat, ei, out=out)
Example #22
0
def propagate_2x2_full(field,
                       wavenumbers,
                       layer,
                       input_layer=None,
                       nsteps=1,
                       mode=+1,
                       reflection=True,
                       betamax=BETAMAX,
                       refl=None,
                       bulk=None,
                       out=None):

    shape = field.shape[-2:]

    d, epsv, epsa = layer
    if input_layer is not None:
        d_in, epsv_in, epsa_in = input_layer

    kd = wavenumbers * d / nsteps

    if out is None:
        out = np.empty_like(field)

    ii, jj = np.meshgrid(range(shape[0]),
                         range(shape[1]),
                         copy=False,
                         indexing="ij")

    for step in range(nsteps):
        for i in range(len(wavenumbers)):
            ffield = fft2(field[..., i, :, :, :])
            ofield = np.zeros_like(out[..., i, :, :, :])

            b, p = betaphi(shape, wavenumbers[i])
            mask = b < betamax

            amplitude = ffield[..., mask]

            betas = b[mask]
            phis = p[mask]
            iind = ii[mask]
            jind = jj[mask]

            if bulk is not None:
                obulk = bulk[..., i, :, :, :]

            if refl is not None:
                tampl = fft2(refl[..., i, :, :, :])[..., mask]
                orefl = refl[..., i, :, :, :]
                orefl[...] = 0.

            for bp in sorted(zip(range(len(betas)), betas, phis, iind, jind),
                             key=lambda el: el[1],
                             reverse=False):
                #for j,bp in enumerate(zip(betas,phis,iind,jind)):

                j, beta, phi, ieig, jeig = bp

                out_af = alphaf(beta, phi, epsv, epsa)
                alpha, fmat_out = out_af
                e = E_mat(fmat_out, mode=mode)
                ei0 = inv(e)
                ei = ei0
                pm = phase_mat(alpha, kd[i, None, None], mode=mode)
                w = eigenwave(amplitude.shape[:-1] + shape,
                              ieig,
                              jeig,
                              amplitude=amplitude[..., j])
                if step == 0 and reflection != False:
                    alphain, fmat_in = alphaf(beta, phi, epsv_in, epsa_in)
                    if refl is not None:
                        ei, eri = Etri_mat(fmat_in, fmat_out, mode=mode)
                        ein = E_mat(fmat_in, mode=-1 * mode)
                        t = eigenwave(amplitude.shape[:-1] + shape,
                                      ieig,
                                      jeig,
                                      amplitude=tampl[..., j])
                        r = dotmf(eri, w)
                        r = dotmf(ein, r, out=r)
                        np.add(orefl, r, orefl)

                        w = dotmf(ei, w, out=w)
                        t = dotmf(ei0, t, out=t)
                        w = np.add(t, w, out=w)

                    else:
                        ei = Eti_mat(fmat_in, fmat_out, mode=mode)
                        w = dotmf(ei, w, out=w)
                    w = dotmf(dotmd(e, pm), w, out=w)
                    np.add(ofield, w, ofield)

                else:
                    w = dotmdmf(e, pm, ei, w, out=w)
                    np.add(ofield, w, ofield)

                if bulk is not None:
                    e2h = E2H_mat(fmat_out, mode=mode)
                    obulk[..., 1::2, :, :] += dotmf(e2h, w)
                    obulk[..., ::2, :, :] += w

            out[..., i, :, :, :] = ofield

        field = out
    return out, refl
Example #23
0
def _transfer_ray_2x2_1(fft_field,
                        wavenumbers,
                        layer,
                        effective_layer_in,
                        effective_layer_out,
                        dmat1,
                        dmat2,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        mode=+1,
                        reflection=True,
                        betamax=BETAMAX,
                        refl=None,
                        bulk=None,
                        out=None,
                        tmpdata=None):
    _out = {} if tmpdata is None else tmpdata
    #fft_field = fft2(fft_field, out = out)
    shape = fft_field.shape[-2:]
    d_in, epsv_in, epsa_in = effective_layer_in

    d_out, epsv_out, epsa_out = effective_layer_out

    if reflection:
        tmat, rmat = E_tr_matrix(shape,
                                 wavenumbers,
                                 epsv_in=epsv_in,
                                 epsa_in=epsa_in,
                                 epsv_out=epsv_out,
                                 epsa_out=epsa_out,
                                 mode=mode,
                                 betamax=betamax)

    d, epsv, epsa = layer
    alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("alphaf"))

    e = E_mat(fmat, mode=mode, copy=False)  #2x2 E-only view of fmat
    ei = inv(e, out=_out.get("ei"))
    #
    kd = wavenumbers * d
    p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p"))

    if tmpdata is not None:
        _out["alphaf"] = alpha, fmat
        _out["ei"] = ei
        _out["p"] = p

    for j in range(nsteps):
        if j == 0 and reflection:
            #reflect only at the beginning
            if refl is not None:
                trans = refl.copy()
                refl = dotmf(rmat, fft_field, out=refl)
                fft_field = dotmf(tmat, fft_field, out=out)
                fft_field = np.add(fft_field, trans, out=fft_field)

                if mode == -1 and bulk is not None:
                    field = ifft2(fft_field)
                    e2h = E2H_mat(fmat, mode=mode)
                    bulk[..., ::2, :, :] += field
                    bulk[..., 1::2, :, :] += dotmf(e2h, field, out=field)

                fft_field = dotmf(dmat1, fft_field, out=fft_field)
                out = fft_field
            else:
                fft_field = dotmf(tmat, fft_field, out=out)
                fft_field = dotmf(dmat1, fft_field, out=fft_field)
                out = fft_field
        else:
            if dmat1 is not None:
                fft_field = dotmf(dmat1, fft_field, out=out)
            out = fft_field
        field = ifft2(fft_field, out=out)
        field = dotmdmf(e, p, ei, field, out=field)
        fft_field = fft2(field, out=field)
        if dmat2 is not None:
            fft_field = dotmf(dmat2, fft_field, out=fft_field)
    #return fft_field, refl

    #out = ifft2(fft_field, out = out)

    if mode == +1 and bulk is not None:
        field = ifft2(fft_field)
        e2h = E2H_mat(fmat, mode=mode)
        bulk[..., 1::2, :, :] += dotmf(e2h, field)
        bulk[..., ::2, :, :] += field

    return fft_field, refl
Example #24
0
def _transfer_ray_2x2_2(field,
                        wavenumbers,
                        in_layer,
                        out_layer,
                        dmat=None,
                        beta=0,
                        phi=0,
                        nsteps=1,
                        mode=+1,
                        reflection=True,
                        betamax=BETAMAX,
                        refl=None,
                        bulk=None,
                        out=None,
                        tmpdata=None):
    _out = {} if tmpdata is None else tmpdata
    if in_layer is not None:
        d, epsv, epsa = in_layer
        alpha, fmat_in = alphaf(beta, phi, epsv, epsa, out=_out.get("afin"))
        if tmpdata is not None:
            _out["afin"] = alpha, fmat_in
    d, epsv, epsa = out_layer
    alpha, fmat = alphaf(beta, phi, epsv, epsa, out=_out.get("afout"))
    e = E_mat(fmat, mode=mode, copy=False)  #2x2 E-only view of fmat
    #    if refl is not None:
    #        ein = E_mat(fmat_in, mode = mode * (-1)) #reverse direction
    #
    #    if reflection == 0:
    #        kd = wavenumbers * d
    #    else:
    kd = wavenumbers * d / 2
    p = phase_mat(alpha, kd[..., None, None], mode=mode, out=_out.get("p"))

    ei0 = inv(e, out=_out.get("ei0"))
    ei = ei0

    if tmpdata is not None:
        _out["afout"] = alpha, fmat
        _out["ei0"] = ei
        _out["p"] = p

    for j in range(nsteps):
        #reflect only at the beginning
        if j == 0 and reflection != 0:
            #if we need to track reflections (multipass)
            if refl is not None:
                #ei,eri = Etri_mat(fmat_in, fmat, mode = mode, out = _out.get("eieri"))
                tmat, rmat = tr_mat(fmat_in,
                                    fmat,
                                    mode=mode,
                                    out=_out.get("eieri"))
                if tmpdata is not None:
                    #_out["eieri"] = ei,eri
                    _out["eieri"] = tmat, rmat
                trans = refl.copy()
                #refl = dotmf(eri, field, out = refl)
                refl = dotmf(rmat, field, out=refl)
                #field = dotmf(ei,field, out = out)
                field = dotmf(tmat, field, out=out)
                field = np.add(field, trans, out=field)

                if mode == -1 and bulk is not None:
                    #tmp_field = dotmf(e,field)
                    tmp_field = field
                    e2h = E2H_mat(fmat, mode=mode)
                    bulk[..., ::2, :, :] += tmp_field
                    bulk[..., 1::2, :, :] += dotmf(e2h, tmp_field)

                field = dotmf(ei, field, out=field)

                if d != 0.:
                    field = dotmf(dotmd(e, p), field, out=field)

                else:
                    field = dotmf(e, field, out=field)
                out = field

                #                rmat = dotmm(ein, eri, out = eri)
                #                trans = refl.copy()
                #                refl = dotmf(rmat, field, out = refl)
                #                ei0 = inv(e)
                #                field = dotmf(ei,field, out = out)
                #                field = dotmf(e,field) + trans
                #                if d != 0.:
                #                    field = dotmdmf(e,p,ei0,field, out = out)

                ei = ei0
            else:
                ei = Eti_mat(fmat_in, fmat, mode=mode, out=_out.get("eti"))
                field = dotmdmf(e, p, ei, field, out=out)
                out = field
                if tmpdata is not None:
                    _out["eti"] = ei
                ei = ei0
        else:
            #no need to compute if d == 0!.. identity
            if d != 0.:
                field = dotmdmf(e, p, ei, field, out=out)
                out = field
        if dmat is not None:
            field = diffract(field, dmat, out=out)
            out = field
        #no need to compute if d == 0!.. identity
        if d != 0.:
            field = dotmdmf(e, p, ei, field, out=out)

    if mode == +1 and bulk is not None:
        e2h = E2H_mat(fmat, mode=mode)
        bulk[..., 1::2, :, :] += dotmf(e2h, field)
        bulk[..., ::2, :, :] += field

    return field, refl
Example #25
0
#: in 4x4 we are propagating backward--- minus sign must be taken in the phase
p = tmm.phase_mat(a,-kd)

# uncoment this to test that setting backward propagating waves to zero, 
# you have single reflections only... -same result as 2x2 with reflection.
#p[...,1::2] = 0.

#4x4 characteristic matrix
m = dotmdm(f,p,fi)
#we could have built layer matrices directly, note the there is no negative value in front of kd:
#m = tmm.layer_mat(kd,eps_values, eps_angles, beta = beta, phi = phi)

#e field 2x22 matrix.. skip the first layer (air)
e = tmm.E_mat(f[1:], mode = +1)
# the inverse, no reflections
ei = linalg.inv(e)
# the inverse, with reflections
eti = tmm.Eti_mat(f[:-1], f[1:], mode = +1)
p2 = tmm.phase_mat(a,kd, mode = +1)[:,1:]

#2x2 characteristic matrix
m2 = dotmdm(e,p2,ei) #no reflections
m2t = dotmdm(e,p2,eti) #with reflections

# multiply matrices together over second axis (first axis is wavelenght, second are layers)
cmat = linalg.multi_dot(m, axis = 1) 

#the 2x2 matrices must be multiplied in reverse order... because we propagate forward
cmat2 = linalg.multi_dot(m2, axis = 1, reverse = True) 
cmat2t = linalg.multi_dot(m2t, axis = 1, reverse = True) 
Example #26
0
def _system_mat2d(fmatin, cmat, fmatout):
    """Computes a system matrix from a characteristic matrix Fin-1.C.Fout"""
    fmatini = inv(fmatin)
    out = bdotdm(fmatini, cmat)
    return bdotmd(out, fmatout)