Skip to content

Instantly share code, notes, and snippets.

@alisterburt
Created December 4, 2022 21:04
Show Gist options
  • Select an option

  • Save alisterburt/1ee49bdfcea46b87faad44504696e402 to your computer and use it in GitHub Desktop.

Select an option

Save alisterburt/1ee49bdfcea46b87faad44504696e402 to your computer and use it in GitHub Desktop.
symmetrise rfft
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "f41114dd-556b-47d9-8dee-f8205a1729f0",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/alisterburt/mambaforge/envs/libtilt/lib/python3.10/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n"
]
}
],
"source": [
"import torch"
]
},
{
"cell_type": "markdown",
"id": "779a475c-d568-49a4-a669-0cbac398f40c",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"# 1d case"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "770dd81b-3301-40dc-aadb-9fb1ddcd864c",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"tensor([0.7233, 0.9658, 0.8935, 0.1781, 0.0599, 0.8690])"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a = torch.rand(6)\n",
"a"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "692fb044-76df-4fb5-b527-26f86b7cf796",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(tensor([ 3.6897+0.0000j, 0.9859-0.8057j, -0.4927+0.6381j, -0.3361+0.0000j]),\n",
" torch.Size([4]))"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rfft = torch.fft.rfftn(a)\n",
"rfft, rfft.shape"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "75a9bd24-09cf-4fdc-b9ff-c2a39c0d0020",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(tensor([ 3.6897+0.0000j, 0.9859-0.8057j, -0.4927+0.6381j, -0.3361+0.0000j,\n",
" -0.4927-0.6381j, 0.9859+0.8057j]),\n",
" torch.Size([6]))"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fft = torch.fft.fftn(a)\n",
"fft, fft.shape"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "e3b6bb20-afef-4990-83e4-0d7a91504243",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fftfreq: tensor([ 0.0000, 0.1667, 0.3333, -0.5000, -0.3333, -0.1667])\n",
"rfftfreq: tensor([0.0000, 0.1667, 0.3333, 0.5000])\n",
"fftshifted fftfreq: tensor([-0.5000, -0.3333, -0.1667, 0.0000, 0.1667, 0.3333])\n",
"desired output: tensor([-0.5000, -0.3333, -0.1667, 0.0000, 0.1667, 0.3333, 0.5000])\n"
]
}
],
"source": [
"print('fftfreq: ', torch.fft.fftfreq(6))\n",
"print('rfftfreq: ',torch.fft.rfftfreq(6))\n",
"print('fftshifted fftfreq: ', torch.fft.fftshift(torch.fft.fftfreq(6)))\n",
"desired_output = torch.empty(7)\n",
"desired_output[:6] = torch.fft.fftshift(torch.fft.fftfreq(6))\n",
"desired_output[6] = -desired_output[0]\n",
"print('desired output: ', desired_output) "
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "59dd68fb-6f94-4316-a464-5d3b4fe7f9c9",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"tensor([-0.3361-0.0000j, -0.4927-0.6381j, 0.9859+0.8057j, 3.6897+0.0000j,\n",
" 0.9859-0.8057j, -0.4927+0.6381j, -0.3361+0.0000j])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def rfft_to_symmetrised_dft_1d(rfft: torch.Tensor) -> torch.Tensor:\n",
" r = 2 * (rfft.shape[0] - 1)\n",
" output = torch.zeros(r + 1, dtype=torch.complex64)\n",
" dc = r // 2\n",
" output[dc:] = rfft\n",
" output[:dc] = torch.conj(torch.flip(rfft[1:], dims=(0, )))\n",
" return output\n",
"\n",
"rfft_to_symmetrised_dft_1d(rfft)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "cde5d90c-1603-4dee-881a-abe8625d2d65",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"tensor([-0.3361+0.0000j, -0.4927-0.6381j, 0.9859+0.8057j, 3.6897+0.0000j,\n",
" 0.9859-0.8057j, -0.4927+0.6381j])"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"torch.fft.fftshift(torch.fft.fftn(a))"
]
},
{
"cell_type": "markdown",
"id": "1e247dbe-5f39-4979-9b3b-1fb7b9aa9779",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"# 2D case"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c02ca3ba-5c66-41f9-bf33-d3ab3bb79bc5",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "0e35f4fe-fa91-432e-80ac-b8b4ef8fa23e",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"a = torch.rand((10, 10))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "132e6596-a4dd-421f-84bc-1aa60579b549",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"fft = torch.fft.fftshift(torch.fft.fftn(a, dim=(-2, -1)), dim=(-2, -1))\n",
"rfft = torch.fft.rfftn(a, dim=(-2, -1))\n",
"rfft_shifted = torch.fft.fftshift(rfft, dim=(-2, ))"
]
},
{
"cell_type": "markdown",
"id": "eb679978-281a-4b94-a632-8cb1e5ac74f3",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"check out the hermitian symmetry... around DC component, not true image center"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "401e78a7-0875-48b8-a7d4-6a9172705a00",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([ 0.0000, 0.1000, 0.2000, 0.3000, 0.4000, -0.5000, -0.4000, -0.3000,\n",
" -0.2000, -0.1000])\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 640x480 with 3 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, 3)\n",
"ax[0].imshow(torch.real(fft))\n",
"ax[1].imshow(torch.real(rfft))\n",
"ax[2].imshow(torch.real(rfft_shifted))\n",
"print(torch.fft.fftfreq(10))"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "41dc2514-f51b-4ff5-9abc-3663ebecf6f7",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"b = torch.zeros((11, 11), dtype=torch.complex64)\n",
"dc = 5\n",
"b[:-1, dc:] = rfft_shifted"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "1d1478e2-fa03-4056-b18d-4e7e457dfe97",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x111cab010>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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ktJaL1qPIEny+ZLkz4YxX+zKbR3HFRAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMJDxAK1eulM/nU3V1daKXAgCkkIQGqKmpSa+99pruv//+RC4DAEhBCQvQl19+qfLycm3cuFHDhw9P1DIAgBSVsABVVlZqzpw5Kisr+6fHRaNRRSKRHhsAoP9LyBNRt2/frpaWFjU1Nd3y2FAopJdffjkRYwAAkpjnV0Ctra1avHixtmzZoszMzFseX1tbq3A43L21trZ6PRIAIAl5fgXU3Nysjo4OPfDAA937YrGYDhw4oFdffVXRaFR+v7/7tUAgoEAg4PUYAIAk53mAZs6cqQ8//LDHvoULF2r8+PF66aWXesQHADBweR6g7OxsFRcX99g3ZMgQjRw58ob9AICBizshAABMJORTcP9o3759fbEMACCFcAUEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAw0Sd3QgD6k//c/5b1CJKkOQ/9h/UISrvYZT3CNSOC1hNIkuKZGdYjKO2/kuCRNu7ybR3GFRAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMBEuvUAQKr590eesB5BkuRzV6xHkO+rqPUI18Ti1hNIktzHZ6xHkP7tXusJpFhUitz6MK6AAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATCQnQF198oaeeekojR45UVlaWJk2apGPHjiViKQBAivL8btgXLlxQaWmpHn30Ub377ru66667dObMGQ0fPtzrpQAAKczzAK1atUqFhYV64403uvcVFRV5vQwAIMV5/iO4d955RyUlJXryySeVk5OjKVOmaOPGjTc9PhqNKhKJ9NgAAP2f5wH69NNP1dDQoHHjxukPf/iDnnvuOS1atEibN2/u9fhQKKRgMNi9FRYWej0SACAJ+ZxzzstvmJGRoZKSEr3//vvd+xYtWqSmpiYdOnTohuOj0aii0etPVYxEIiosLNTMexYp3R/wcjTAGz6f9QSSJN9l+yei6mrMeoJrMgZZTyBJunr2M+sR5E+CJ6JejUXV+Em9wuGwhg4detPjPL8Cys/P14QJE3rsu++++/T555/3enwgENDQoUN7bACA/s/zAJWWlurUqVM99p0+fVp3332310sBAFKY5wF6/vnndfjwYb3yyiv65JNPtHXrVr3++uuqrKz0eikAQArzPEBTp07Vzp07tW3bNhUXF2v58uWqr69XeXm510sBAFKY5/8fkCQ9/vjjevzxxxPxrQEA/QT3ggMAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJhIyJ0QgH7tYqf1BJIkNyzbegTFRyTH3ev958PWI0hKjkchuCR4NIWLxW/rOK6AAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJtKtBwBSjotbTyBJ8n192XoEpV0IW48gSYqPzrUeQZKU1vY36xHkG5xlPYLS4tHbOy7BcwAA0CsCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwITnAYrFYqqrq1NRUZGysrJ07733avny5XLOeb0UACCFeX437FWrVqmhoUGbN2/WxIkTdezYMS1cuFDBYFCLFi3yejkAQIryPEDvv/++5s2bpzlz5kiSxo4dq23btuno0aNeLwUASGGe/wjuoYceUmNjo06fPi1J+uCDD3Tw4EHNnj271+Oj0agikUiPDQDQ/3l+BbRkyRJFIhGNHz9efr9fsVhMK1asUHl5ea/Hh0Ihvfzyy16PAQBIcp5fAb355pvasmWLtm7dqpaWFm3evFm/+tWvtHnz5l6Pr62tVTgc7t5aW1u9HgkAkIQ8vwJ64YUXtGTJEi1YsECSNGnSJH322WcKhUKqqKi44fhAIKBAIOD1GACAJOf5FdClS5eUltbz2/r9fsXjca+XAgCkMM+vgObOnasV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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"ax.imshow(torch.real(b))"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "457ccd32-41f9-4bc3-b167-5b8fcd450eb7",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"b[-1, dc:] = rfft_shifted[0, :]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "8c5835df-e765-47a3-af30-169088457921",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x111caa920>"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAGdCAYAAABU0qcqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAX+UlEQVR4nO3db2xUdb7H8c90SqeFlOGfbelSpBpuEIosWiBYs66hkXCRCzExS1I3DSarcctCbaLS3QViWBxgd0kDEkCSFTbLPx8IuuTKhtsVCJE/hYIr0QW8Eh1l2y67MFOLDjDzuw+4llspC1zP9Dszfb+S86Bnjj3fHGDePdPjOT7nnBMAAD0sy3oAAEDvRIAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAICJbOsBvi2RSOjcuXPKz8+Xz+ezHgcAcIecc2pvb1dxcbGysm5+npNyATp37pxKSkqsxwAAfEfhcFjDhg276espF6D8/HxJ0iMjnlV2VsB4GqAbOX2sJ5AkXe2faz2C+pz7p/UI16TIHcUSg/pbj6Csf0SsR9DVxGXtbXm98/38ZlIuQN987JadFVC2nwAhBflTI0DKtg9QyvyQmCoBSoH3rKxU+TORbvlrFC5CAACYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmEhagNasWaMRI0YoNzdXkyZN0pEjR5K1KwBAGkpKgLZv3666ujotXrxYzc3NGjdunKZOnaq2trZk7A4AkIaSEqCVK1fqJz/5iebMmaPRo0dr3bp16tu3r373u98lY3cAgDTkeYAuX76sY8eOqbKy8vpOsrJUWVmpgwcP3rB9LBZTNBrtsgAAMp/nATp//rzi8bgKCwu7rC8sLFRLS8sN24dCIQWDwc6FZwEBQO9gfhVcfX29IpFI5xIOh61HAgD0AM+fBzRkyBD5/X61trZ2Wd/a2qqioqIbtg8EAgoEUuf5FQCAnuH5GVBOTo4efPBBNTY2dq5LJBJqbGzU5MmTvd4dACBNJeWJqHV1daqurlZ5ebkmTpyohoYGdXR0aM6cOcnYHQAgDSUlQD/60Y/097//XYsWLVJLS4u+//3va/fu3TdcmAAA6L2SEiBJmjt3rubOnZusbw8ASHPmV8EBAHonAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADCRtFvxABnratx6AklSn5aL1iPIXbpkPcI1BYOtJ5AkXR7c13oEBa7Y//108T7SuVtvxxkQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACayrQcA0s4/L1pPIElKFN1lPYJ87V9ajyBJujqgr/UIkqTA5xetR5Dvatx6BPkSl29rO86AAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYMLzAIVCIU2YMEH5+fkqKCjQrFmzdOrUKa93AwBIc54HaN++faqpqdGhQ4e0Z88eXblyRY899pg6Ojq83hUAII15/jyg3bt3d/l648aNKigo0LFjx/SDH/zA690BANJU0h9IF4lEJEmDBg3q9vVYLKZYLNb5dTQaTfZIAIAUkNSLEBKJhGpra1VRUaGysrJutwmFQgoGg51LSUlJMkcCAKSIpAaopqZGJ0+e1LZt2266TX19vSKRSOcSDoeTORIAIEUk7SO4uXPnateuXdq/f7+GDRt20+0CgYACgUCyxgAApCjPA+Sc089+9jPt2LFDe/fuVWlpqde7AABkAM8DVFNToy1btuitt95Sfn6+WlpaJEnBYFB5eXle7w4AkKY8/x3Q2rVrFYlE9MMf/lBDhw7tXLZv3+71rgAAaSwpH8EBAHAr3AsOAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgIukPpAMyji81fm7zxS5bjyAVDLaeQJKUfb7degRJksvLsR5BLtHHegQl4r7b2i41/iUBAHodAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAExkWw8ApJ0B+dYTXHOx3XoCJe4utB5BkpQVvmg9giTJ50uRvxvGfPErt7UdZ0AAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwkfQALVu2TD6fT7W1tcneFQAgjSQ1QE1NTVq/fr3uv//+ZO4GAJCGkhagL7/8UlVVVdqwYYMGDhyYrN0AANJU0gJUU1Oj6dOnq7Ky8l9uF4vFFI1GuywAgMyXlCeibtu2Tc3NzWpqarrltqFQSC+//HIyxgAApDDPz4DC4bDmz5+vzZs3Kzc395bb19fXKxKJdC7hcNjrkQAAKcjzM6Bjx46pra1NDzzwQOe6eDyu/fv369VXX1UsFpPf7+98LRAIKBAIeD0GACDFeR6gKVOm6IMPPuiybs6cORo1apReeumlLvEBAPRengcoPz9fZWVlXdb169dPgwcPvmE9AKD34k4IAAATSbkK7tv27t3bE7sBAKQRzoAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmeuROCEAm+c99b1qPIEma/tB/WI+grIsd1iNcMyhoPYEkKZGbYz2Csv47BR5p4y7f1macAQEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAExkWw8ApJt/f+QJ6xEkST53xXoE+b6KWY9wTTxhPYEkyX10xnoE6d/utZ5Aisek6K034wwIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADCRlAB98cUXeuqppzR48GDl5eVp7NixOnr0aDJ2BQBIU57fDfvChQuqqKjQo48+qnfeeUd33XWXzpw5o4EDB3q9KwBAGvM8QMuXL1dJSYlef/31znWlpaVe7wYAkOY8/wju7bffVnl5uZ588kkVFBRo/Pjx2rBhw023j8ViikajXRYAQObzPECffPKJ1q5dq5EjR+pPf/qTnnvuOc2bN0+bNm3qdvtQKKRgMNi5lJSUeD0SACAF+ZxzzstvmJOTo/Lycr333nud6+bNm6empiYdPHjwhu1jsZhisetPVYxGoyopKdGUe+Yp2x/wcjTAGz6f9QSSJN9l+yei6mrceoJrcvpYTyBJunr2U+sR5E+BJ6JejcfU+HGDIpGI+vfvf9PtPD8DGjp0qEaPHt1l3X333afPPvus2+0DgYD69+/fZQEAZD7PA1RRUaFTp051WXf69GndfffdXu8KAJDGPA/Q888/r0OHDumVV17Rxx9/rC1btui1115TTU2N17sCAKQxzwM0YcIE7dixQ1u3blVZWZmWLFmihoYGVVVVeb0rAEAa8/z/A5Kkxx9/XI8//ngyvjUAIENwLzgAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAICJpNwJAchoF9utJ5AkuQH51iMoMSg17l7vPx+xHkFSajwKwaXAoylcPHFb23EGBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMJFtPQCQdlzCegJJku/ry9YjKOtCxHoESVJiWKH1CJKkrJZ/WI8gX9886xGUlYjd3nZJngMAgG4RIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACY8D1A8HtfChQtVWlqqvLw83XvvvVqyZImcc17vCgCQxjy/G/by5cu1du1abdq0SWPGjNHRo0c1Z84cBYNBzZs3z+vdAQDSlOcBeu+99zRz5kxNnz5dkjRixAht3bpVR44c8XpXAIA05vlHcA899JAaGxt1+vRpSdL777+vAwcOaNq0ad1uH4vFFI1GuywAgMzn+RnQggULFI1GNWrUKPn9fsXjcS1dulRVVVXdbh8KhfTyyy97PQYAIMV5fgb0xhtvaPPmzdqyZYuam5u1adMm/eY3v9GmTZu63b6+vl6RSKRzCYfDXo8EAEhBnp8BvfDCC1qwYIFmz54tSRo7dqw+/fRThUIhVVdX37B9IBBQIBDwegwAQIrz/Azo0qVLysrq+m39fr8SiYTXuwIApDHPz4BmzJihpUuXavjw4RozZoyOHz+ulStX6umnn/Z6VwCANOZ5gFavXq2FCxfqpz/9qdra2lRcXKxnn31WixYt8npXAIA05nmA8vPz1dDQoIaGBq+/NQAgg3AvOACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAw4fmteICMN2iA9QSSJJfttx5BPusB/pfvQrv1CJIkN7C/9QiSz/5PxcXdbW3HGRAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJrKtBwDSTrbfegJJ0tVgnvUI6tN+yXqEa+IJ6wkkSS7H/i0163zEegT5ErHb2o4zIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADAxB0HaP/+/ZoxY4aKi4vl8/m0c+fOLq8757Ro0SINHTpUeXl5qqys1JkzZ7yaFwCQIe44QB0dHRo3bpzWrFnT7esrVqzQqlWrtG7dOh0+fFj9+vXT1KlT9fXXX3/nYQEAmeOO7x0+bdo0TZs2rdvXnHNqaGjQL3/5S82cOVOS9Pvf/16FhYXauXOnZs+e/d2mBQBkDE9/B3T27Fm1tLSosrKyc10wGNSkSZN08ODBbv+bWCymaDTaZQEAZD5PA9TS0iJJKiws7LK+sLCw87VvC4VCCgaDnUtJSYmXIwEAUpT5VXD19fWKRCKdSzgcth4JANADPA1QUVGRJKm1tbXL+tbW1s7Xvi0QCKh///5dFgBA5vM0QKWlpSoqKlJjY2Pnumg0qsOHD2vy5Mle7goAkObu+Cq4L7/8Uh9//HHn12fPntWJEyc0aNAgDR8+XLW1tfrVr36lkSNHqrS0VAsXLlRxcbFmzZrl5dwAgDR3xwE6evSoHn300c6v6+rqJEnV1dXauHGjXnzxRXV0dOiZZ57RxYsX9fDDD2v37t3Kzc31bmoAQNrzOeec9RD/VzQaVTAY1JR75inbH7AeB7hRTh/rCSRJV4N51iOoz+f/sB7hmhR5G0sMtv8ddtb5iPUIupqI6b/OrVckEvmXv9c3vwoOANA7ESAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATNzxrXiS7ZsbM1xNxIwnAW4inrCeQJJ09arPegT5UuXfaarcCSFufzyyUuDP5GrisqTr7+c3k3K34vn88895KB0AZIBwOKxhw4bd9PWUC1AikdC5c+eUn58vn+//9xNeNBpVSUmJwuFwr3++EMeiK47HdRyL6zgW13lxLJxzam9vV3FxsbKybv6bnpT7CC4rK+tfFvNO8IC76zgWXXE8ruNYXMexuO67HotgMHjLbbgIAQBgggABAExkZIACgYAWL16sQIDnCXEsuuJ4XMexuI5jcV1PHouUuwgBANA7ZOQZEAAg9REgAIAJAgQAMEGAAAAmMjJAa9as0YgRI5Sbm6tJkybpyJEj1iP1uFAopAkTJig/P18FBQWaNWuWTp06ZT1WSli2bJl8Pp9qa2utRzHxxRdf6KmnntLgwYOVl5ensWPH6ujRo9ZjmYjH41q4cKFKS0uVl5ene++9V0uWLLnlPcwywf79+zVjxgwVFxfL5/Np586dXV53zmnRokUaOnSo8vLyVFlZqTNnzng6Q8YFaPv27aqrq9PixYvV3NyscePGaerUqWpra7MerUft27dPNTU1OnTokPbs2aMrV67oscceU0dHh/VoppqamrR+/Xrdf//91qOYuHDhgioqKtSnTx+98847+vDDD/Xb3/5WAwcOtB7NxPLly7V27Vq9+uqr+uijj7R8+XKtWLFCq1evth4t6To6OjRu3DitWbOm29dXrFihVatWad26dTp8+LD69eunqVOn6uuvv/ZuCJdhJk6c6Gpqajq/jsfjrri42IVCIcOp7LW1tTlJbt++fdajmGlvb3cjR450e/bscY888oibP3++9Ug97qWXXnIPP/yw9RgpY/r06e7pp5/usu6JJ55wVVVVRhPZkOR27NjR+XUikXBFRUXu17/+dee6ixcvukAg4LZu3erZfjPqDOjy5cs6duyYKisrO9dlZWWpsrJSBw8eNJzMXiQSkSQNGjTIeBI7NTU1mj59epe/H73N22+/rfLycj355JMqKCjQ+PHjtWHDBuuxzDz00ENqbGzU6dOnJUnvv/++Dhw4oGnTphlPZuvs2bNqaWnp8m8lGAxq0qRJnr6XptzNSL+L8+fPKx6Pq7CwsMv6wsJC/fWvfzWayl4ikVBtba0qKipUVlZmPY6Jbdu2qbm5WU1NTdajmPrkk0+0du1a1dXV6ec//7mampo0b9485eTkqLq62nq8HrdgwQJFo1GNGjVKfr9f8XhcS5cuVVVVlfVoplpaWiSp2/fSb17zQkYFCN2rqanRyZMndeDAAetRTITDYc2fP1979uxRbm6u9TimEomEysvL9corr0iSxo8fr5MnT2rdunW9MkBvvPGGNm/erC1btmjMmDE6ceKEamtrVVxc3CuPR0/LqI/ghgwZIr/fr9bW1i7rW1tbVVRUZDSVrblz52rXrl169913PXvMRbo5duyY2tra9MADDyg7O1vZ2dnat2+fVq1apezsbMXjcesRe8zQoUM1evToLuvuu+8+ffbZZ0YT2XrhhRe0YMECzZ49W2PHjtWPf/xjPf/88wqFQtajmfrm/TLZ76UZFaCcnBw9+OCDamxs7FyXSCTU2NioyZMnG07W85xzmjt3rnbs2KE///nPKi0ttR7JzJQpU/TBBx/oxIkTnUt5ebmqqqp04sQJ+f1+6xF7TEVFxQ2X458+fVp333230US2Ll26dMMD0/x+vxKJ1HjsupXS0lIVFRV1eS+NRqM6fPiwt++lnl3OkCK2bdvmAoGA27hxo/vwww/dM8884wYMGOBaWlqsR+tRzz33nAsGg27v3r3ub3/7W+dy6dIl69FSQm+9Cu7IkSMuOzvbLV261J05c8Zt3rzZ9e3b1/3hD3+wHs1EdXW1+973vud27drlzp4969588003ZMgQ9+KLL1qPlnTt7e3u+PHj7vjx406SW7lypTt+/Lj79NNPnXPOLVu2zA0YMMC99dZb7i9/+YubOXOmKy0tdV999ZVnM2RcgJxzbvXq1W748OEuJyfHTZw40R06dMh6pB4nqdvl9ddftx4tJfTWADnn3B//+EdXVlbmAoGAGzVqlHvttdesRzITjUbd/Pnz3fDhw11ubq6755573C9+8QsXi8WsR0u6d999t9v3iOrqaufctUuxFy5c6AoLC10gEHBTpkxxp06d8nQGHscAADCRUb8DAgCkDwIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADAxP8ADlnTUagrGF8AAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"ax.imshow(torch.real(b))"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "531c4088-0742-4a9f-a08e-f0b7720b21fa",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"b[:, :dc] = torch.flip(torch.conj(b[:, dc+1:]), dims=(-2, -1))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "17a1955a-1bb8-4bb7-bfc9-3d8ce4c16ab8",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x111d8b3a0>"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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mCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMBE0HqAW/E1X5MvYNvHxKm/ma4vScHiQdYjSJICDResR5CCAesJJEmuV671CNddbLSeQMlB+dYjSJL8tRetR5Ak+XwZ8r1hzJe4dkfHcQUEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAE2kP0JIlS+Tz+VRVVZXupQAAHUhaA1RTU6PXX39d999/fzqXAQB0QGkL0KVLl1ReXq5169apd+/e6VoGANBBpS1AlZWVmjx5ssrKyv7pcfF4XLFYrNUGAOj80vJE1C1btujo0aOqqam57bGRSESvvPJKOsYAAGQwz6+AamtrNXv2bG3cuFHZ2dm3PX7evHmKRqOprba21uuRAAAZyPMroCNHjqihoUEPPPBAal8ikdDevXv12muvKR6PKxAIpF4LhUIKhUJejwEAyHCeB2jChAn66KOPWu2bMWOGhg4dqpdffrlVfAAAXZfnAcrNzdWIESNa7evRo4f69u17034AQNfFnRAAACbS8im4b9u9e3d7LAMA6EC4AgIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJholzsh/Esazku+LNMRfKOHm64vSe5qs/UI1wXs/67ia0lYjyBJ+u89b1uPIEma/NB/WY8g/8Um6xGu6xO2nkCSlMy2PWdJkv9vGfBIG3dn5y37swoAoEsiQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYIEAAABMECABgggABAEwQIACACQIEADBBgAAAJggQAMAEAQIAmCBAAAATBAgAYIIAAQBMECAAgAkCBAAwQYAAACYIEADABAECAJggQAAAEwQIAGCCAAEATBAgAIAJAgQAMEGAAAAmCBAAwAQBAgCYCFoPcEt5/aRAyHQEf9NV0/UlSdFG6wkkScmiPOsR5D9bbz2CJOk/H3nSegRJks9dsx5Bvitx6xGuSyStJ5AkuU9OW48g/ce91hNIibgUu/1hXAEBAEwQIACACQIEADBBgAAAJggQ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\n",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots()\n",
"ax.imshow(torch.real(b))"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "66d12059-750e-4a6f-b969-7ee42777a849",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"torch.allclose(fft, b[:-1, :-1])"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "72904d12-57cb-4c7b-9870-2a7aa5504c68",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [],
"source": [
"def rfft_to_symmetrised_dft_2d(rfft: torch.Tensor) -> torch.Tensor:\n",
" r = rfft.shape[0] # original dim length, assumes rfft was performed on even length dim\n",
" dc = r // 2\n",
" output = torch.zeros((r+1, r+1), dtype=torch.complex64)\n",
" # fftshift dim which needs shifting to center DC\n",
" rfft = torch.fft.fftshift(rfft, dim=(-2, ))\n",
" output[:-1, dc:] = rfft # place rfft\n",
" output[-1, dc:] = rfft[0, :] # fill symmetrised nyquist\n",
" # fill redundant half\n",
" output[:, :dc] = torch.flip(torch.conj(output[:, dc+1:]), dims=(-2, -1))\n",
" return output"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "564d7da4-87e8-4a80-8099-e11d909fcdc1",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"result = rfft_to_symmetrised_dft_2d(rfft)\n",
"torch.allclose(fft, result[:-1, :-1])"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "9c3e535b-faad-4b45-8b66-596467d4bbda",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x111dd7af0>"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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qKCgQGPHjvWvaQBJRdgA0C47d+7U3Xffnfh52rRpkqTx48dr2bJlevLJJ3Xy5Ek9+uijOnbsmO644w6tW7dOWVlZfrUMIMkIGwDa5a677pIxpsXbA4GAfvvb3+q3v/1tErsCkEo4ZwMAADhF2AAAAE4l/TBK4+7W87Gok/rnz3dwUjfkqF9JUvysk7KBuLueTSzmrLYCITdlHT4fUsBJVROzX7fxf+9Shz5STWLcsPy/Erf8fx108TcWsPs3cP68gzlpLD+P58/b/7u3/v/v4P8n1f8eG///2jJ2BEySR5zPP/+cqwECKaCmpkbXXnut3220CuMGkDraMnYkPWzE43F9+eWXysnJUeAyiT0SiaiwsFA1NTVpc1Efek4Oem47Y4yOHz+ugoICBYPpcSS1teNGqjzHtnybHg+PJTV5eSztGTuSfhglGAx6TkTpeAVBek4Oem6b3NxcX3+/V17HjVR4jm36Nj0eHktqau1jaevYkR4fawAAQNoibAAAAKdSOmyEw2HNmjVL4XDY71ZajZ6Tg57RnG/bc/xtejw8ltSUrMeS9BNEAQDAd0tK79kAAADpj7ABAACcImwAAACnCBsAAMCplA0bixYtUq9evZSVlaUhQ4Zo+/btfrd0SRUVFbrtttuUk5Ojbt26aezYsTpw4IDfbbXaM888o0AgoLKyMr9buawvvvhCDz74oLp06aLs7GwNGDBAO3fu9LutFsViMc2YMUNFRUXKzs5W7969NWfOnLSamySVeB0b/vSnP6lv377KysrSgAED9Ne//jVJnV5aW8aMZcuWKRAINFmysrKS1HHLfvOb31zUV9++fS95n1R9XXr16nXRYwkEAiotLW12+1R7TTZt2qTRo0eroKBAgUBAa9eubXK7MUYzZ85U9+7dlZ2dreLiYh06dOiyddv7npySYePVV1/VtGnTNGvWLO3evVsDBw7UiBEjVF9f73drLXr33XdVWlqqrVu3asOGDTp37pzuvfdenTx50u/WLmvHjh168cUXddNNN/ndymV98803Gj58uDp06KC3335bH330kX7/+9/rqquu8ru1Fs2bN0+VlZV64YUX9PHHH2vevHl69tlntXDhQr9bSztex4b3339fP/3pT/Xwww9rz549Gjt2rMaOHav9+/cnufOLtXXM6Nixo7766qvEcvTo0SR1fGn9+vVr0tfmzZtb3DaVX5cdO3Y0eRwbNmyQJN1///0t3ieVXpOTJ09q4MCBWrRoUbO3P/vss3r++ee1ePFibdu2TVdeeaVGjBihM2danqDPynuySUG33367KS0tTfwci8VMQUGBqaio8LErb+rr640k8+677/rdyiUdP37c9OnTx2zYsMHceeedZurUqX63dElPPfWUueOOO/xuw5NRo0aZiRMnNln34x//2JSUlPjUUfryOjb85Cc/MaNGjWqybsiQIeaxxx5z2mdbtGbMWLp0qcnNzU1eU600a9YsM3DgwFZvn06vy9SpU03v3r1NPB5v9vZUfU2MMUaSWbNmTeLneDxu8vPzzX//938n1h07dsyEw2GzcuXKFuvYeE9OuT0bZ8+e1a5du1RcXJxYFwwGVVxcrC1btvjYmTcNDQ2SpM6dO/vcyaWVlpZq1KhRTZ7vVPbmm29q8ODBuv/++9WtWzcNGjRIS5Ys8butSxo2bJiqq6t18OBBSdIHH3ygzZs3a+TIkT53ll7aMjZs2bLlor/tESNGpORY0tox48SJE+rZs6cKCws1ZswYffjhh8lo77IOHTqkgoICXXfddSopKdFnn33W4rbp8rqcPXtWr7zyiiZOnHjJCQBT9TX5T0eOHFFtbW2T5z43N1dDhgxp8bm39Z6ccmHj66+/ViwWU15eXpP1eXl5qq2t9akrb+LxuMrKyjR8+HD179/f73ZatGrVKu3evVsVFRV+t9Jqn376qSorK9WnTx+tX79ekyZN0pQpU1RVVeV3ay2aPn26xo0bp759+6pDhw4aNGiQysrKVFJS4ndraaUtY0NtbW1ajCWtHTO+973v6eWXX9Ybb7yhV155RfF4XMOGDdPnn3+exG4vNmTIEC1btkzr1q1TZWWljhw5ou9///s6fvx4s9uny+uydu1aHTt2TA899FCL26Tqa9KcxufXy3Nv6z056bO+fheUlpZq//79lzxm6beamhpNnTpVGzZsSIkTzForHo9r8ODBevrppyVJgwYN0v79+7V48WKNHz/e5+6at3r1ai1fvlwrVqxQv379tHfvXpWVlamgoCBle0ZytXbMGDp0qIYOHZr4ediwYbrhhhv04osvas6cOa7bbNGFe+luuukmDRkyRD179tTq1av18MMP+9ZXe/3hD3/QyJEjVVBQ0OI2qfqapJqUCxtdu3ZVKBRSXV1dk/V1dXXKz8/3qavWmzx5st566y1t2rTJ05TYybZr1y7V19frlltuSayLxWLatGmTXnjhBUWjUYVCIR87bF737t114403Nll3ww036LXXXvOpo8t74oknEns3JGnAgAE6evSoKioqCBsetGVsyM/PT/mxpD1jRuOessOHDzvqrm06deqk66+/vsW+0uF1OXr0qP72t7/p9ddf93S/VH1NJCWe37q6OnXv3j2xvq6uTjfffHOz97H1npxyh1EyMzN16623qrq6OrEuHo+rurq6SXpMNcYYTZ48WWvWrNHf//53FRUV+d3SJd1zzz3at2+f9u7dm1gGDx6skpIS7d27NyWDhiQNHz78oq8HHjx4UD179vSpo8s7deqUgsGm/2qhUEjxeNynjtJTW8aGoUOHNtlekjZs2JASY4mNMSMWi2nfvn1N3jhSwYkTJ/TJJ5+02Fcqvy6Nli5dqm7dumnUqFGe7peqr4kkFRUVKT8/v8lzH4lEtG3bthafe2vvyV7ObE2WVatWmXA4bJYtW2Y++ugj8+ijj5pOnTqZ2tpav1tr0aRJk0xubq7ZuHGj+eqrrxLLqVOn/G6t1dLh2yjbt283GRkZZu7cuebQoUNm+fLl5oorrjCvvPKK3621aPz48eaaa64xb731ljly5Ih5/fXXTdeuXc2TTz7pd2tp53Jjw89+9jMzffr0xPbvvfeeycjIMM8995z5+OOPzaxZs0yHDh3Mvn37/HoICa0ZM/7z8cyePdusX7/efPLJJ2bXrl1m3LhxJisry3z44Yd+PISEX/7yl2bjxo3myJEj5r333jPFxcWma9eupr6+3hiTXq+LMf/+tkWPHj3MU089ddFtqf6aHD9+3OzZs8fs2bPHSDLz5883e/bsMUePHjXGGPPMM8+YTp06mTfeeMP84x//MGPGjDFFRUXm9OnTiRo//OEPzcKFCxM/23hPTsmwYYwxCxcuND169DCZmZnm9ttvN1u3bvW7pUuS1OyydOlSv1trtXQIG8YY8+c//9n079/fhMNh07dvX/PSSy/53dIlRSIRM3XqVNOjRw+TlZVlrrvuOvOrX/3KRKNRv1tLS5caG+68804zfvz4JtuvXr3aXH/99SYzM9P069fP/OUvf0lyx81rzZjxn4+nrKws8djz8vLMj370I7N79+7kN/8fHnjgAdO9e3eTmZlprrnmGvPAAw+Yw4cPJ25Pp9fFGGPWr19vJJkDBw5cdFuqvybvvPNOs39XjT3H43EzY8YMk5eXZ8LhsLnnnnsuepw9e/Y0s2bNarKuve/JTDEPAACcSrlzNgAAwLcLYQMAADhF2AAAAE4RNgAAgFOEDQAA4BRhAwAAOEXYAAAAThE2AACAU4QNAADgFGEDAAA4RdgAAABOETYAAIBT/xdTo4EQ4hnRKAAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 640x480 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(1, 2)\n",
"ax[0].imshow(torch.real(fft))\n",
"ax[1].imshow(torch.real(result))"
]
},
{
"cell_type": "markdown",
"id": "600d93c4-4cd3-495e-a8d8-1aa0db70327f",
"metadata": {
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"# 3d case"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "fe9218c8-3a99-48b8-912d-ec1da44abc68",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"torch.Size([10, 10, 10])"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"v = torch.rand((10, 10, 10))\n",
"v.shape"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "432ddb90-5e3b-4041-9fd5-9b1e9a6f8315",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"torch.Size([10, 10, 6])"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"rfft = torch.fft.rfftn(v, dim=(-3, -2, -1))\n",
"rfft.shape"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "045e6d61-0360-450f-941b-ec7957afb0c9",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"torch.Size([10, 10, 10])"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fft = torch.fft.fftn(v, dim=(-3, -2, -1))\n",
"fft = torch.fft.fftshift(fft, dim=(-3, -2, -1))\n",
"fft.shape"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "f1615546-a8de-47f1-997f-2ce36fc8ba4a",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def rfft_to_symmetrised_dft_3d(rfft: torch.Tensor) -> torch.Tensor:\n",
" r = rfft.shape[0]\n",
" dc = r // 2\n",
" output = torch.zeros((r+1, r+1, r+1), dtype=torch.complex64)\n",
" # fftshift dims which need shifting to center DC component\n",
" rfft = torch.fft.fftshift(rfft, dim=(-3, -2))\n",
" # place rfft\n",
" output[:-1, :-1, dc:] = rfft\n",
" # fill empty symmetrised nyquist\n",
" output[:-1, -1, dc:] = rfft[:, 0, :]\n",
" output[-1, :-1, dc:] = rfft[0, :, :]\n",
" output[-1, -1, dc:] = rfft[0, 0, :]\n",
" # fill redundant half\n",
" output[:, :, :dc] = torch.flip(torch.conj(output[:, :, dc+1:]), dims=(-3, -2, -1))\n",
" return output\n",
"\n",
"result = rfft_to_symmetrised_dft_3d(rfft)\n",
"torch.allclose(fft, result[:-1, :-1, :-1])"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "1ad88a3e-6294-45da-9bb2-a1bb900a7181",
"metadata": {
"pycharm": {
"name": "#%%\n"
}
},
"outputs": [
{
"data": {
"text/plain": [
"<Image layer 'Image [1]' at 0x2b2addcf0>"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import napari\n",
"viewer = napari.Viewer(ndisplay=3)\n",
"viewer.add_image(torch.real(fft).numpy())\n",
"viewer.add_image(torch.real(result).numpy())"
]
}
],
"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.10.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment