Created
January 30, 2026 10:29
-
-
Save kumanna/af9421db03e6e83855fdca0383788931 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "id": "be9d289c", | |
| "metadata": {}, | |
| "source": [ | |
| "# Quick introduction to OTFS\n", | |
| "Follows the paper [\"Derivation of OTFS Modulation From First Principles\" by Prof. Saif Mohammed](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9392379)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "85c32381", | |
| "metadata": {}, | |
| "source": [ | |
| "We base our consideration on equation (19) in the paper, which discusses the construction of the signals $\\alpha_{(k,l)}(t)$." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "id": "d93f5f8f", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import numpy as np\n", | |
| "import matplotlib.pyplot as plt\n", | |
| "\n", | |
| "T = 1\n", | |
| "delta_f = 1 / T\n", | |
| "M = 8\n", | |
| "N = 8\n", | |
| "OVERSAMPLING = 128\n", | |
| "t = np.arange(-10 * N * M * T, 10 * N * T * M, 1 / OVERSAMPLING)\n", | |
| "\n", | |
| "def alpha_kl(k, l, t, M, N, T):\n", | |
| " s = np.zeros_like(t, dtype='complex')\n", | |
| " delta_f = 1 / T\n", | |
| " for n in range(N):\n", | |
| " EXPPARAM = (t - l * T / M - n * T)\n", | |
| " s_ = np.exp(1j * 2 * np.pi * n * k / N) * \\\n", | |
| " np.exp(1j * np.pi * delta_f * M * EXPPARAM) * \\\n", | |
| " np.sinc(delta_f * M * EXPPARAM) * M * delta_f\n", | |
| " s = s + s_\n", | |
| " return np.sqrt(T / M / N) * s" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f97f5fc6", | |
| "metadata": {}, | |
| "source": [ | |
| "We can initialize all of the $\\alpha_{(k,l)}$ signals into an array for convenience." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "id": "1d32efb7", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "sample_vector = alpha_kl(0, 0, t, M, N, T)\n", | |
| "vector_len = len(sample_vector)\n", | |
| "\n", | |
| "# Initialize a 3D array of zeros\n", | |
| "# Shape: (M rows, N columns, vector_len depth)\n", | |
| "alpha_array = np.zeros((M, N, vector_len), dtype='complex')\n", | |
| "\n", | |
| "# Populate the array using nested loops\n", | |
| "for k in range(M):\n", | |
| " for l in range(N):\n", | |
| " alpha_array[k, l, :] = alpha_kl(k, l, t, M, N, T)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "60d9fe9d", | |
| "metadata": {}, | |
| "source": [ | |
| "Let us now suppose that w intend sending four symbols using some of these signals. One way to do it is this:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "id": "3f8771dc", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Send symbols on these\n", | |
| "symbols = np.array([1, 1j, 1+1j, -1j])\n", | |
| "waveform = np.zeros_like(alpha_array[0][0], dtype='complex')\n", | |
| "\n", | |
| "waveform += symbols[0] * alpha_array[0][0]\n", | |
| "waveform += symbols[1] * alpha_array[0][1]\n", | |
| "waveform += symbols[2] * alpha_array[1][0]\n", | |
| "waveform += symbols[3] * alpha_array[1][1]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "200511d1", | |
| "metadata": {}, | |
| "source": [ | |
| "Using the orthogonality of the $\\alpha_{k,l}$ signals, we can recover our data:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "id": "e8b1a953", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[ 1.+0.j 0.+1.j 1.+1.j -0.-1.j]\n", | |
| "[ 9.99841680e-01-1.58318873e-04j -1.58320298e-04+9.99841681e-01j\n", | |
| " 1.00000000e+00+9.99999999e-01j 1.94412130e-09-1.00000000e+00j]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Recover the symbols\n", | |
| "symbols_recovered = np.zeros_like(symbols, dtype='complex')\n", | |
| "symbols_recovered[0] = np.trapezoid(waveform * np.conj(alpha_array[0][0]), t)\n", | |
| "symbols_recovered[1] = np.trapezoid(waveform * np.conj(alpha_array[0][1]), t)\n", | |
| "symbols_recovered[2] = np.trapezoid(waveform * np.conj(alpha_array[1][0]), t)\n", | |
| "symbols_recovered[3] = np.trapezoid(waveform * np.conj(alpha_array[1][1]), t)\n", | |
| "print(symbols)\n", | |
| "print(symbols_recovered)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "be3b96f9", | |
| "metadata": {}, | |
| "source": [ | |
| "Let's take a single symbol separately and add a delay and doppler offset to see what happens." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "163271ec", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "(0.9998416173283038-1.4934538260588343e-18j)\n", | |
| "(0.9399505342307242+1.2242106723840473e-10j)\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "waveform = symbols[0] * alpha_array[0][0]\n", | |
| "waveform_delay = np.roll(waveform, OVERSAMPLING // M * 2) # Delay by 2 * T / M units of time\n", | |
| "print(np.trapezoid(waveform_delay * np.conj(alpha_array[0][2]), t))\n", | |
| "# In addition, add an extra 2 / N / T Doppler modulation\n", | |
| "waveform_delay_doppler = np.roll(waveform * np.exp(1j * 2 * np.pi * 2 / T / N * t), OVERSAMPLING // M * 2)\n", | |
| "print(np.trapezoid(waveform_delay_doppler * np.conj(alpha_array[2][2]), t))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ddb265aa", | |
| "metadata": {}, | |
| "source": [ | |
| "More realistic channels consist of multiple reflectors. Let's take them as triplets." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 28, | |
| "id": "a42928a0", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "image/png": "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", | |
| "text/plain": [ | |
| "<Figure size 640x480 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "triplets = [\n", | |
| " # (gain, normalized time delay, normalized doppler shift)\n", | |
| " # normalized means between 0 and M - 1 and 0 and N - 1\n", | |
| " (1.0+1j, 4, 4),\n", | |
| " (0.5-0.5j, 3, 1),\n", | |
| " ]\n", | |
| "\n", | |
| "actual_signal = np.zeros_like(t) * 0.0j\n", | |
| "for i in triplets:\n", | |
| " gain, time_delay, doppler = i\n", | |
| " actual_signal += np.roll(waveform * np.exp(1j * 2 * np.pi * doppler / T / N * t), OVERSAMPLING // M * time_delay)\n", | |
| "\n", | |
| "dd_domain_rx = np.zeros((M, N), dtype='complex')\n", | |
| "for k in range(M):\n", | |
| " for l in range(N):\n", | |
| " dd_domain_rx[k][l] = np.trapezoid(actual_signal * np.conj(alpha_array[k][l]), t)\n", | |
| "plt.imshow(np.abs(dd_domain_rx))\n", | |
| "plt.show()" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3 (ipykernel)", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.13.5" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment