Topology in neuroscience
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

783 lines
1.0 MiB

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import persim\n",
"import matplotlib.pyplot as plt\n",
"import math\n",
"from umap import UMAP\n",
"import ripser\n",
"from scipy.optimize import least_squares\n",
"from tqdm import trange\n",
"from scipy.stats import zscore"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"X.shape (4598, 200)\n",
"stim.shape (4598,)\n"
]
}
],
"source": [
"data = np.load('stringer_orientations_pca.npy', allow_pickle=True).item()\n",
"X, stim = data['pc_score'], data['orientation']\n",
"print('X.shape', X.shape)\n",
"print('stim.shape', stim.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4598 trials. In each trial, a static orientation grating was shown to the mouse.\n",
"\n",
"data has fields:\n",
"* `data['pc_score']`: (4598, 200) contains the population activity score along the first 200 principal components - PCA was carried out on the population activity of ~23000 neurons\n",
"\n",
"* `data['istim']`: (4598,) contains orientation values shown on each trial, orientation values range from 0 to 2*np.pi.\n",
"\n",
"For more details see https://compneuro.neuromatch.io/projects/neurons/README.html#stringer\n",
"\n",
"(#samples, #features) = dat['sresp'] (4598, 23589) ----PCA---> (4598, 200)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Principal components"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fbdabee05bf94525b677e677c7f9c750",
"version_major": 2,
"version_minor": 0
},
"image/png": "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
"text/html": [
"\n",
" <div style=\"display: inline-block;\">\n",
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
" Figure\n",
" </div>\n",
" <img src='data:image/png;base64,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
" </div>\n",
" "
],
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from mpl_toolkits import mplot3d\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"\n",
"%matplotlib inline\n",
"%matplotlib widget\n",
"\n",
"x, y, z = X[:,1], X[:,2], X[:,3]\n",
"\n",
"fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n",
"ax = fig.add_subplot(1, 1, 1, projection='3d')\n",
"ax.scatter3D(x, y, z, c=stim, cmap='hsv')\n",
"ax.set(xlabel=\"PC0\", ylabel=\"PC1\", zlabel=\"PC2\", xticks=[], yticks=[], zticks=[])\n",
"fig.suptitle('PCA 3D')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x576 with 15 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"ncomp_disp = 5\n",
"fig = plt.figure(figsize=(8,8))\n",
"for j in range(ncomp_disp):\n",
" for i in range(j+1):\n",
" ax = fig.add_subplot(ncomp_disp,ncomp_disp, j + ncomp_disp*i + 1)\n",
" if i == j:\n",
" ax.scatter(stim, X[:, i], s=1)\n",
" ax.set(xlabel='stim', ylabel='PC%d'%i)\n",
" else:\n",
" ax.scatter(X[:, j], X[:, i], s=1, c=stim, cmap='hsv')\n",
" \n",
" ax.set(xticks=[], yticks=[])\n",
" \n",
" if i==0 and j>0:\n",
" ax.set(xlabel='PC%d'%j)\n",
" ax.xaxis.set_label_position('top') \n",
"\n",
" if j==ncomp_disp-1 and i<ncomp_disp-1:\n",
" ax.set(ylabel='PC%d'%i)\n",
" ax.yaxis.set_label_position('right') \n",
"\n",
"fig.set_facecolor('white')\n",
"fig.suptitle('PCA')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"# @title run a manifold embedding algorithm (UMAP) in two or three dimensions.\n",
"\n",
"ncomp = 3 # try 2, then try 3\n",
"xinit = 3 * zscore(X[:, :ncomp], axis=0)\n",
"embed = UMAP(n_components=ncomp, init=xinit, n_neighbors=5,\n",
" metric='correlation', random_state=5).fit_transform(X)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "f73a9955ec844f4491977d22c1244e27",
"version_major": 2,
"version_minor": 0
},
"image/png": "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
"text/html": [
"\n",
" <div style=\"display: inline-block;\">\n",
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
" Figure\n",
" </div>\n",
" <img src='data:image/png;base64,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
" </div>\n",
" "
],
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from mpl_toolkits import mplot3d\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"\n",
"%matplotlib inline\n",
"%matplotlib widget\n",
"\n",
"x, y, z = embed[:,0], embed[:,1], embed[:,2]\n",
"\n",
"fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n",
"ax = fig.add_subplot(1, 1, 1, projection='3d')\n",
"ax.scatter3D(x, y, z, c=stim, cmap='hsv')\n",
"ax.set(xlabel=\"U0\", ylabel=\"U1\", zlabel=\"U2\", xticks=[], yticks=[], zticks=[])\n",
"fig.suptitle('UMAP 3D')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x576 with 6 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"ncomp_disp = 3\n",
"fig = plt.figure(figsize=(8,8))\n",
"for j in range(ncomp_disp):\n",
" for i in range(j+1):\n",
" ax = fig.add_subplot(ncomp_disp,ncomp_disp, j + ncomp_disp*i + 1)\n",
" if i == j:\n",
" ax.scatter(stim, embed[:, i], s=1)\n",
" ax.set(xlabel='stim', ylabel='U%d'%i)\n",
" else:\n",
" ax.scatter(embed[:, j], embed[:, i], s=1, c=stim, cmap='hsv')\n",
" \n",
" ax.set(xticks=[], yticks=[])\n",
" \n",
" if i==0 and j>0:\n",
" ax.set(xlabel='U%d'%j)\n",
" ax.xaxis.set_label_position('top') \n",
"\n",
" if j==ncomp_disp-1 and i<ncomp_disp-1:\n",
" ax.set(ylabel='U%d'%i)\n",
" ax.yaxis.set_label_position('right') \n",
"\n",
"fig.set_facecolor('white')\n",
"fig.suptitle('UMAP')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Point cloud simplification\n",
"### Radial distance\n",
"\n",
"For faster computation we need to reduce the number of datapoints"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [],
"source": [
"def radial_distance(X, eps, random_state=None):\n",
" \"\"\"\n",
" point cloud simplification using radial distance (euclidean metric). \n",
" Start with the first point in in X and mark it as a key point. All consecutive points that have a distance less than a predetermined distance eps to the key point are removed. The first point that have a distance greater than eps to the key point is marked as the new key point. The process repeates itself from this new key point, and continues until it reaches the end of the point cloud.\n",
" \n",
" Parameters\n",
" ----------\n",
" X: pandas DataFrame (n_datapoints, n_features):\n",
"\n",
" eps: max radial distance - cutoff distance\n",
"\n",
" random_state: seed of random generator used for choosing the inital point\n",
"\n",
" Returns\n",
" -------\n",
" X.iloc[ind_reduced]: dataframe with chosen datapoints \n",
" \"\"\"\n",
" if random_state is not None:\n",
" np.random.seed(random_state)\n",
" \n",
" ix0 = np.random.choice(X.shape[0])\n",
" x0 = X.iloc[ix0]\n",
" xt = x0\n",
" ixt = ix0\n",
" X_temp = X\n",
" ind_reduced = [ix0]\n",
"\n",
" while True:\n",
" dist = np.linalg.norm(X_temp.to_numpy() - xt.to_numpy(), axis=1)\n",
" cond = dist < eps\n",
"\n",
" X_temp = X_temp.drop(X_temp.index[np.where(cond)])\n",
" if len(X_temp)==0:\n",
" break\n",
"\n",
" where_not_cond = np.where(np.logical_not(cond))\n",
" w = np.argmin(dist[where_not_cond]) \n",
" ixt = X_temp.index[w]\n",
" xt = X.iloc[ixt]\n",
" ind_reduced.append(ixt)\n",
"\n",
" return X.iloc[ind_reduced]\n"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAaAAAAETCAYAAABwaNKCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAeRElEQVR4nO3de5wcZZ3v8c83kwkMFxMl0TUXCK4hGFnd6IjsWS85gCTgGiKLLnhYBVnRddH1QpSoixy8ICcK6soRQV0WPYpRszG4uLMvFQ7rJUAwSgyc0YhgMgEJl0SEQWbi7/zx1ISaSc9MT1LTT8/M9/165ZXuquqnfnXp+nY9XVOtiMDMzKzRJuUuwMzMJiYHkJmZZeEAMjOzLBxAZmaWhQPIzMyycACZmVkW4yKAJN0o6e9God35kn4q6RFJb6+47U2SFlXZ5iDzGa11s0jS1r143RWS/qnqeoq275Z0fPH4fZI+Xxr3aklbJP1e0sLRWv+SviPpDVW3u7dGc33vK0lnSvpB6fnvJT2rjtfNlRSSJtc5n6slfbh4/FJJnXtf9fhWrNdnV9TW7vfjYOragBPYe4AbIuLPq244Ip5b77SS7gb+LiK+W3UdjRYRb2nQfD46YNDHgXMj4lvF87rX/2AkXQg8OyLOKM33xH1tt0qNWt9ViIiDGjCP/wLmDzddrW073ki6EfhyRHx+uGlHy7g4AxpFhwGbchdhlfC2HEX1no2Y9RMRQ/4DZgLfBLYDvwbeXgx/GrAVeFXx/CBgM/D64vkrgQ3A74AtwIWlNucCAZxVjHsYeAvwIuB2YAfwmdL0ZwI/BD4D7AT+H3BcafyNpDOEvudvBO4s2u0ADhti+ZaSDkw7inaeUwz/PrALeBz4PXBEjdfeCFwM3FIs57eApw3XdjHubuD44vGFwCrgGuCR4jXtxbgvAX8Euos63jPIcpwM/LSo41fAkoHrhvSB4wPAPcD9xfymFuMWAVsHtFmusQ24ulindwDLB05fep2Ay4p5/A7YCBxVjLsa+HB5nqQzzfuBe4FlwEnAL4CHgPeV2r0Q+AbwtWI9/QR4/hDr9MvAfsV6C+BR4Fc1pm0B3lest0eA24A5xbhPkfbR3xXDX1oMXwI8AfQU7f9shOt7blHTG4DfAA8A7x9iP93dbuk98YO9XN/vLq3vs0ptHgJcV7RxK/DhvnnUqKev/rOL+m8qhn8duI/0Pr0JeO6A9tcW7d8CfKjcftHes0dw/Jg8SG0Li33jEdK+cu3AdVCa9r1AVzFtJ3DcENv2LNJx5RHgLuDNpXaGW7dtwCeKfWEn8AOgrRh3DPAj0nHiZ8CiIfaDu0nvvdtJ+/MXgGcA3ynq+i7w1NL0NdsGPkL/49tnStvgLcAvi9dcDmi4/bkY/7fFuAeB91N6jw26PEOOTDO8DbgAmAI8q1jxi4vxJ5B2tqcDVwHfGLBB/qxo43nAb4FlA3agK4D9i3YeB9YUbc0qFvDlpTdbL/BOoBX4m2IjPq3Gm/5kUhA+h9TF+AHgR4Ms3xHFRnxF0e57itdOqfWmH+Sg0AUcBRxICuov19n27o1DOlg+TjrwtpBCbV2tA+sgdRxdrI9XFOt7FnBkjXXzxqKGZ5E+MKwGvlRnAH0M+C/SB485wM8HTl963WLSfjONdHB8DvDMQQ6IvaT9qxV4E+mDzleAg0ndZN3A4aX11AOcWkx/HulDUetgAVTr4FZj2uWkg/b8ot7nA4cU484gHTgnkw4u9wH715rHCNf33KKmq0gHp+cDf6D0IWUEATTS9X1Rsf5OAh6jOGCRDtTXAgcAC0gH/uEC6BrSvt9WWuaDScH/SeCnpddcS/qgdSDpPdPF4AG0iOGPH3sEEOk4dQ9PHitOJe0zewRQsb23ADNL7f7pENv2lcCfFuv45cW6e0Gd6/byYhvOIr3H/1uxjmaRDtgnFcv6iuL5jCECaB0pdPqOkz8hhe7+pA/OHyymHbJtahzfivX6bdK+dCjp/biktG0H258XkILsZcVyXVqsj30KoBcDvxkwbAXwL6Xn/0x683ZRvGkHaeuTwGUDdqBZpfEPAn9Tev5N4B2lN9s2iiQuht0C/G2NN/13gLNL000qdoTDatT0T8CqAdN28eSnhD02UI2DwsdKzxeQPjm11NH23fQ/WH53QDvdtQ6Wg9Txub51O9SBC/ge8NbSuPmkN+dkhg+gu/p2xOL5OQOnL407lnQGcwwwacC4q+l/MOgGWornBxf7xYtL09/GkweeC+kfzJNInzRfWqPeC6k/gDqBk4d6L5Re9zDFWdfAeYxwfc8tapo9YJ8+bbjtWHpP9AXQSNf35NL4+4vXtRS1zS+Nq+cM6FlDrKtpxTRTS+0fWRr/UQYJoBptfZI9jx+1Auhl7Hms+BG1A+jZxfIfT/EhpvSaPbZtjXmtAf6xjnU7qRj3/BptvJfiIF4a1gG8YZB53g38j9LzbwKfLT1/G7CmnrYH7lOlbfCS0vNVwPl17M8XANeWxh1IOhYOGUDDfQd0GDBT0o6+f6SuimeUprmS9Gnm6oh4sG+gpBdLukHSdkk7Sad10we0/9vS4+4az8tfSnZFsWSFe0jdg7Vq/lSp3odIn1hm1Zh2ZtEOABHxR9InolrTDmbLgJpaScs50rbvKz1+DNh/BP3qc0jdR8PpV1PxeDL9t+dQrx24rDVFxPdJ3aWXA/dLulLSUwaZ/MGI2FU87i7+H2o/2F1DsU63Uns/GIlB15+k8yTdKWlnsT9NZc/9eDD1rO+B233EX8TvxfrurTHPGUVt5W1cfjyY3dNIapH0MUm/kvQ70sES0vqq1f6g+1Cdx49aZlL7WLGHiNgMvIMUNvdLulbSoPuSpBMlrZP0ULEvnDSgpsHW7XTS2Umtfeww4DUDjrEvAZ45xDLWe9zcm7Zh8H1yqP253/EhIh4lnVQMabgA2gL8OiKmlf4dHBEnQdrhSAF0DfDWAZfvfYXU3zsnIqaSuts0XEFDmCWp/PpDSZ90atX85gE1t0XEj2pMu420kSiWR6SDUdcI6pozoKYeUn9+FW33iWHGbyF1DQynX02kentJO/CjpK4XYPe2nVGa9l72XNZBRcSnI+KFpLO5I0jdXFXYXYOkScBsau8HI1Fz/Ul6Kanr9LWkrpRppK7Ovv1wuO0y1PoeqX7bB/iT8sgK1vf2orbZpWFzBpm236xLj19H6gI/nhTUc4vhKrVf7z60t8ePe6l9rKhdfMRXIuIlpO0UwCV9o8rTSdqPdLbxceAZxb5wfZ01PUDqYq/1Ht1COkspH68OjIiP1dHucIZre7j9d6Ch9ud+xwdJB5C6roc0XADdAjwi6b2S2opPOEdJelEx/n2khXgjsBK4pjhwQepOeSgiHpd0NGnn3BdPB94uqVXSa0j93NfXmO4KYIWk5wJImlpMX8sq4JWSjpPUSurj/wPplL1eZ0haUKzwi0jfg+2qqO0+vyX1uw7mC8BZxbwmSZol6cga030VeKekwyUdROoC+Vrxqe0XpLOuVxb1foDUl9tnFWm9PlXSbNKpfk2SXlR8gm0lHTgfJ11IUYUXSjqlODt8B2mdrtvHNj8PfEjSPCXPk3QIaR/uJR08J0u6ACifWfwWmFsEYS1Dre+R+ilwiqQDig96Z/eNqGJ9F/vsauDCYh5HAq8fYY0Hk7bHg6Sw3H0pfI32F5AuwBiqrb05fvyYtM36jhWnkL4j3YPS3/kdW4TL46Szh771NnDbTiG9H7YDvZJOJH13PaziTP2LwKWSZhbH0b8o5vtl4FWSFhfD91f6G7vZQ7dal+HaHu64MtBQ+/M3gL+S9BJJU0jHwmGvsh5ygmKn+Svgz0lf9j5AerNOlfRC4F2kq952kT45BHB+8fK3AhdJeoTUP7hqBAtay83AvKKGjwCnlrv8SjX/W1HLtUU3wM+Bmn+bERGdpC+Z/7lo91Wkq/qeGEFdXyL1s99HOs1+e4Vt97kY+EBxGn1ejeW4hXSFzmWkT+j/l/6fVPp8saj3JtL2fJwiSCJiJ2mbfZ50lvYoqXurz/8knXL/GvjPop3BPIX05frDPHlVzMr6FnVY3yJdhPIw6aq
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"# point cloud simplification using radial distance method - example \n",
"x = pd.DataFrame(np.random.rand(10,2))\n",
"x_reduced = radial_distance(x, eps=0.5, random_state=42)\n",
"\n",
"%matplotlib inline\n",
"plt.scatter(x.to_numpy()[:,0], x.to_numpy()[:,1])\n",
"plt.scatter(x_reduced.to_numpy()[:,0], x_reduced.to_numpy()[:,1], marker='*')\n",
"plt.title('example of point cloud simplification using radial distance method', y=1.05)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [],
"source": [
"eps = 0.6\n",
"embed_reduced = radial_distance(pd.DataFrame(embed), eps=eps, random_state=12)\n",
"stim_r = stim[embed_reduced.index]\n",
"embed_r = embed_reduced.to_numpy()"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "de2953c3212e4aa28eebb7f35a0815e4",
"version_major": 2,
"version_minor": 0
},
"image/png": "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
"text/html": [
"\n",
" <div style=\"display: inline-block;\">\n",
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
" Figure\n",
" </div>\n",
" <img src='data:image/png;base64,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
" </div>\n",
" "
],
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from mpl_toolkits import mplot3d\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"\n",
"%matplotlib inline\n",
"%matplotlib widget\n",
"\n",
"x, y, z = embed[:,0], embed[:,1], embed[:,2]\n",
"\n",
"fig = plt.figure(figsize=(16, 6))\n",
"ax1 = fig.add_subplot(1, 2, 1, projection='3d')\n",
"ax1.scatter3D(x, y, z, c=stim, cmap='hsv')\n",
"ax1.set(xlabel=\"U0\", ylabel=\"U1\", zlabel=\"U2\", title='UMAP - before point-cloud simplification\\n %d points'%embed.shape[0])\n",
"\n",
"x_r, y_r, z_r = embed_r[:,0], embed_r[:,1], embed_r[:,2]\n",
"\n",
"ax2 = fig.add_subplot(1, 2, 2, projection='3d')\n",
"ax2.scatter3D(x_r, y_r, z_r, c=stim_r, cmap='hsv')\n",
"ax2.set(xlabel=\"U0\", ylabel=\"U1\", zlabel=\"U2\", xticks=[], yticks=[], zticks=[], title='UMAP - after point-cloud simplification\\n radial distance $\\epsilon=%.1f$\\n %d points'%(eps,embed_r.shape[0]))\n",
"\n",
"fig.suptitle('Point-cloud simplification', weight='bold')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cohomological feature extraction\n",
"### persistent homology\n"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"ripser_result = ripser.ripser(embed_r, maxdim=1, coeff=2, do_cocycles=False)"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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REJAgSsiIhICClwREZEQUOCKiIiEgAJXREQkBBS4IiIiIaDAFRERCQEFroiISAgocEVEREJAgSsiIhICClwREZEQUOCKiIiEgAJXREQkBBS4IiIiIaDAFRERCQEFroiISAgocEVEREJAgSsiIhICClwREZEQUOCKiIiEgAJXREQkBBS4IiIiIaDAFRERCQEFroiISAgocEVEREJAgSsiIhICClwREZEQUOCKiIiEgAJXREQkBBS4IiIiIaDAFRERCQEFroiISAgocEVEREJAgSsiIhICClwREZEQUOCKiIiEQDWvCyiscePGrnXr1l6XISIickyys7NZs2YNeXl525xzyaXtE1aB27p1azIzM70uQ0REpMJyc3NJS0ujXbt2rF69en1Z+4VV4IqIiESa+Ph4Zs+eTc2aNWnevHmZ+6kPV0RE5Dj4fD5uuukm8vLyaNu2Lc2aNSt3fwWuiIjIMfL5fAwfPpx33nmHXbt2VegYBa6IiMgxyA/blJQU5s+fT4MGDSp0nAJXRESkgoqH7dFuIxemwBUREamgPXv2cNJJJx1z2IICV0RE5Ki2b98OwDnnnMPixYuPOWxBgSsiIlIun89H27ZtmTlzJuB/DOh4KHBFRETKkN9n27x5c/r27VupcylwRURESpEftqmpqcybN++4biMXpsAVEREpZv369VUatqDAFRERKaFVq1ZMmjSpysIW9C5lERGRAhkZGSQlJdGtWzeuv/76Kj23WrgiIiL4+2yHDRvGddddh3Ouys+vwBURkZhXeIDU66+/jplV+TUUuCIiEtOqejRyWRS4IiIS0x599NGghy1o0FSBnTkHeWHhenKdY0zflpyQlOh1SSIiEkTOOcyMF198kd27d3PCCScE9Xpq4QIHDudyydML+efcb3j0gzVc9O+F5Bw47HVZIiISJD6fj0GDBrFz504SExODHrYQZi3c1atXM3DgwCLrLr74Yq699lr27t3LOeecU+KYcePGMW7cOLZt28ZFF11UYvuECRO45JJL2LBhA2PHji2x/Y9//CMd+gxk+YpVbP/v4wBsBvq/UY+kxGrccccdnHXWWXz55ZfceOONJY6/7777OO200/jkk0+4/fbbS2x/+OGH6d69O3PnzuXee+8tsf2pp56iQ4cOzJo1i4ceeqjE9hdffJHU1FSmTZvGv//97xLbp0+fTuPGjXn++ed5/vnnS2x/5513qFWrFv/617947bXXSmz/8MMPAXjwwQeZPXt2kW01a9bk3XffBeCee+7hgw8+KLK9UaNGzJgxA4A///nPLFy4sMj2lJQUXnrpJQBuvPFGvvzyyyLb27dvz9NPPw3A+PHj+eabb4ps7969Ow8//DAAY8aMYePGjUW2n3rqqdx///0AXHjhhQUvF883ePBg7rzzTgCGDx/Ovn37imwfMWIEN998M0CJP3cQmj97I0eOZPXq1Vx99dUltuvPnv7s6c9ecP7s3XPPPQwfPpxatWpx7rnnUr169YJtlf2zVx61cIETkmqQmHDkZdRxZtSoph+NiEi02bVrV8EAqWuuuaZI2AabBeNZo+OVnp7uMjMzPbn2gm+2ct87K8nNc9x8dgfO7tzUkzpERCQ4PvnkE4YOHRrUAVJmttg5l17atrC6peyl/u2T6d8+2esyREQkSFq0aEH//v2ZPHl
"text/plain": [
"<Figure size 576x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"fig = plt.figure(figsize=(8,8))\n",
"ax = fig.add_subplot(1,1,1)\n",
"persim.plot_diagrams(ripser_result['dgms'], ax=ax)\n",
"dgm1 = ripser_result['dgms'][1]\n",
"idx = np.argmax(dgm1[:, 1] - dgm1[:, 0])\n",
"ax.scatter(dgm1[idx, 0], dgm1[idx, 1], 50, 'k', 'x', label='1st order persistent cohomology', alpha=0.3)\n",
"ax.legend()\n",
"fig.suptitle('Persistence diagram')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For simple example of persistent homology and representative cocycles see https://ripser.scikit-tda.org/en/latest/notebooks/Representative%20Cocycles.html#:~:text=Ripser%20is%20cohomology%20based%2C%20and,from%20the%20persistent%20cohomology%20algorithm."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### circular parametrization"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [],
"source": [
"# cohomological parametrization\n",
"\n",
"EPSILON = 0.0000000000001\n",
"\n",
"def shortest_cycle(graph, node2, node1):\n",
" \"\"\"\n",
" Returns the shortest cycle going through an edge\n",
" \n",
" Used for computing weights in decode\n",
" \n",
" Parameters\n",
" ----------\n",
" graph: ndarray (n_nodes, n_nodes)\n",
" A matrix containing the weights of the edges in the graph\n",
" node1: int\n",
" The index of the first node of the edge\n",
" node2: int\n",
" The index of the second node of the edge\n",
"\n",
" Returns\n",
" -------\n",
" cycle: list of ints\n",
" A list of indices representing the nodes of the cycle in order\n",
" \"\"\"\n",
" N = graph.shape[0]\n",
" distances = np.inf * np.ones(N)\n",
" distances[node2] = 0\n",
" prev_nodes = np.zeros(N)\n",
" prev_nodes[:] = np.nan\n",
" prev_nodes[node2] = node1\n",
" while (math.isnan(prev_nodes[node1])):\n",
" distances_buffer = distances\n",
" for j in range(N):\n",
" possible_path_lengths = distances_buffer + graph[:,j]\n",
" if (np.min(possible_path_lengths) < distances[j]):\n",
" prev_nodes[j] = np.argmin(possible_path_lengths)\n",
" distances[j] = np.min(possible_path_lengths)\n",
" prev_nodes = prev_nodes.astype(int)\n",
" cycle = [node1]\n",
" while (cycle[0] != node2):\n",
" cycle.insert(0,prev_nodes[cycle[0]])\n",
" cycle.insert(0,node1)\n",
" return cycle\n",
"\n",
"\n",
"def cohomological_parameterization(X ,cocycle_number=1, coeff=2,weighted=False):\n",
" \"\"\"\n",
" Compute an angular parametrization on the data set corresponding to a given\n",
" 1-cycle\n",
" \n",
" Parameters\n",
" ----------\n",
" X: ndarray(n_datapoints, n_features):\n",
" Array containing the data\n",
" cocycle_number: int, optional, default 1\n",
" An integer specifying the 1-cycle used\n",
" The n-th most stable 1-cycle is used, where n = cocycle_number\n",
" coeff: int prime, optional, default 1\n",
" The coefficient basis in which we compute the cohomology\n",
" weighted: bool, optional, default False\n",
" When true use a weighted graph for smoother parameterization\n",
" as proposed in arxiv:1711.07205\n",
" \n",
" Returns\n",
" -------\n",
" decoding: ndarray(n_datapoints)\n",
" The parameterization of the dataset consisting of a number between\n",
" 0 and 1 for each datapoint, to be interpreted modulo 1\n",
" \"\"\"\n",
" # Get the cocycle\n",
" result = ripser.ripser(X, maxdim=1, coeff=coeff, do_cocycles=True)\n",
" diagrams = result['dgms']\n",
" cocycles = result['cocycles']\n",
" D = result['dperm2all']\n",
" dgm1 = diagrams[1]\n",
" idx = np.argsort(dgm1[:, 1] - dgm1[:, 0])[-cocycle_number] \n",
" cocycle = cocycles[1][idx]\n",
" thresh = dgm1[idx, 1]-EPSILON\n",
" \n",
" # Compute connectivity\n",
" N = X.shape[0]\n",
" connectivity = np.zeros([N,N])\n",
" for i in range(N):\n",
" for j in range(i):\n",
" if D[i, j] <= thresh:\n",
" connectivity[i,j] = 1\n",
" cocycle_array = np.zeros([N,N])\n",
" \n",
" # Lift cocycle\n",
" for i in range(cocycle.shape[0]):\n",
" cocycle_array[cocycle[i,0],cocycle[i,1]] = (\n",
" ((cocycle[i,2] + coeff/2) % coeff) - coeff/2\n",
" )\n",
" \n",
" # Weights\n",
" if (weighted):\n",
" def real_cocycle(x):\n",
" real_cocycle =(\n",
" connectivity * (cocycle_array + np.subtract.outer(x, x))\n",
" )\n",
" return np.ravel(real_cocycle)\n",
" \n",
" # Compute graph\n",
" x0 = np.zeros(N)\n",
" res = least_squares(real_cocycle, x0)\n",
" real_cocyle_array = res.fun\n",
" real_cocyle_array = real_cocyle_array.reshape(N,N)\n",
" real_cocyle_array = real_cocyle_array - np.transpose(real_cocyle_array)\n",
" graph = np.array(real_cocyle_array>0).astype(float)\n",
" graph[graph==0] = np.inf\n",
" graph = (D + EPSILON) * graph # Add epsilon to avoid NaNs\n",
" \n",
" # Compute weights\n",
" cycle_counts = np.zeros([N,N]) \n",
" iterator = trange(0, N, position=0, leave=True)\n",
" iterator.set_description(\"Computing weights for decoding\")\n",
" for i in iterator:\n",
" for j in range(N):\n",
" if (graph[i,j] != np.inf):\n",
" cycle = shortest_cycle(graph, j, i)\n",
" for k in range(len(cycle)-1):\n",
" cycle_counts[cycle[k], cycle[k+1]] += 1\n",
" \n",
" weights = cycle_counts / (D + EPSILON)**2\n",
" weights = np.sqrt(weights)\n",
" else:\n",
" weights = np.outer(np.ones(N),np.ones(N))\n",
" \n",
" def real_cocycle(x):\n",
" real_cocycle =(\n",
" weights * connectivity * (cocycle_array + np.subtract.outer(x, x))\n",
" )\n",
" return np.ravel(real_cocycle)\n",
" \n",
" # Smooth cocycle\n",
" print(\"Decoding...\", end=\" \")\n",
" x0 = np.zeros(N)\n",
" res = least_squares(real_cocycle, x0)\n",
" decoding = res.x\n",
" decoding = np.mod(decoding, 1)\n",
" print(\"done\")\n",
" \n",
" decoding = pd.DataFrame(decoding, columns=[\"decoding\"])\n",
" decoding = decoding.set_index(X.index)\n",
" return decoding\n"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Decoding... done\n"
]
}
],
"source": [
"decoding = cohomological_parameterization(pd.DataFrame(embed_r), cocycle_number=1, coeff=2, weighted=False)"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 576x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"fig, ax = plt.subplots(1,1,figsize=(8,6))\n",
"ax.scatter(decoding['decoding'], stim_r)\n",
"ax.set(title='circular parametrization', xlabel='parameter', ylabel='orientation')\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "cdd33726863b43038eba9f8f82643f16",
"version_major": 2,
"version_minor": 0
},
"image/png": "iVBORw0KGgoAAAANSUhEUgAABIAAAAGwCAYAAADR6h5QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOzdeXwdVfn48c8zM3fLnjRp2nTfoZRC2XdQZN8FUVEQFVxQUVHx58IXFbevitvXXVFUVBQRBJQdkX0r0BYo3dd0SZo9N7nLzDm/P+YmTdK0Tds0aW6ft6/7kuTOnXtmMr3Puc885xyx1qKUUkoppZRSSiml8pcz3A1QSimllFJKKaWUUnuXJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRSSimllFJKKaXynCaAlFJKKaWUUkoppfKcJoCUUkoppZRSSiml8pwmgJRS/RKRySJiRcQb7rb0JCK3isjXh7sd+zI9R0oppQaT9gn6fe/7ReR9w/HefYnIe0TkoeFuh1Jq36cJIKWU2kUi8riIXLUX929FZPre2v9IpYktpZRS+wpr7VnW2t/v6X5E5EoReWoXtt8mGWet/ZO19vQ9bYtSKv9pAkgpNej2tTuEQ21/Of6Rdpwjrb1KKZUP8u2zV0L6HUopNSLph5dS+wERmSAi/xCRehFpEJGf5H7viMiXRWSNiNSJyB9EpHQ7+6gRkXtEpFFElovI1T2e+4qI/F1EbhORVuDKfl6fEJGbc+/VIiJPiUgi99z5IvK6iDTnqmsO7PG6eSLysoi0ichfgXif/Z4rIq/mXvuMiMzdhfNygIg8nDumJSJyae7303K/O6zHsdeLyCki8g3gROAnItLe41xaEfmYiCwDluV+9yMRWScirSIyX0RO7PHeroh8UURW5I5tfu7v9ERukwW5/b9zZ8e5s3PU55ivFJGnReQnub/DmyJyao/n3y8ii3P7WikiH+7x3Ckisl5EPi8im4DfiUi5iNyXOz9Nuf8e3+M1j4vI13NtbheRe0VklIj8KXdeXhSRyQP4m3wIeA9wfdd+evxt7sy9/yoRubbHvnZ6XSql1P5GtE+wvfNyXC4mteT+/7gezz0uIt8QkaeBDmCq9KkGFpEP5OJnk4g8KCKTejxnReQjIrIs17afSuhA4BfAsbnY1pzb/hwReSUXJ9eJyFd6NLWrn9Cce82x0qeKaADHcpOEfYE2EXlIRCoHep6UUiOctVYf+tBHHj8AF1gA/AAoJOwsnZB77gPAcmAqUAT8A/hj7rnJgAW83M9PAD/Lvf5QoB54a+65rwBZ4ELCxHKin3b8FHgcGJdr03FADJgJJIHTgAhwfa5N0dxjDfDp3HOX5N7n67l9zgPqgKNz+3wfsBqI5Z7/GfCz7ZyXQmAd8H7Ay+1rCzA79/zVwBtAAfAg8L0er30cuKrP/izwMFDRdfzAe4FRuf1/BtgExHPPfQ5YBMwCBDgEGNVjX9N77Hu7x7mzc9TPcV8J+D22fyfQAlTknj8HmJZr08mEHd3Dcs+dknvt/+beO5E7votz56kYuAO4u8+5Wp7bZ2nunC4F3pY7L38AfjfAv8mtPY+L8FqbD/xP7jxMBVYCZwz0utSHPvShj/3pgfYJttcnqACagMtz8efduZ+74vLjwFrgoNzzEXr0BYALcu08MPf8l4FneuzfAvcBZcDE3Pk6M/fclcBTfdpzCnBw7vzNBTYDF/b3t+i7jwEey4rcuU7kfv72cF+b+tCHPobmMewN0Ic+9LF3H8CxuY6G189zjwLX9Ph5Vq4z5fXsYAATgAAo7rHtt4Bbc//9FeCJHbTBATqBQ/p57gbgb322rc11fk4CNgDS4/lnenT2fg7c1Gd/S4CTB3Be3gk82ed3vwRu7PHzPYRJmoXkOpC533d3+nr8zpLr/O7gPZu6zkGunRdsZ7u+CaDtHufOzlE/+76yn+1fAC7fzvZ3A5/M/fcpQIZcEms72x8KNPU5V1/q8fPNwP09fj4PeHUgfxO2TQAdDazts/0X2JpQ2uF1qQ996EMf+9sD7RNsr02XAy/0+d2zwJW5/34c+Fqf5x9nawLofuCDfdrdAUzK/WzJJdpyP/8N+H+5/76SPgmgftr3Q+AHuf/u/lv0eL57HwM8li/3eO4a4IHhvjb1oQ99DM0jr8bkKqX6NQFYY631+3muhvBuWpc1hJ276n62a7TWtvXZ9ogeP6/bQRsqCe8SrthZG6y1RkTWEd4VDIBaa63t875dJgHvE5FP9PhdNLfPnZkEHN1Vbp3jAX/s8fOvCZNAH7LWpgewz17nQEQ+C3ww1x4LlBCeCwj/Lv2dj+21dXvHadnxOepPf9vX5Np8FnAj4Z1Bh7CyZ1GPbeuttamuH0SkgPBO8plAee7XxSLiWmuD3M+be7y+s5+fi3oc587+Jj1NAmr6bO8CT/b4eUfXpVJK7W+0T9C/vsfete9xPX7e0TFNAn4kIjf3+J3kXt+13009nutga+zbhogcDXwbmEN4DDHCCtuBGMixDLgtSqn8onMAKZX/1gETpf9JGDcQdlq6TCQc4rO5n+0qRKS4z7a1PX62bN8WIEU4DGiHbRARIeyg1gIbgXG53/V83y7rgG9Ya8t6PAqstX/ZQVt6vva/fV5bZK39aK4dRYR33G4BviIiFQM41u7fSzjfz/XApUC5tbaMcKhV17Gso//zsb22bu84d3aO+tPf9htEJAbcCXwPqM61+d892tzrGHM+Q3iX+GhrbQnhHVr6vGagdvg36ee91wGr+mxfbK09ewftVUqp/Zn2CfrX99i79j3QY1oHfLjPeyestc8M4L372++fCW9ATbDWlhLOEyQ72L6ngRyLUmo/pQkgpfLfC4Sdpm+LSKGIxEXk+NxzfwE+LSJTcgmPbwJ/7Xtn0Fq7jrDM+lu5188lrGy5bSANsNYa4LfA93MTR7q5SQtjhGXQ54jIqSISIUwopHPv9yxh5/NaEYmIyNuBo3rs+tfAR0Tk6NxkioW5iROL2bn7gJkicnlu3xERObLHZJM/Al6y1l4F/Iuw89VlM+EcCTtSnGt7PeCJyP8QVgB1+Q1wk4jMyLV9roiM2s7+d3ScOztH/RndY/t3EM5Z8G+23mWsB/xcNdDOlpUtJqziac4lyW7cyfY7srO/Sd/z8gLQJuGk1IncdTVHRI7cgzYopVQ+0z5B//5NGH8uExFPwgUYZhPGpYH4BfAFETkIQERKc/F1IDYD40Uk2uN3xYRVVikROQq4rMdz9YBh+/2QPT0WpVQe0wSQUnkuNwznPGA64QSG6wnnWoGwA/ZHwskcVxHekftEP7uBcBLByYR3lu4inJflkV1oymcJhxK9CDQSTiTsWGuXEE6W/H+EdwXPA86z1mastRng7YRj2xtz7f5Hj2N7iXCy5p8Qzq+znB6rjYjIL0SkZ+KGHq9tI0xuvCt3TJtybYqJyAWEQ5q6Kk+uAw4Tkffkfv4RcImEK338eDvH+yDwAOGEx2sIz23P8vHvE3Z0HwJaCSuNErnnvgL8XsKVQi7
"text/html": [
"\n",
" <div style=\"display: inline-block;\">\n",
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
" Figure\n",
" </div>\n",
" <img src='data:image/png;base64,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
" </div>\n",
" "
],
"text/plain": [
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from mpl_toolkits import mplot3d\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"\n",
"%matplotlib inline\n",
"%matplotlib widget\n",
"\n",
"x, y, z = embed_r[:,0], embed_r[:,1], embed_r[:,2]\n",
"\n",
"fig, ax = plt.subplots(1, 1, figsize=(8, 6))\n",
"ax = fig.add_subplot(1, 1, 1, projection='3d')\n",
"ax.scatter3D(x, y, z, c=decoding, cmap='hsv')\n",
"\n",
"from mpl_toolkits import mplot3d\n",
"from mpl_toolkits.mplot3d import Axes3D\n",
"\n",
"%matplotlib inline\n",
"%matplotlib widget\n",
"\n",
"fig = plt.figure(figsize=(16, 6))\n",
"\n",
"x_r, y_r, z_r = embed_r[:,0], embed_r[:,1], embed_r[:,2]\n",
"\n",
"ax1 = fig.add_subplot(1, 2, 1, projection='3d')\n",
"ax1.scatter3D(x_r, y_r, z_r, c=decoding['decoding'], cmap='hsv')\n",
"\n",
"ax1.set(xlabel=\"U0\", ylabel=\"U1\", zlabel=\"U2\", xticks=[], yticks=[], zticks=[], title='color code: extracted parameter')\n",
"\n",
"x_r, y_r, z_r = embed_r[:,0], embed_r[:,1], embed_r[:,2]\n",
"\n",
"ax2 = fig.add_subplot(1, 2, 2, projection='3d')\n",
"ax2.scatter3D(x_r, y_r, z_r, c=stim_r, cmap='hsv')\n",
"ax2.set(xlabel=\"U0\", ylabel=\"U1\", zlabel=\"U2\", xticks=[], yticks=[], zticks=[], title='color code: orientation')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.8.10 64-bit",
"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.8.10"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "c3057a75a033c35728e4dd89a89a6bf948e5354d1015c384d386d516b0ed8dfa"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}