Skip to content

Add Julia tutorial for simulating time evolution of the Ising model - #5254

Open
haimeng-zhang wants to merge 35 commits into
Qiskit:mainfrom
haimeng-zhang:julia-tutorial
Open

Add Julia tutorial for simulating time evolution of the Ising model#5254
haimeng-zhang wants to merge 35 commits into
Qiskit:mainfrom
haimeng-zhang:julia-tutorial

Conversation

@haimeng-zhang

@haimeng-zhang haimeng-zhang commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Julia is a dynamic language designed for high-performance numerical and scientific computing, making it a natural fit for quantum simulation workflows. The tutorial shows how Julia is used for both classical pre- and post-processing (e.g., building Hamiltonians, running ODE solvers, computing expectation values) and for orchestrating quantum hardware jobs, eliminating the need to switch between languages or environments. The example used in this tutorial is simulating time evolution of the transverse-field Ising model.

To interface with IBM Quantum hardware from Julia, this tutorial uses two packages from the Qiskit ecosystem: Qiskit.jl wraps the Qiskit C API and provides circuit construction and transpilation functionality in Julia; QiskitIBMRuntime.jl connects to IBM Quantum hardware through the Qiskit IBM Runtime service, enabling job submission and result retrieval directly from Julia.

Files

The PR adds the following files:

  • the notebook docs/tutorials/time-evolution/time-evolution.ipynb
  • the files docs/tutorials/time-evolution/Project.toml and docs/tutorials/time-evolution/Manifest.toml, which are needed to set up the Julia environment and install the dependencies to run the notebook.

@qiskit-bot

Copy link
Copy Markdown
Contributor

Thanks for contributing to Qiskit documentation!

Before your PR can be merged, it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient. Thanks! 🙌

@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@henryzou50
henryzou50 self-requested a review June 17, 2026 14:23
@garrison

Copy link
Copy Markdown
Member

Before I forget ... the runtime client has a pending rename, which will be complete once JuliaRegistries/General#158556 merges.

@@ -0,0 +1,10 @@
[deps]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to remove both the toml files? These files won't render on the site and readers won't be able to see their contents. I would say if it's not critical to have the exact package versions installed you could just list these as packages the user should install. If it is, I would add the contents of Project.toml into the notebook through an accordion object.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kaelynj, Sorry for the late reply on this! I edited the Requirements section of the notebook. It now has a code cell that directly installs the tutorial dependencies; this way the installation experience is self-contained in the notebook. It also provide an alternative approach to install from the .toml files, by linking to the Qiskit documentation github repo for those files, for users who want exact reproducibility. Let me know if this looks good to you :)

Comment thread docs/tutorials/time-evolution/time-evolution.ipynb
Comment thread docs/tutorials/time-evolution/time-evolution.ipynb
"\n",
" # Neel state initialization\n",
" for i in 1:2:n\n",
" qc.x(i)\n",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of what a corresponding change would look like. Throughout, all mutating operations starting with qc. should be replaced with the corresponding method ending with a !.

Suggested change
" qc.x(i)\n",
" x!(qc, i)\n",

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for coming to this late. I've made this change to the tutorial. @garrison, please take a look.

Comment thread docs/tutorials/time-evolution/time-evolution.ipynb Outdated

@henryzou50 henryzou50 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together @haimeng-zhang! Overall the tutorial looks great and was easy to setup for me. I did note one potential bug and a few small changes below.

1. Bug: Rx angles are a factor of 2 too small

Rx(θ) = exp(−iθX/2), so the half-step exp(−i·h·X·δt/2) needs θ = h·δt, but both circuits use h[i] * δt / 2 -- the /2 double-counts the ½ already in the gate definition, so the circuits evolve under an effective field of h/2. (The Rzz angle is correct.) I confirmed numerically with the notebook's own exact-solution code at N=12: the TN circuit as written differs from exact(h=1) by up to 0.31 in site magnetization, but matches exact(h=0.5) to 3×10⁻⁴. This also contradicts the text before the final figure ("classical and tensor network results are now in close agreement").

The fix is dropping / 2 from the four Rx angle expressions (two per function — the Rx layer appears before and after the Rzz layer in each Trotter step). Rzz lines are untouched.

In make_trotter_circuit_tn:

         # first half X rotation
-        append!(circuit, [("Rx", [(i,)], h[i]* δt / 2) for i in 1:n])
+        append!(circuit, [("Rx", [(i,)], h[i] * δt) for i in 1:n])
         # ZZ interactions
         append!(circuit, [("Rzz", [(i,), (i+1,)], 2 * J[i] * δt) for i in 1:n-1])
         # second half X rotation
-        append!(circuit, [("Rx", [(i,)], h[i] * δt / 2) for i in 1:n])
+        append!(circuit, [("Rx", [(i,)], h[i] * δt) for i in 1:n])

In make_trotter_circuit (both rx! loops):

         for i in 1:n
-            rx!(qc, h[i] * δt / 2, i)
+            rx!(qc, h[i] * δt, i)
         end

After the fix, the notebook needs a full re-run, including the hardware jobs and all saved outputs.

2. Template alignment: label the simulator vs. hardware sections

Right now the hardware Steps 1–4 are H3 headers nested under ## Small-scale simulator example, so readers can't tell where simulation ends and hardware begins. Suggest restructuring the headers to follow the tutorial template:

  • Keep ## Small-scale simulator example — covering the exact solution and the TN simulation.
  • Add ## Large-scale hardware example immediately before ### Step 1: Map classical inputs to a quantum problem, with a one-line intro (and a brief note on the N=20 scale).

Two small additions while in there:

  • Add the usage estimate after the title (template format): Usage estimate: X minutes on ibm_y. (NOTE: This is an estimate only. Your runtime may vary.)
  • Add a short ## Next steps section at the end linking related material (e.g., Qiskit.jl repo, a related time-evolution tutorial).

3. Reproducibility: state the Julia version

The Manifest was generated with Julia 1.11.5, but Requirements doesn't mention a version. note that Option 2's "exact environment" depends on it. Add one line to Requirements, e.g. "This tutorial was developed with Julia 1.11; install via juliaup add 1.11."

4. Minor code cleanups

  • Delete s = siteinds("S=1/2", g), as it is unused.
  • Delete the fidelities accumulation (or mention the final fidelity in the text) -- currently unused after the loop.
  • Delete the bare job_list display cell -- redundant with the status loop that follows..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

7 participants