{ "cells": [ { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "meta", "difficulty": 1, "kind": "orientation", "title": "Objectives" } }, "source": "## META | difficulty 1 | Objectives\n\nThis bundle introduces the transform itself in its negacyclic form.\n\nFocus:\n\n- the difference between `\u03c9` and `\u03c8`\n- direct NTT\u03c8 and INTT\u03c8\n- the direct convolution theorem in the negacyclic setting\n- why this is still too slow at `O(n^2)` without butterflies\n" }, { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "meta", "difficulty": 1, "kind": "route_nav", "title": "Route Guardrails" } }, "source": "## META | difficulty 1 | Route Guardrails\n\nYou are at **step 7 of 27** in the only supported route.\n\nNever choose the next notebook manually from the file tree. Use only the links in this cell and the final handoff cell.\n\n**Immediate navigation**\n- Next notebook: [Foundations / 02 Negative Wrapped NTT / Lab](lab.ipynb)\n- Previous notebook: [Foundations / 01 Convolution To Toy NTT / Studio](../01_convolution_to_toy_ntt/studio.ipynb)\n- Restart route: [Start Here](../../START_HERE.ipynb)\n\n**Official route chain**\n1. [Start Here](../../START_HERE.ipynb)\n2. [Course Blueprint](../../COURSE_BLUEPRINT.ipynb)\n3. [Foundations / 01 Convolution To Toy NTT / Lecture](../01_convolution_to_toy_ntt/lecture.ipynb)\n4. [Foundations / 01 Convolution To Toy NTT / Lab](../01_convolution_to_toy_ntt/lab.ipynb)\n5. [Foundations / 01 Convolution To Toy NTT / Problems](../01_convolution_to_toy_ntt/problems.ipynb)\n6. [Foundations / 01 Convolution To Toy NTT / Studio](../01_convolution_to_toy_ntt/studio.ipynb)\n7. **Foundations / 02 Negative Wrapped NTT / Lecture** <- you are here\n8. [Foundations / 02 Negative Wrapped NTT / Lab](lab.ipynb)\n9. [Foundations / 02 Negative Wrapped NTT / Problems](problems.ipynb)\n10. [Foundations / 02 Negative Wrapped NTT / Studio](studio.ipynb)\n11. [Butterfly Mechanics / 03 Fast Forward CT / Lecture](../../butterfly_mechanics/03_fast_forward_ct/lecture.ipynb)\n12. [Butterfly Mechanics / 03 Fast Forward CT / Lab](../../butterfly_mechanics/03_fast_forward_ct/lab.ipynb)\n13. [Butterfly Mechanics / 03 Fast Forward CT / Problems](../../butterfly_mechanics/03_fast_forward_ct/problems.ipynb)\n14. [Butterfly Mechanics / 03 Fast Forward CT / Studio](../../butterfly_mechanics/03_fast_forward_ct/studio.ipynb)\n15. [Butterfly Mechanics / 04 Fast Inverse GS / Lecture](../../butterfly_mechanics/04_fast_inverse_gs/lecture.ipynb)\n16. [Butterfly Mechanics / 04 Fast Inverse GS / Lab](../../butterfly_mechanics/04_fast_inverse_gs/lab.ipynb)\n17. [Butterfly Mechanics / 04 Fast Inverse GS / Problems](../../butterfly_mechanics/04_fast_inverse_gs/problems.ipynb)\n18. [Butterfly Mechanics / 04 Fast Inverse GS / Studio](../../butterfly_mechanics/04_fast_inverse_gs/studio.ipynb)\n19. [Kyber Mapping / 05 Kyber NTT And Base Multiplication / Lecture](../../kyber_mapping/05_kyber_ntt_and_base_multiplication/lecture.ipynb)\n20. [Kyber Mapping / 05 Kyber NTT And Base Multiplication / Lab](../../kyber_mapping/05_kyber_ntt_and_base_multiplication/lab.ipynb)\n21. [Kyber Mapping / 05 Kyber NTT And Base Multiplication / Problems](../../kyber_mapping/05_kyber_ntt_and_base_multiplication/problems.ipynb)\n22. [Kyber Mapping / 05 Kyber NTT And Base Multiplication / Studio](../../kyber_mapping/05_kyber_ntt_and_base_multiplication/studio.ipynb)\n23. [Professional / 06 Debugging NTT Failures / Lecture](../../professional/06_debugging_ntt_failures/lecture.ipynb)\n24. [Professional / 06 Debugging NTT Failures / Lab](../../professional/06_debugging_ntt_failures/lab.ipynb)\n25. [Professional / 06 Debugging NTT Failures / Problems](../../professional/06_debugging_ntt_failures/problems.ipynb)\n26. [Professional / 06 Debugging NTT Failures / Studio](../../professional/06_debugging_ntt_failures/studio.ipynb)\n27. [Course Complete](../../COURSE_COMPLETE.ipynb)\n" }, { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 2, "kind": "explanation", "title": "Why \u03c8 Shows Up" } }, "source": "## MANDATORY | difficulty 2 | Why \u03c8 Shows Up\n\nFor negative-wrapped convolution, the clean transform formula uses a `2n`-th root `\u03c8` with:\n\n- `\u03c8^2 = \u03c9`\n- `\u03c8^n = -1`\n\nThat is what bakes the negacyclic sign rule into the transform itself.\n" }, { "cell_type": "code", "execution_count": null, "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 2, "kind": "demo", "title": "Inspect \u03c9, \u03c8, And The Direct Transform Matrix" } }, "outputs": [], "source": "# MANDATORY | difficulty 2 | Inspect \u03c9, \u03c8, And The Direct Transform Matrix\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import find_primitive_root, find_psi, ntt_psi_exponent_grid, ntt_psi_matrix\nfrom ntt_learning.visuals import direct_ntt_player, plot_ntt_psi_exponent_heatmap, plot_ntt_psi_matrix_heatmap\n\nmodulus = 17\nn = 4\nomega = find_primitive_root(n, modulus)\npsi = find_psi(n, modulus)\n\nprint(\"omega:\", omega)\nprint(\"psi:\", psi)\nprint(\"exponent grid:\")\nfor row in ntt_psi_exponent_grid(n):\n print(row)\nprint(\"NTT_psi matrix:\")\nfor row in ntt_psi_matrix(n, modulus, psi):\n print(row)\n\ndisplay(direct_ntt_player([1, 2, 3, 4], modulus, psi))\ndisplay(plot_ntt_psi_exponent_heatmap(n, title=\"Exponents 2ij + i for n=4\"))\ndisplay(plot_ntt_psi_matrix_heatmap(n, modulus, psi, title=\"Concrete NTT_psi matrix in Z_17\"))\n" }, { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 2, "kind": "explanation", "title": "Direct NTT\u03c8 Is Mechanically Clear But Still Quadratic" } }, "source": "## MANDATORY | difficulty 2 | Direct NTT\u03c8 Is Mechanically Clear But Still Quadratic\n\nThe direct transform is useful because every coefficient and every exponent is visible.\nIt is not yet efficient. It still performs the full matrix multiplication.\n" }, { "cell_type": "code", "execution_count": null, "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 2, "kind": "demo", "title": "Run A Direct NTT\u03c8 / INTT\u03c8 Round Trip" } }, "outputs": [], "source": "# MANDATORY | difficulty 2 | Run A Direct NTT\u03c8 / INTT\u03c8 Round Trip\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import find_psi, forward_ntt_psi, inverse_ntt_psi\nfrom ntt_learning.visuals import direct_ntt_player\n\nsignal = [1, 2, 3, 4]\nmodulus = 17\npsi = find_psi(len(signal), modulus)\nspectrum = forward_ntt_psi(signal, modulus, psi)\n\nprint(\"signal:\", signal)\nprint(\"spectrum:\", spectrum)\nprint(\"inverse recovery:\", inverse_ntt_psi(spectrum, modulus, psi))\ndisplay(direct_ntt_player(signal, modulus, psi))\n" }, { "cell_type": "code", "execution_count": null, "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 3, "kind": "demo", "title": "Use Direct NTT\u03c8 For Negacyclic Multiplication" } }, "outputs": [], "source": "# MANDATORY | difficulty 3 | Use Direct NTT\u03c8 For Negacyclic Multiplication\n\nfrom IPython.display import display\n\nfrom ntt_learning.toy_ntt import find_psi, forward_ntt_psi, inverse_ntt_psi, negacyclic_multiply, pointwise_multiply\nfrom ntt_learning.visuals import plot_transform_pipeline\n\nleft = [1, 2, 3, 4]\nright = [5, 6, 7, 8]\nmodulus = 17\npsi = find_psi(4, modulus)\n\nleft_hat = forward_ntt_psi(left, modulus, psi)\nright_hat = forward_ntt_psi(right, modulus, psi)\nproduct_hat = pointwise_multiply(left_hat, right_hat, modulus)\n\nprint(\"NTT_psi(left):\", left_hat)\nprint(\"NTT_psi(right):\", right_hat)\nprint(\"pointwise product:\", product_hat)\nprint(\"inverse of pointwise product:\", inverse_ntt_psi(product_hat, modulus, psi))\nprint(\"schoolbook negacyclic:\", negacyclic_multiply(left, right, n=4, modulus=modulus))\ndisplay(plot_transform_pipeline(left, right, modulus=modulus, psi=psi, title=\"Direct negacyclic multiply pipeline\"))\n" }, { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "mandatory", "difficulty": 2, "kind": "quiz", "title": "Retrieval Check" } }, "source": "## MANDATORY | difficulty 2 | Retrieval Check\n\n1. Why is `\u03c8` stronger than `\u03c9` in the negacyclic story?\n2. What exact property does the inverse add that the forward transform does not?\n3. Why are we still dissatisfied after seeing the direct transform work correctly?\n" }, { "cell_type": "code", "execution_count": null, "metadata": { "pedagogy": { "role": "facultative", "difficulty": 4, "kind": "exploration", "title": "Optional: Compare Positive And Negative Wrapped Transforms" } }, "outputs": [], "source": "# FACULTATIVE | difficulty 4 | Optional: Compare Positive And Negative Wrapped Transforms\n\nfrom ntt_learning.toy_ntt import find_primitive_root, find_psi, forward_ntt, forward_ntt_psi\n\nsignal = [1, 2, 3, 4]\nmodulus = 17\nomega = find_primitive_root(4, modulus)\npsi = find_psi(4, modulus)\n\nprint(\"positive-wrapped NTT:\", forward_ntt(signal, modulus, omega))\nprint(\"negative-wrapped NTT_psi:\", forward_ntt_psi(signal, modulus, psi))\n" }, { "cell_type": "markdown", "metadata": { "pedagogy": { "role": "meta", "difficulty": 1, "kind": "handoff", "title": "Next Notebook" } }, "source": "## META | difficulty 1 | Next Notebook\n\nYou finished **Foundations / 02 Negative Wrapped NTT / Lecture**.\n\n**Primary next action**\n- Next notebook: [Step 8 of 27 - Foundations / 02 Negative Wrapped NTT / Lab](lab.ipynb)\n\n**Recovery links if you get lost**\n- Previous notebook: [Foundations / 01 Convolution To Toy NTT / Studio](../01_convolution_to_toy_ntt/studio.ipynb)\n- Restart route: [Start Here](../../START_HERE.ipynb)\n" } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python" }, "ntt_learning": { "title": "Lecture: Negative-Wrapped 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 }