Terms
Description
transition_matrices() in differt/em/_utils.py:307 has a skeleton but raises NotImplementedError. It accepts vertices, objects, interaction_types, object_normals, computes ray direction vectors, makes a zero Jones matrix, then hits mat_r = mat # TODO: fixme and gives up.
This is the function that should compute the 2x2 Jones transfer matrix for a whole path, accumulating all reflections and diffractions. Without it, multi-bounce polarization tracking doesn't work, and interaction_types on Paths goes unused.
@jax.jit
def transition_matrices(
vertices: Float[ArrayLike, "*batch path_length 3"],
objects: Int[ArrayLike, "*batch path_length"],
interaction_types: Int[ArrayLike, "*batch path_length-2"],
object_normals: Float[ArrayLike, "num_objects 3"],
*,
n_r: Inexact[ArrayLike, " num_objects"] | None = None,
wavenumber: Float[ArrayLike, ""] | None = None,
wedge_angles: Float[ArrayLike, " num_objects"] | None = None,
) -> Complex[Array, "*batch 2 2"]:
"""2x2 Jones transfer matrix per path.
T = R_N @ M_N @ ... @ R_1 @ M_1
"""
Implementation would be jax.lax.scan over interaction points, with jax.lax.switch on interaction_types to pick reflection vs diffraction coefficients. The building blocks are there: sp_directions, sp_rotation_matrix, fresnel_coefficients. Getting the basis rotation chain right across N interactions is the hard part. sp_rotation_matrix does one rotation; chaining them needs careful bookkeeping of which frame you're in.
I think this makes sense in two phases. First: reflection only, using existing Fresnel + sp_rotation infrastructure. Then add diffraction once #429 lands.
The companion compute_received_fields issue can start without this (just apply Fresnel directly like deepmimo.py does), but eventually this becomes the cleaner way to do it, and it's the right fix for the multi-bounce polarization errors that tripped up #355.
For validation: single reflection against the worked example in reflection_coefficients docstring, identity matrix for LOS paths, and reciprocity check (T for TX->RX should equal transpose of T for RX->TX).
#427 (compute_received_fields) can work without this initially, but should eventually use it internally. The diffraction branch needs both #429 (UTD coefficients, for D_s, D_h) and #428 (edge detection, for wedge_angles). #355 got stuck on multi-bounce polarization; this is what's actually needed to fix that.
Terms
Description
transition_matrices()indiffert/em/_utils.py:307has a skeleton but raisesNotImplementedError. It accepts vertices, objects, interaction_types, object_normals, computes ray direction vectors, makes a zero Jones matrix, then hitsmat_r = mat # TODO: fixmeand gives up.This is the function that should compute the 2x2 Jones transfer matrix for a whole path, accumulating all reflections and diffractions. Without it, multi-bounce polarization tracking doesn't work, and
interaction_typesonPathsgoes unused.Implementation would be
jax.lax.scanover interaction points, withjax.lax.switchoninteraction_typesto pick reflection vs diffraction coefficients. The building blocks are there:sp_directions,sp_rotation_matrix,fresnel_coefficients. Getting the basis rotation chain right across N interactions is the hard part.sp_rotation_matrixdoes one rotation; chaining them needs careful bookkeeping of which frame you're in.I think this makes sense in two phases. First: reflection only, using existing Fresnel + sp_rotation infrastructure. Then add diffraction once #429 lands.
The companion
compute_received_fieldsissue can start without this (just apply Fresnel directly likedeepmimo.pydoes), but eventually this becomes the cleaner way to do it, and it's the right fix for the multi-bounce polarization errors that tripped up #355.For validation: single reflection against the worked example in
reflection_coefficientsdocstring, identity matrix for LOS paths, and reciprocity check (T for TX->RX should equal transpose of T for RX->TX).#427 (
compute_received_fields) can work without this initially, but should eventually use it internally. The diffraction branch needs both #429 (UTD coefficients, for D_s, D_h) and #428 (edge detection, forwedge_angles). #355 got stuck on multi-bounce polarization; this is what's actually needed to fix that.