Skip to content

Commit

Permalink
Explain edge collapse
Browse files Browse the repository at this point in the history
  • Loading branch information
danshapero committed Jan 2, 2025
1 parent 234b3f4 commit 79af7bc
Showing 1 changed file with 97 additions and 47 deletions.
144 changes: 97 additions & 47 deletions demo/simplification.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@
"metadata": {},
"outputs": [],
"source": [
"triangle_ids = list(set(cotriangles[vertex0]).union(cotriangles[vertex1]))\n",
"triangle_ids0 = cotriangles[vertex0]\n",
"triangle_ids1 = cotriangles[vertex1]\n",
"triangle_ids = list(set(triangle_ids0).union(triangle_ids1))\n",
"patch = triangles[triangle_ids]\n",
"patch"
]
Expand Down Expand Up @@ -190,118 +192,166 @@
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8a107f56-2ff8-4fd6-88ad-7575846fb360",
"cell_type": "markdown",
"id": "e950ce37-00ed-43c4-9cf4-a0432605fa47",
"metadata": {},
"outputs": [],
"source": [
"copatch = [[] for index in range(len(vertex_ids))]\n",
"for index, triangle in enumerate(patch):\n",
" for vertex in triangle:\n",
" copatch[vertex].append(index)\n",
"\n",
"copatch"
"Now we'll convert this simplicial complex into its linear algebraic representation."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "db782eb7-f6d3-4f80-8398-5ac1d88a4181",
"id": "f22ef651-af3b-455c-8483-f410e07c6d10",
"metadata": {},
"outputs": [],
"source": [
"Q0 = zmsh.simplification.compute_qmatrix(points[vertex_ids[patch[copatch[vtx0]]]])\n",
"Q1 = zmsh.simplification.compute_qmatrix(points[vertex_ids[patch[copatch[vtx1]]]])\n",
"Q0, Q1"
"d_0, d_1, d_2 = zmsh.polytopal.from_simplicial(patch)"
]
},
{
"cell_type": "markdown",
"id": "87f91fc4-ed34-4c9b-96b0-fd61facb86ce",
"metadata": {},
"source": [
"We'll first collapse the edge between vertex 0 and vertex 1.\n",
"To do that, we can perform a row operation on the $d_1$ matrix.\n",
"The operation is to add the rows corresponding to vertex 0 and vertex 1 together.\n",
"We'll then zero out the row corresponding to vertex 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fe136419-7682-4557-a6b4-ddb1ad062169",
"id": "e451bdec-1d96-4558-aeb5-db06e7e0ddda",
"metadata": {},
"outputs": [],
"source": [
"Q = Q0 + Q1\n",
"Q[0, 0] = 1\n",
"Q[0, 1:] = 0\n",
"f = np.array([1, 0, 0, 0])\n",
"r = np.linalg.solve(Q, f)[1:]\n",
"r, points[triangles[0][0]]"
"P = np.eye(len(vertex_ids), dtype=np.int8)\n",
"P[vtx0, [vtx0, vtx1]] = (+1, +1)\n",
"P[vtx1, :] = 0\n",
"P"
]
},
{
"cell_type": "markdown",
"id": "b3c894c1-0895-404b-8e8a-172429882dea",
"metadata": {},
"source": [
"The cell below shows the resulting matrix, which we'll call $e_1$.\n",
"(I'm showing the transpose so that we don't have to spill lines.)\n",
"You might notice that, for example, rows 0 and 1 are identical.\n",
"Any two rows that are scalar multiples of each other can be merged.\n",
"The adjacency of higher-dimensional cells can then be coalesced into adjacency to the merged cell."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f3a012fa-56e3-4f03-ae26-2defa19ad949",
"id": "bc0e2b8c-b2fe-466d-a90c-3c87c2f73139",
"metadata": {},
"outputs": [],
"source": [
"fig, ax = plt.subplots(subplot_kw={\"projection\": \"3d\"})\n",
"colors = [\"tab:green\" for index in range(len(vertex_ids))]\n",
"colors[vtx0] = \"tab:orange\"\n",
"colors[vtx1] = \"tab:orange\"\n",
"ax.plot_trisurf(x[vertex_ids], y[vertex_ids], z[vertex_ids], triangles=patch)\n",
"ax.scatter(x[vertex_ids], y[vertex_ids], z[vertex_ids], color=colors)\n",
"ax.scatter([r[0]], [r[1]], [r[2]], color=\"black\");"
"e_1 = P @ d_1\n",
"e_1.T"
]
},
{
"cell_type": "markdown",
"id": "2ca5ef8d-739d-4440-a4ea-17db3ff03725",
"metadata": {},
"source": [
"The function below creates the matrices that we will multiply by $e_1$ and $d_2$ in order to merge these cells."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f22ef651-af3b-455c-8483-f410e07c6d10",
"id": "14b1458c-39c8-449a-bbc1-1323f6d0fc85",
"metadata": {},
"outputs": [],
"source": [
"d0, d1, d2 = zmsh.polytopal.from_simplicial(patch)"
"A, B = zmsh.polytopal.make_reduction_matrices(e_1)"
]
},
{
"cell_type": "markdown",
"id": "35e83e9d-daa8-49dc-b7e3-134ef16af068",
"metadata": {},
"source": [
"The matrix $A$ selects some of the columns of $e_1$."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e451bdec-1d96-4558-aeb5-db06e7e0ddda",
"id": "b1696315-05a0-4658-a418-70c747853dc9",
"metadata": {},
"outputs": [],
"source": [
"P0 = np.eye(len(vertex_ids), dtype=np.int8)\n",
"P0[vtx0, [vtx0, vtx1]] = (+1, +1)\n",
"P0[vtx1, :] = 0\n",
"P0"
"print(A)"
]
},
{
"cell_type": "markdown",
"id": "2130b3cd-f322-4205-b9aa-f95cad2eabb6",
"metadata": {},
"source": [
"Meanwhile the matrix $B$ does a row operation to collapse the incidence of any 2-cells to redundant edges down to the remaining non-redundant edges."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bc0e2b8c-b2fe-466d-a90c-3c87c2f73139",
"id": "64c97f9e-b118-469e-bb3b-c3f105d7fbdc",
"metadata": {},
"outputs": [],
"source": [
"e1 = P0 @ d1\n",
"e1.T"
"print(B)"
]
},
{
"cell_type": "markdown",
"id": "fec2c6b5-fd1c-43a5-aa99-877379a6edac",
"metadata": {},
"source": [
"If we look at $e_1\\cdot A$, we can see that there are no columns left that are multiples of each other."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "67f584cf-f121-47b6-8fa7-35b45710e4c9",
"id": "1088710f-4b44-49be-bf17-ac2c5df9b8ac",
"metadata": {},
"outputs": [],
"source": [
"for index0, col0 in enumerate(e1.T):\n",
" for index1, col1 in enumerate(e1.T):\n",
" if (np.array_equal(col0, col1) or np.array_equal(col0, -col1)) and (index0 != index1) and (not np.all(col0 == 0)):\n",
" print(index0, index1)"
"print(e_1 @ A)"
]
},
{
"cell_type": "markdown",
"id": "1e546417-668c-4420-836b-7d3a640de149",
"metadata": {},
"source": [
"And the columns of $B\\cdot d_2$ have their adjacencies to redundant columns summed together."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "42db5da8-937c-418f-8112-02cbc4a49918",
"id": "2f5b82f2-eb7e-4e36-bfbd-49e8005ba144",
"metadata": {},
"outputs": [],
"source": [
"zmsh.polytopal.merge([e1, d2], face_ids=[3, 13])"
"print(B @ d_2)"
]
},
{
"cell_type": "markdown",
"id": "71ba922a-096d-4108-b205-bec49df309d2",
"metadata": {},
"source": [
"You'll also note that some 2-cells are now empty, which we expect."
]
}
],
Expand Down

0 comments on commit 79af7bc

Please sign in to comment.