QuTiP Virtual Lab Dev Log #3
This week in development of the QuTiP Virtual Lab, things are starting to take shape. It’s actually starting to look like an application.
But before I could devote 100% of my time to UI development, I had to take care of a couple of bugs with the compilation of QuTiP to WebAssembly.
When the application is built, it compiles QuTiP and its dependencies, and produces a WebAssembly module and a Javascript runtime.
Then, when the web app is run, the runtime gets bundled with the UI dependencies, like React and the graphing libraries, via a tool called webpack
.
The issue I was having was with bundling the runtime with the other dependencies, because the runtime was using an older syntax.
While webpack
is capable of transforming code (via plugins), I found that I could write a script to accomplish the same thing in a fraction of the time:
|
|
All this does is rename the variable package
to pkg
, and remove a dynamic import statement.
There are reasons for this but I will spare you, dear reader, the details.1
Finally an App that Works
Picking up from last week, I added the logic to call QuTiP when the Simulate button is pressed. According to my sketch, the button belongs to the section which also shows the details of the simulation, so I added a Details.jsx
component with the code.
|
|
The loadWasm
function is the main workhorse here and it is responsible for loading the compiled QuTiP.
It returns a pyjs
object, which is the Javascript runtime mentioned earlier.
To run Python code from this component, we just pass a valid Python script to the pyjs.exec
function as a Javascript string. In the component above, demo
is just the following code:
|
|
This code is just a demo of QuTiP’s solver for the Schrodinger equation. It solves the differential equation:
\[ i\hbar\frac{d \psi(t)}{dt} = \sigma_z \psi(t) \]
with initial condition
\[
\psi(0) = \begin{pmatrix}
1/\sqrt{3} \\\
2/\sqrt{3}
\end{pmatrix}
\]
and returns the Bloch vector of the state for times between 0 and 100. The results are then piped back to the Javascript application as a string, the result of calling Python’s print
function.
With all this in place, I finally had an application that could run QuTiP in the browser, just by pressing a button! After pressing Simulate, I could watch the runtime load the WebAssembly in the browser inspector, run the simulation, and print the result.
Once I had this example in place, I refactored the application to support caching the runtime.
This was the other main problem I set out to tackle as of last week.
The solution was to load the pyjs
object into React’s useRef function.
This keeps the runtime in memory for the life of the application, but it also allows React to access it across renders.
As a result, the runtime should only be loaded once, which means the user will not have to wait as long.
Next up: Inspecting the Results
Next week I will be focussing on adding more to the UI to support visualization of the results. The Bloch sphere will be getting a companion graph, and there will be more to look at in my next development post as a result.
As it turns out,
package
is a future reserved word in the Javascript language, so using it as a variable name would cause a syntax error. The dynamic import statement is problematic forwebpack
because it messes with the bundling algorithm that resolves dependencies. This application doesn’t actually need to use it, so we can just remove it from the source code. ↩︎
Comments