Skip to content

Instantly share code, notes, and snippets.

@avivajpeyi
Created October 29, 2025 23:02
Show Gist options
  • Select an option

  • Save avivajpeyi/3083790412049a4e33fff9d7e5ce6767 to your computer and use it in GitHub Desktop.

Select an option

Save avivajpeyi/3083790412049a4e33fff9d7e5ce6767 to your computer and use it in GitHub Desktop.
tdi_for_glitches.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyPV7LfPA1k90adY8V1RQ6Pt",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/avivajpeyi/3083790412049a4e33fff9d7e5ce6767/tdi_for_glitches.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"source": [
"# TDI for glitches\n",
"\n",
"For each of the two optical benches per MOSA, there are associated intermediary variables $\\xi_{ij}$ and $\\eta_{ij}$ constructed to mitigate spacecraft jitter and to reduce the six laser links to three independent effective links.\n",
"The $\\xi_{ij}$ combinations have the form\n",
"\\begin{equation}\n",
" \\xi_{12}\n",
" =\n",
" \\text{isi}_{12}\n",
" +\n",
" \\frac{\\text{rfi}_{12}-\\text{tmi}_{12}}{2}\n",
" +\n",
" \\frac{\\textbf{D}(\\text{rfi}_{21}-\\text{tmi}_{21})}{2},\n",
"\\end{equation}\n",
"whose subsequent index combinations $(ij)$ are obtained by rotation and reflection of the indices.\n",
"The $\\eta_{ij}$ combinations have the form\n",
"\\begin{equation}\n",
" \\eta_{12}\n",
" =\n",
" \\xi_{12}\n",
" +\n",
" \\frac{\\textbf{D}(\\text{rfi}_{21}-\\text{rfi}_{23})}{2},\\\\\n",
" \\eta_{13}\n",
" =\n",
" \\xi_{13}\n",
" +\n",
" \\frac{\\text{rfi}_{12}-\\text{rfi}_{13}}{2},\n",
"\\end{equation}\n",
"whose subsequent index combinations are obtained by cyclic permutation.\n",
"\n",
"\n",
"\n",
"We can then express the first-generation Michelson variable for a static LISA configuration as\n",
"\\begin{equation}\n",
" X_1\n",
" \\approx\n",
" (1-\\textbf{D}^2)[\\eta_{13}+\\textbf{D}\\eta_{31} - \\eta_{12} - \\textbf{D}\\eta_{21}],\n",
"\\end{equation}\n",
"and obtain $Y_1$ and $Z_1$ by cyclic permutation of indices.\n",
"The second-generation Michelson variable is\n",
"\\begin{equation}\n",
" X_2 \\approx (1 - \\textbf{D}^4) X_{1}\n",
"\\end{equation}\n",
"\n",
"\n",
"We can write the final expression for $X_2$ by plugging in $X_1$, and the various $\\eta_{ij}$:\n"
],
"metadata": {
"id": "qMM1eORgKGGS"
}
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "mTPT273wF1Y8",
"outputId": "21b789fd-e9cf-4f5c-bb6f-8cc6b6ea5c6c"
},
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Latex output:\n",
"\\begin{equation}\n",
"X_{2} = \\frac{\\left(\\mathbf{D} - 1\\right)^{2} \\left(\\mathbf{D} + 1\\right)^{2} \\left(\\mathbf{D}^{2} + 1\\right) \\left(\\mathbf{D}^{2} \\text{tmi}_{12} - \\mathbf{D}^{2} \\text{tmi}_{13} + 2 \\mathbf{D} \\text{tmi}_{21} - 2 \\mathbf{D} \\text{tmi}_{31} + \\text{tmi}_{12} - \\text{tmi}_{13}\\right)}{2}\n",
"\\end{equation}\n"
]
}
],
"source": [
"import sympy as sp\n",
"\n",
"# 1. Define symbols\n",
"# ------------------------------------------------------------------\n",
"D = sp.Symbol(\"D\", commutative=True) # static equal-arm delay operator\n",
"half = sp.Rational(1, 2)\n",
"\n",
"# Measurements (tmi_ij)\n",
"t12, t13, t21, t31 = sp.symbols(\"tmi_{12} tmi_{13} tmi_{21} tmi_{31}\")\n",
"\n",
"# η_ij variables\n",
"eta12, eta13, eta21, eta31 = sp.symbols(\"eta_{12} eta_{13} eta_{21} eta_{31}\")\n",
"\n",
"# 2. Glitch-only substitution: η_ij = -(1/2) (tmi_ij + D * tmi_ji)\n",
"# ------------------------------------------------------------------\n",
"eta_subs = {\n",
" eta12: -half * (t12 + D * t21),\n",
" eta13: -half * (t13 + D * t31),\n",
" eta21: -half * (t21 + D * t12),\n",
" eta31: -half * (t31 + D * t13),\n",
"}\n",
"\n",
"# 3. First- and second-generation Michelson combinations\n",
"# ------------------------------------------------------------------\n",
"X1_eta = (1 - D**2) * (eta13 + D*eta31 - eta12 - D*eta21)\n",
"X2_eta = (1 - D**4) * X1_eta\n",
"\n",
"# Substitute η_ij → tmi_ij\n",
"X2_tmi = sp.simplify(sp.expand(X2_eta.subs(eta_subs)))\n",
"X2_tmi = sp.simplify(sp.factor(X2_tmi))\n",
"\n",
"\n",
"# 4. Print results\n",
"# ------------------------------------------------------------------\n",
"\n",
"# LaTeX-ready equation\n",
"latex_expr = sp.latex(sp.Eq(sp.Symbol(\"X_2\"), X2_tmi))\n",
"latex_expr = latex_expr.replace(\"D\", \"\\\\mathbf{D}\")\n",
"latex_expr = latex_expr.replace(\"tmi\", \"\\\\text{tmi}\")\n",
"print(\"Latex output:\\n\\\\begin{equation}\")\n",
"print(str(latex_expr))\n",
"print(\"\\\\end{equation}\")\n"
]
},
{
"cell_type": "markdown",
"source": [
"Expression obtained from Sympy:\n",
"\n",
"\\begin{equation}\n",
"X_{2} = \\frac{\\left(\\mathbf{D} - 1\\right)^{2} \\left(\\mathbf{D} + 1\\right)^{2} \\left(\\mathbf{D}^{2} + 1\\right) \\left(\\mathbf{D}^{2} \\text{tmi}_{12} - \\mathbf{D}^{2} \\text{tmi}_{13} + 2 \\mathbf{D} \\text{tmi}_{21} - 2 \\mathbf{D} \\text{tmi}_{31} + \\text{tmi}_{12} - \\text{tmi}_{13}\\right)}{2}\n",
"\\end{equation}\n",
"\n",
"\n",
"Latex expression obtained by hand:\n",
"\n",
"\\begin{equation}\n",
"X_2\n",
"= \\frac{1}{2}(1 - \\textbf{D}^4)^2\\bigl(\\text{tmi}_{12} - \\text{tmi}_{13}\\bigr)\n",
" + \\textbf{D}(1 - \\textbf{D}^4)(1 - \\textbf{D}^2)\\bigl(\\text{tmi}_{21} - \\text{tmi}_{31}\\bigr).\n",
"\\end{equation}\n",
"\n",
"\n",
"We can now check if the two match:\n"
],
"metadata": {
"id": "s4uSP3zMG_to"
}
},
{
"cell_type": "code",
"source": [
"# Analytic target form for validation\n",
"# ------------------------------------------------------------------\n",
"X2_target = half*(1 - D**4)**2 * (t12 - t13) + D*(1 - D**4)*(1 - D**2)*(t21 - t31)\n",
"\n",
"# Check equivalence\n",
"print(\"Does sympy match the hand derived expression?: \", sp.simplify(X2_tmi - X2_target) == 0)\n"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "BrMByVOGLXgS",
"outputId": "958b38b1-1f95-48f0-fa02-0fa0af9924a1"
},
"execution_count": 14,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Does sympy match the hand derived expression?: True\n"
]
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment