NTT-learning/notebooks/foundations/01_convolution_to_toy_ntt/lecture.ipynb

163 lines
8.3 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "meta",
"difficulty": 1,
"kind": "orientation",
"title": "Objectives"
}
},
"source": "## META | difficulty 1 | Objectives\n\nThis first bundle is about making the raw multiplication problem visible before any transform is introduced.\n\nFocus:\n\n- the schoolbook product grid\n- diagonal sums\n- cyclic vs negacyclic folding\n- a tiny teaser of why transforms help\n"
},
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "explanation",
"title": "Schoolbook Multiplication Is A Grid"
}
},
"source": "## MANDATORY | difficulty 2 | Schoolbook Multiplication Is A Grid\n\nStop thinking \u201cmultiply two polynomials\u201d as one sentence.\nThe mechanical reality is a grid of pairwise products whose diagonals have to be accumulated.\n\nIf that grid is not concrete, the NTT has nothing to optimize in your mind.\n"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "demo",
"title": "See The Product Grid And The Diagonal Sums"
}
},
"outputs": [],
"source": "# MANDATORY | difficulty 2 | See The Product Grid And The Diagonal Sums\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import convolution_contributions, schoolbook_convolution\nfrom ntt_learning.visuals import plot_convolution_grid\n\nleft = [1, 2, 3, 4]\nright = [5, 6, 7, 8]\nraw = schoolbook_convolution(left, right)\n\nprint(\"raw convolution:\", raw)\nfor row in convolution_contributions(left, right):\n print(row)\n\nfig = plot_convolution_grid(left, right, title=\"Schoolbook products for [1,2,3,4] * [5,6,7,8]\")\ndisplay(fig)\n"
},
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "explanation",
"title": "Wraparound Is The First Structural Fork"
}
},
"source": "## MANDATORY | difficulty 2 | Wraparound Is The First Structural Fork\n\nOnce the raw tail exists, the ring tells you what to do with it.\n\n- in `x^n - 1`, high-degree terms wrap back with a positive sign\n- in `x^n + 1`, high-degree terms wrap back with a sign flip\n\nThat sign flip is not cosmetic. It is exactly what makes the negacyclic story different.\n"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "demo",
"title": "See Cyclic And Negacyclic Folding Side By Side"
}
},
"outputs": [],
"source": "# MANDATORY | difficulty 2 | See Cyclic And Negacyclic Folding Side By Side\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import negacyclic_multiply, schoolbook_convolution, wraparound_contributions\nfrom ntt_learning.visuals import plot_wraparound\n\nleft = [1, 2, 3, 4]\nright = [5, 6, 7, 8]\nraw = schoolbook_convolution(left, right)\n\nprint(\"raw convolution:\", raw)\nprint(\"negacyclic in x^4 + 1:\", negacyclic_multiply(left, right, n=4))\nprint(\"cyclic folding rows:\")\nfor row in wraparound_contributions(raw, n=4, negacyclic=False):\n print(row)\nprint(\"negacyclic folding rows:\")\nfor row in wraparound_contributions(raw, n=4, negacyclic=True):\n print(row)\n\ndisplay(plot_wraparound(raw, n=4, negacyclic=False, title=\"Cyclic folding into x^4 - 1\"))\ndisplay(plot_wraparound(raw, n=4, negacyclic=True, title=\"Negacyclic folding into x^4 + 1\"))\n"
},
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "explanation",
"title": "The Tiny Transform Teaser"
}
},
"source": "## MANDATORY | difficulty 2 | The Tiny Transform Teaser\n\nThe transform is not magic. It is a change of coordinates chosen so that multiplication gets easier.\n\nThe next bundle will treat the transform itself directly.\nThis first bundle only makes sure the learner can see the raw thing being optimized.\n"
},
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "mandatory",
"difficulty": 2,
"kind": "quiz",
"title": "Retrieval Check"
}
},
"source": "## MANDATORY | difficulty 2 | Retrieval Check\n\nAnswer in words before moving on:\n\n1. Why do diagonal sums appear in schoolbook multiplication?\n2. What is the one exact sign difference between cyclic and negacyclic folding?\n3. If you cannot track the tail wraparound, what part of the NTT story will stay vague?\n"
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"pedagogy": {
"role": "facultative",
"difficulty": 4,
"kind": "exploration",
"title": "Optional: Compare Another Example"
}
},
"outputs": [],
"source": "# FACULTATIVE | difficulty 4 | Optional: Compare Another Example\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import negacyclic_multiply, schoolbook_convolution\nfrom ntt_learning.visuals import plot_convolution_grid, plot_wraparound\n\nleft = [2, 1, 0, 3]\nright = [4, 0, 1, 2]\nraw = schoolbook_convolution(left, right)\n\nprint(\"raw convolution:\", raw)\nprint(\"negacyclic:\", negacyclic_multiply(left, right, n=4))\ndisplay(plot_convolution_grid(left, right, title=\"A second schoolbook grid\"))\ndisplay(plot_wraparound(raw, n=4, negacyclic=True, title=\"A second negacyclic fold\"))\n"
},
{
"cell_type": "markdown",
"metadata": {
"pedagogy": {
"role": "meta",
"difficulty": 1,
"kind": "handoff",
"title": "Next Notebook"
}
},
"source": "## META | difficulty 1 | Next Notebook\n\nNext notebook: `lab.ipynb`\n"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
},
"ntt_learning": {
"title": "Lecture: Convolution To Toy NTT",
"contract_version": "0.2",
"sequence": [
"notebooks/START_HERE.ipynb",
"notebooks/COURSE_BLUEPRINT.ipynb",
"notebooks/foundations/01_convolution_to_toy_ntt/lecture.ipynb",
"notebooks/foundations/01_convolution_to_toy_ntt/lab.ipynb",
"notebooks/foundations/01_convolution_to_toy_ntt/problems.ipynb",
"notebooks/foundations/01_convolution_to_toy_ntt/studio.ipynb",
"notebooks/foundations/02_negative_wrapped_ntt/lecture.ipynb",
"notebooks/foundations/02_negative_wrapped_ntt/lab.ipynb",
"notebooks/foundations/02_negative_wrapped_ntt/problems.ipynb",
"notebooks/foundations/02_negative_wrapped_ntt/studio.ipynb",
"notebooks/butterfly_mechanics/03_fast_forward_ct/lecture.ipynb",
"notebooks/butterfly_mechanics/03_fast_forward_ct/lab.ipynb",
"notebooks/butterfly_mechanics/03_fast_forward_ct/problems.ipynb",
"notebooks/butterfly_mechanics/03_fast_forward_ct/studio.ipynb",
"notebooks/butterfly_mechanics/04_fast_inverse_gs/lecture.ipynb",
"notebooks/butterfly_mechanics/04_fast_inverse_gs/lab.ipynb",
"notebooks/butterfly_mechanics/04_fast_inverse_gs/problems.ipynb",
"notebooks/butterfly_mechanics/04_fast_inverse_gs/studio.ipynb",
"notebooks/kyber_mapping/05_kyber_ntt_and_base_multiplication/lecture.ipynb",
"notebooks/kyber_mapping/05_kyber_ntt_and_base_multiplication/lab.ipynb",
"notebooks/kyber_mapping/05_kyber_ntt_and_base_multiplication/problems.ipynb",
"notebooks/kyber_mapping/05_kyber_ntt_and_base_multiplication/studio.ipynb",
"notebooks/professional/06_debugging_ntt_failures/lecture.ipynb",
"notebooks/professional/06_debugging_ntt_failures/lab.ipynb",
"notebooks/professional/06_debugging_ntt_failures/problems.ipynb",
"notebooks/professional/06_debugging_ntt_failures/studio.ipynb",
"notebooks/COURSE_COMPLETE.ipynb"
]
}
},
"nbformat": 4,
"nbformat_minor": 5
}