# Path: cubical/kernels/generics.py
# def compute_2x2_inverse(x, xinv, flags, eps, flagbit):
# def compute_diag_inverse(x, xinv, flags, eps, flagbit):
# def compute_chisq(r, chisq):
# def compute_chisq_diag(r, chisq):
# def compute_chisq_offdiag(r, chisq):
# 
# Path: cubical/kernels/diag_complex.py
# def compute_residual(m, g, gh, r, t_int, f_int):
# def compute_jh(m, g, jh, t_int, f_int):
# def compute_update(jhr, jhjinv, upd):
# def compute_corrected(o, g, gh, corr, t_int, f_int):
# def apply_gains(m, g, gh, t_int, f_int):
# def right_multiply_gains(g, g_next, t_int, f_int):
# 
# Path: cubical/kernels/phase_only.py
# def compute_jhj(m, jhj, t_int=1, f_int=1):
# def compute_jhr(gh, jh, r, jhr, t_int=1, f_int=1):
# def compute_update(jhr, jhjinv, upd):
# 
# Path: cubical/kernels/tf_plane.py
# def allocate_param_array(shape, dtype, zeros=False):
# def compute_jhj(tmp_jhj, jhj, ts, fs, t_int, f_int):
# def compute_jhjinv(jhj, jhjinv, eps):
# def compute_jhr(tmp_jhr, jhr, ts, fs, t_int, f_int):
# def compute_update(jhr, jhj, upd):
# def construct_gains(param, g, ts, fs, t_int, f_int):


from builtins import range
from numba import jit, prange
from cubical.kernels import generics
from cubical.kernels import diag_complex
from cubical.kernels import phase_only
from cubical.kernels import tf_plane
import numpy as np
import cubical.kernels
            Number of frequencies per solution interval.
    """

    n_dir = g.shape[0]
    n_tim = g.shape[1]
    n_fre = g.shape[2]
    n_ant = g.shape[3]

    broadcast_times = np.array([t//t_int for t in range(n_tim)])
    broadcast_freqs = np.array([f//f_int for f in range(n_fre)])

    for aa in prange(n_ant):
        for t in range(n_tim):
            bt = broadcast_times[t]
            for f in range(n_fre):
                bf = broadcast_freqs[f]
                for d in range(n_dir):
                    for c in range(2):
                        p0cc = param[d,bt,bf,aa,0,c,c]
                        p1cc = param[d,bt,bf,aa,1,c,c]

                        g[d,t,f,aa,c,c] = np.exp(1j*(p0cc + fs[f]*p1cc))


# Cherry-pick other methods from standard kernels

# inner_jhj is just a phase J^H.J, with intervals of 1,1
compute_inner_jhj = lambda m,jhj1: phase_only.compute_jhj(m, jhj1, 1, 1)

# inner_jhr is just a phase J^H.R with intervals of 1,1

# Path: cubical/kernels/generics.py
# def compute_2x2_inverse(x, xinv, flags, eps, flagbit):
# def compute_diag_inverse(x, xinv, flags, eps, flagbit):
# def compute_chisq(r, chisq):
# def compute_chisq_diag(r, chisq):
# def compute_chisq_offdiag(r, chisq):
# 
# Path: cubical/kernels/diag_complex.py
# def compute_residual(m, g, gh, r, t_int, f_int):
# def compute_jh(m, g, jh, t_int, f_int):
# def compute_update(jhr, jhjinv, upd):
# def compute_corrected(o, g, gh, corr, t_int, f_int):
# def apply_gains(m, g, gh, t_int, f_int):
# def right_multiply_gains(g, g_next, t_int, f_int):
# 
# Path: cubical/kernels/phase_only.py
# def compute_jhj(m, jhj, t_int=1, f_int=1):
# def compute_jhr(gh, jh, r, jhr, t_int=1, f_int=1):
# def compute_update(jhr, jhjinv, upd):
# 
# Path: cubical/kernels/tf_plane.py
# def allocate_param_array(shape, dtype, zeros=False):
# def compute_jhj(tmp_jhj, jhj, ts, fs, t_int, f_int):
# def compute_jhjinv(jhj, jhjinv, eps):
# def compute_jhr(tmp_jhr, jhr, ts, fs, t_int, f_int):
# def compute_update(jhr, jhj, upd):
# def construct_gains(param, g, ts, fs, t_int, f_int):


# Path: cubical/kernels/f_slope.py
from builtins import range
from numba import jit, prange
from cubical.kernels import generics
from cubical.kernels import diag_complex
from cubical.kernels import phase_only
from cubical.kernels import tf_plane
import numpy as np
import cubical.kernels

            Number of frequencies per solution interval.
    """

    n_dir = g.shape[0]
    n_tim = g.shape[1]
    n_fre = g.shape[2]
    n_ant = g.shape[3]

    broadcast_times = np.array([t//t_int for t in range(n_tim)])
    broadcast_freqs = np.array([f//f_int for f in range(n_fre)])

    for aa in prange(n_ant):
        for t in range(n_tim):
            bt = broadcast_times[t]
            for f in range(n_fre):
                bf = broadcast_freqs[f]
                for d in range(n_dir):
                    for c in range(2):
                        p0cc = param[d,bt,bf,aa,0,c,c]
                        p1cc = param[d,bt,bf,aa,1,c,c]

                        g[d,t,f,aa,c,c] = np.exp(1j*(p0cc + fs[f]*p1cc))


# Cherry-pick other methods from standard kernels

# inner_jhj is just a phase J^H.J, with intervals of 1,1
compute_inner_jhj = lambda m,jhj1: phase_only.compute_jhj(m, jhj1, 1, 1)

# inner_jhr is just a phase J^H.R with intervals of 1,1

compute_inner_jhr = lambda jh,gh,r,jhr1: phase_only.compute_jhr(jh, gh, r, jhr1, 1, 1)