add the chemistry active space notebook course - #3568
add the chemistry active space notebook course#3568Dhairya Patel (HABER7789) wants to merge 155 commits into
Conversation
…ER7789/chemistry-course # Conflicts: # .gitignore
- Course now lives in resources/qdk-learning/courses/chemistry-qpe - Authoring tools in resources/qdk-learning/utils/chemistry-qpe, kept out of the package by .vscodeignore - Dropped the course id, the folder name is the id now - requirements.txt uses >= so a minor release does not break the course - Stopped calling the course a port in the manifest and README
| { | ||
| "id": "overview", | ||
| "title": "Tutorial Overview", | ||
| "dir": "overview" |
There was a problem hiding this comment.
Minor nit: But perhaps the overview directory should be 00- prefixed, and the actual content should start from 01-, that way the folders are listed in the correct order. (Not too important before getting this in though)
There was a problem hiding this comment.
That would be tidier, but shouldn't affect display order, only folder older.
There was a problem hiding this comment.
Yes, the course.json file controls the display order so I’ll rename them to 00-overview and the content from 01 to 06 and update the manifest and converter references.
| @@ -0,0 +1,2 @@ | |||
| qdk-chemistry[jupyter]>=2.1.0 | |||
| ipykernel>=6.0 | |||
There was a problem hiding this comment.
Do you need both this file and the importChecks in course.json? I see course.json also lists PySCF, which isn't here.
There was a problem hiding this comment.
This file is for constructing a venv. The import checks are for confirming that the current env (which may or may not be the course venv) has certain key imports available.
| "from the QDK course folder." | ||
| ) | ||
|
|
||
| course = json.loads(course_json_path.read_text()) |
There was a problem hiding this comment.
You nearly always want to pass the encoding="utf-8" parameter to read_text, else I believe it defaults to Windows-1252 on Windows, which can lead to... surprises.
There was a problem hiding this comment.
In fairness, this was almost certainly inherited - probably from a vibe-coded prototype.
There was a problem hiding this comment.
Alright. I'll add the encoding utf-8.
| .idea/ | ||
| *.so | ||
| samples/scratch/ | ||
| # A stray workspace created by running the extension at the repo root. |
There was a problem hiding this comment.
How did you manage to do that? All of the launch.json targets point at samples, don't they?
There was a problem hiding this comment.
This came from when I was locally testing, you are correct about the current launch.json I'll remove it.
| samples/qdk-learning/ | ||
| samples/qdk-learning.json | ||
| # Learner working copies and progress files, wherever a course is opened. | ||
| **/*.workbook.ipynb |
There was a problem hiding this comment.
These files should be under qdk-learning, so these lines seem unnecessary.
| coordinate-minimized selected orbitals needed by mapping, state | ||
| preparation, and visualization. | ||
| """ | ||
| ################################################################################ |
There was a problem hiding this comment.
How is this file used? If a learner will see it, we might want to clean up some of these delimiters.
| ("Packages", ", ".join(f"<code>{m}</code> missing" for m in missing), False) | ||
| ) | ||
| errors.append( | ||
| "Install missing packages by running the following in a new cell, then re-run this cell:" |
There was a problem hiding this comment.
Did you test this? I think I tried and didn't get the result I wanted, but chalked it up to my inexperience with Python.
There was a problem hiding this comment.
(If we really believe it works, maybe we should include it in the cell, commented out)
There was a problem hiding this comment.
Yes, I tested this requirements installation flow in WSL and it works. I agree it would be easier to discover in the notebook, so I’ll include it as a commented optional command in the environment check cell.
There was a problem hiding this comment.
Should we mention virtual environments? Otherwise, I think this might install globally.
| @@ -0,0 +1,13 @@ | |||
| # Ground-State Molecular Energies with QPE | |||
There was a problem hiding this comment.
Is this displayed to the user?
There was a problem hiding this comment.
It does show up in the file explorer but not in the QDK-Learning tree. I can remove this, since we have the setup instruction in the overview.
| { | ||
| "cell_type": "markdown", | ||
| "id": "sec-self-consistent-wavefunction-optimization", | ||
| "metadata" |
There was a problem hiding this comment.
I'm getting a bunch of warnings in the output window
2026-08-18 10:10:24.815 [warning] Learning: ignoring a "solution" cell for exercise "c-e37c60a46531" in unit "describe-molecule": expected a code cell.
2026-08-18 10:10:24.829 [warning] Learning: ignoring a "solution" cell for exercise "c-75c7822257be" in unit "active-space": expected a code cell.
2026-08-18 10:10:24.841 [warning] Learning: ignoring a "solution" cell for exercise "c-ed49001f7051" in unit "map-to-qubits": expected a code cell.
2026-08-18 10:10:24.857 [warning] Learning: ignoring a "solution" cell for exercise "c-6f500714745c" in unit "trial-state": expected a code cell.
2026-08-18 10:10:24.868 [warning] Learning: ignoring a "solution" cell for exercise "c-4cb620545394" in unit "iterative-phase-estimation": expected a code cell.
2026-08-18 10:10:24.868 [warning] Learning: ignoring a "solution" cell for exercise "c-1f5f4640f7af" in unit "iterative-phase-estimation": expected a code cell.
There was a problem hiding this comment.
If they're markdown cells, maybe they were intended to be tagged explanation?
There was a problem hiding this comment.
(If we think this is a stumbling block for authors, we could conceivably tag both types of cells as solution and partition them internally into solutions and solution explanations.)
There was a problem hiding this comment.
I believe these are from the sample exercises that I have created, they have a solution in the author's copy, but the solution code has not been tagged as solution by the converter and the markdown just has the code snippet format in the author's notebook.
| ("Packages", ", ".join(f"<code>{m}</code> missing" for m in missing), False) | ||
| ) | ||
| errors.append( | ||
| "Install missing packages by running the following in a new cell, then re-run this cell:" |
There was a problem hiding this comment.
Should we mention virtual environments? Otherwise, I think this might install globally.
| "section:running-the-chapter-3-workflow" | ||
| ] | ||
| }, | ||
| "source": "## Running the Chapter 3 workflow\n\nEverything below starts from the active space selected in Chapter 3. This cell reruns that workflow so the rest of the notebook has a selected space to map. It is the slowest cell here." |
There was a problem hiding this comment.
I don't think we mention chapter numbers elsewhere in the UI - they're certainly not in the tree. From context, I'm guessing it's the preceding chapter?
There was a problem hiding this comment.
Yes it is, I will replace them with unit titles
| "section:the-jordan-wigner-transformation" | ||
| ] | ||
| }, | ||
| "source": "## The Jordan--Wigner transformation\n\nThe [Jordan–Wigner transformation ↗](https://en.wikipedia.org/wiki/Jordan%E2%80%93Wigner_transformation) assigns each fermionic mode to one qubit.\nIn this molecular problem, each fermionic mode is one active spin orbital.\nTo keep the two kinds of labels distinct, let $\\ell_p$ denote the qubit assigned to fermionic mode $p$; its numerical qubit index is $p$.\n\n$$\n\\vert 0\\rangle_{\\ell_p} \\longleftrightarrow \\text{mode }p\\text{ unoccupied},\n\\qquad\n\\vert 1\\rangle_{\\ell_p} \\longleftrightarrow \\text{mode }p\\text{ occupied}.\n$$\n\nThe occupation operator becomes\n\n$$\n\\hat{n}_p=\\hat{a}_p^\\dagger\\hat{a}_p=\\frac{I_{\\ell_p}-Z_{\\ell_p}}{2}.\n$$\n\nThe creation and annihilation operators become\n\n$$\n\\hat{a}_p^\\dagger\n= \\frac{1}{2}\\left(\\prod_{j=0}^{p-1}Z_{\\ell_j}\\right)(X_{\\ell_p}-iY_{\\ell_p}),\n\\qquad\n\\hat{a}_p\n= \\frac{1}{2}\\left(\\prod_{j=0}^{p-1}Z_{\\ell_j}\\right)(X_{\\ell_p}+iY_{\\ell_p}).\n$$\n\nThe [Pauli operators ↗](https://en.wikipedia.org/wiki/Pauli_matrices) $X_{\\ell_p}$, $Y_{\\ell_p}$, and $Z_{\\ell_p}$ act on qubit $\\ell_p$.\nThe combinations $(X_{\\ell_p}-iY_{\\ell_p})/2$ and $(X_{\\ell_p}+iY_{\\ell_p})/2$ raise $\\vert 0\\rangle_{\\ell_p}$ to $\\vert 1\\rangle_{\\ell_p}$ and lower $\\vert 1\\rangle_{\\ell_p}$ to $\\vert 0\\rangle_{\\ell_p}$, respectively.\nWithin the product, $j$ indexes the lower fermionic modes and $Z_{\\ell_j}$ acts on the qubit assigned to mode $j$.\nThe product of $Z$ operators records the parity of occupied lower-indexed modes.\nEach occupied lower-indexed mode contributes an eigenvalue of $-1$, so the product is negative when an odd number of those modes is occupied.\nActing on mode $p$ crosses the occupied lower-indexed modes in the chosen fermionic ordering, with each crossing contributing a minus sign.\nThe parity string supplies their combined sign, so the mapped operators satisfy the fermionic anticommutation relations.\n\n<div style=\"text-align:center;\">\n\n\n\n*A fermionic mode is one active spin orbital. For target spin orbital $p=3$, the qubits assigned to preceding spin orbitals supply the parity string $Z_{\\ell_0}Z_{\\ell_1}Z_{\\ell_2}$, while qubit $\\ell_3$ changes the target occupation. The same pattern extends to any target $p$.*\n\n</div>\n\nBecause the parity strings depend on mode ordering, the ordering must be specified: QDK/Chemistry places all active $\\alpha$ modes before all active $\\beta$ modes, a convention called *blocked ordering*.\n\n<div style=\"border-left:4px solid #8c4a00;background:#8c4a001a;border-radius:4px;margin:1em 0;\"><details><summary style=\"background:#8c4a00;color:#ffffff;padding:0.35em 0.8em;cursor:pointer;font-weight:600;\">❓ Why does Jordan–Wigner need a string of Pauli Z operators?</summary>\n\n<div style=\"padding:0.1em 1em;\">\n\nThe $Z$ string records the parity of lower-indexed fermionic modes.\nIts sign ensures that encoded creation and annihilation operators anticommute even though operators on different qubits commute.\n\n</div>\n\n</details></div>", |
There was a problem hiding this comment.
-- was probably hoping to convey that this should be an emdash (which is odd, since it definitely seems like a place you'd put a hyphen/endash).
| "section:iqpe-circuit-visualization" | ||
| ] | ||
| }, | ||
| "source": "## IQPE circuit visualization\n\nThe cells below build the six iteration circuits and render the shortest one. No quantum simulation runs here.\n\n<div style=\"text-align:center;\">\n\n\n\n*Overview of the rendered power-one iteration circuit. Dashed outlines mark the nested `MakeIQPECircuit` and `RunIQPE` Q# operations; the solid boxes show their principal composite operations.*\n\n</div>\n\nThe top wire, $\\lvert\\psi_0\\rangle$, is readout ancilla q0.\nIts first H gate creates a superposition, and the `Rz(0.0000)` block applies the phase-feedback rotation.\nThis static preview constructs all six circuits with the builder's initial feedback angle of zero, so the displayed rotation is zero.\nDuring an actual IQPE run, each iteration circuit is rebuilt using the accumulated feedback from earlier measured bits; the power-one iteration can therefore have a nonzero feedback rotation.\n\nThe lower wires, $\\lvert\\psi_1\\rangle$ through $\\lvert\\psi_{12}\\rangle$, are compute-register qubits q1–q12.\nThe `StatePreparation` blocks load the four-determinant trial state on the subsets of compute wires that require preparation operations; blank wires remain part of the compute register.\nThe `RepControlledPauliExp` block is the power-one controlled first-order Trotter evolution.\nThe ancilla controls this block, and the resulting phase kickback places the Hamiltonian eigenphase on the ancilla's relative phase.\nThe final H gate converts that relative phase into measurement probabilities, the measurement produces one shot outcome, and the blue reset operations return the allocated qubits to $\\lvert0\\rangle$.\n\n<div style=\"border-left:4px solid #8c4a00;background:#8c4a001a;border-radius:4px;margin:1em 0;\"><details><summary style=\"background:#8c4a00;color:#ffffff;padding:0.35em 0.8em;cursor:pointer;font-weight:600;\">❓ How can you identify the readout ancilla in the rendered circuit?</summary>\n\n<div style=\"padding:0.1em 1em;\">\n\nThe q0 wire receives the H gates and feedback rotation, controls the Hamiltonian evolution, and is measured to obtain the phase bit.\nThe other twelve wires hold the prepared molecular state and form the compute register.\n\n</div>\n\n</details></div>\n\n<div style=\"border-left:4px solid #8c4a00;background:#8c4a001a;border-radius:4px;margin:1em 0;\"><details><summary style=\"background:#8c4a00;color:#ffffff;padding:0.35em 0.8em;cursor:pointer;font-weight:600;\">❓ Why do all six iteration circuits have the same width but different lengths?</summary>\n\n<div style=\"padding:0.1em 1em;\">\n\nEvery iteration uses the same twelve-qubit compute register and one readout ancilla, so each circuit has thirteen logical qubits.\nDifferent controlled powers repeat the approximate time-evolution unitary different numbers of times |
There was a problem hiding this comment.
Where is import json used?
There was a problem hiding this comment.
It has not been used, I will remove it. Thanks!
- Renumber the unit folders, starting with overview and regenerated the notebooks - Fix solution/explanation cells and exercise traceback behavior - Add utf-8 and kernel selection guidance for verification - Remove the sample course, duplicate README and unnecessary gitignore rules - Verified notebook terms, cross unit references and also unused imports
Andrew Casey (amcasey)
left a comment
There was a problem hiding this comment.
What editing process did you use that changed the IDs of the cells? We're relying on them to be stable, so that's potentially worrisome.
Ohh, thanks for catching this. So I regenerated the notebooks using the converter because I made changed to the code cells. It creates cell IDs from the cell text, so editing a cell changed its ID. Unchanged cells and all exercise IDs stayed the same. Would you like me to fix this before merge, or track it as a follow up? |
Chemistry Course
Ports the ground-state QPE tutorial from Sphinx rst into a notebook course, placed beside circuit-diagrams-new in the learning test workspace. chemistry-course-tools has the converter script, plus the verifier used to validate them.
This branch targets the branch behind #3526 and GitHub will retarget to main once it merges.
Note: This is content only; no extension code.