Undergrad Quirk: A drag-and-drop in-browser quantum circuit simulator

Click For Summary
Quirk is a drag-and-drop quantum circuit simulator that has recently improved with features like resizable gates and enhanced displays. It is primarily built using JavaScript, with a focus on real-time simulation and animation. Users have expressed interest in the underlying mathematics and functionality, particularly regarding complex linear algebra and state initialization. Although there is currently no formal documentation, users are encouraged to explore the code and ask questions for specific implementations. Quirk serves as a valuable tool for experimenting with quantum circuits, despite its complexity.
Strilanc
Science Advisor
Messages
612
Reaction score
229
(A follow-up on this thread.)

I've posted before about Quirk, the toy quantum circuit simulator I'm working on. It's improved quite a lot in the past month (e.g. resizable gates, more displays, log-scale indicators). So I figured I'd mention it again.

You can play with it at algorithmicassertions.com/quirk

I compare it to some other simulators in this blog post.
 
Last edited by a moderator:
  • Like
Likes MichPod, Boing3000, DrClaude and 3 others
Physics news on Phys.org
Wow, this is quite cool. What language are you using to construct it?

Is this your code at Github?

https://github.com/Strilanc/Quirk/

It looks like its based on Javascript.

You should check into Elm (www.elm-lang.org) as an implementing language for a challenge.

It is an FRP ie Functional Reactive Programming language and it compiles to Javascript.

What theory / book reference is your simulator based on?
 
10/10 for beautiful GUI.
I'm not sure what I am looking at though.
 
jedishrfu said:
Wow, this is quite cool. What language are you using to construct it?

Is this your code at Github?

https://github.com/Strilanc/Quirk/

It looks like its based on Javascript.

Yes, that's the repository and yes, it's mostly Javascript (+webgl and of course some HTML).

jedishrfu said:
You should check into Elm (www.elm-lang.org) as an implementing language for a challenge.

It is an FRP ie Functional Reactive Programming language and it compiles to Javascript.

It's a bit late in the project to be changing the language. Most of the code isn't really amenable to FRP; basically just the few hundred lines in main.js that deal with user interactions.

jedishrfu said:
What theory / book reference is your simulator based on?

The textbook that I read was Nielsen and Chuang. It'd be a bit odd to say simulator is based on that book, though, because the simulation is the simplest possible thing: represent the state as a big vector of amplitudes, and hit it with sparse matrix multiplications.
 
  • Like
Likes jedishrfu
Quirk is a browser-based drag-and-drop quantum circuit simulator that reacts, simulates, and animates in real-time.
I will certainly have fun with that, thanks.
 
jedishrfu said:
Have you seen this approach to simulating Quantum Computer at Univ of Texas at Austin?

http://www.arlut.utexas.edu/lab/cqr/index.html

This is a hardware simulation. They wrote a paper on it:

http://www.worldscientific.com/doi/10.1142/S0219749916400049

I think I remember reading about it, but I don't know much about the details.
 
A great program.

I have downloaded it from your git page, because I'm hoping to use some of the math functions as a library and try out some ideas.
Is there any documentation to help people to develop using your library elements?
 
Swamp Thing said:
A great program.

I have downloaded it from your git page, because I'm hoping to use some of the math functions as a library and try out some ideas.
Is there any documentation to help people to develop using your library elements?

Unfortunately, no. I'd start by looking at how other gates are implemented, and you can ask questions here about specifics.

Because all the heavy lifting is done by webgl shaders, and the shaders all need common features (e.g. applying to different wires, controls), I have code to write the shader code. And that code does different things based on features supported by the user's hardware. And gates have quite a lot of properties that do specific things... I know that it can look quite daunting.
 
  • #10
Actually, I'm going to do only some very simple toy problems, so I'm more interested in the math than the graphics part. For example, how can I initialize a ket and apply a matrix transform to it? How can I do inner products? That kind of really basic thing.

Did you develop the maths (complex linear algebra) from scratch?
 
  • #11
Swamp Thing said:
Actually, I'm going to do only some very simple toy problems, so I'm more interested in the math than the graphics part. For example, how can I initialize a ket and apply a matrix transform to it? How can I do inner products? That kind of really basic thing.

Did you develop the maths (complex linear algebra) from scratch?

Everything in Quirk is custom. Although I wouldn't say I "developed the math", I did write all the code to do the math.

The code is isn't really designed around scripting the simulator. So, ironically, the easiest way to initialize a state and apply a few transforms is to draw a little ascii diagram like a lot of the tests do:

Code:
perfGoal(
    "16-Qubit QFT gate with manual de-QFT",
    millis(75),
    circuit => CircuitStats.fromCircuitAtTime(circuit, 0),
    diagram(`-Q-H-1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---
             -/---•-H-1---2---3---4---5---6---7---8---9---A---B---C---D---E---
             -/-------•-H-1---2---3---4---5---6---7---8---9---A---B---C---D---
             -/-----------•-H-1---2---3---4---5---6---7---8---9---A---B---C---
             -/---------------•-H-1---2---3---4---5---6---7---8---9---A---B---
             -/-------------------•-H-1---2---3---4---5---6---7---8---9---A---
             -/-----------------------•-H-1---2---3---4---5---6---7---8---9---
             -/---------------------------•-H-1---2---3---4---5---6---7---8---
             -/-------------------------------•-H-1---2---3---4---5---6---7---
             -/-----------------------------------•-H-1---2---3---4---5---6---
             -/---------------------------------------•-H-1---2---3---4---5---
             -/-------------------------------------------•-H-1---2---3---4---
             -/-----------------------------------------------•-H-1---2---3---
             -/---------------------------------------------------•-H-1---2---
             -/-------------------------------------------------------•-H-1---
             -/-----------------------------------------------------------•-H-`));

... but you still need to define what each character in that diagram means.

The method you should look at, if you want to figure out how computation is bootstrapped into something useful, is CircuitStats._fromCircuitAtTime_noFallback and the various methods it calls. At a low level the work basically comes down to "make a WglTextureTrader, keep giving it shaders, ask to keep intermediate results you care about, keep doing that until you're done, then read all the pixels".

Code:
static _fromCircuitAtTime_noFallback(circuitDefinition, time) {
    circuitDefinition = circuitDefinition.withMinimumWireCount();
    const numWires = circuitDefinition.numWires;

    // Advance state while collecting stats into textures.
    let stateTrader = new WglTextureTrader(CircuitShaders.classicalState(0).toVec2Texture(numWires));
    let controlTex = CircuitShaders.controlMask(Controls.NONE).toBoolTexture(numWires);
    let {colQubitDensities, colNorms, customStats, customStatsMap} = advanceStateWithCircuit(
        new CircuitEvalContext(
            time,
            0,
            numWires,
            Controls.NONE,
            controlTex,
            stateTrader,
            new Map()),
        circuitDefinition,
        true);
    controlTex.deallocByDepositingInPool("controlTex in _fromCircuitAtTime_noFallback");
    if (currentShaderCoder().vec2.needRearrangingToBeInVec4Format) {
        stateTrader.shadeHalveAndTrade(Shaders.packVec2IntoVec4);
    }

    // Read all texture data.
    let pixelData = Util.objectifyArrayFunc(KetTextureUtil.mergedReadFloats)({
        output: stateTrader.currentTexture,
        colQubitDensities,
        colNorms,
        customStats});

    // -- INTERPRET --
    let qubitDensities =
        CircuitStats._extractColumnQubitStatsFromPixelDatas(circuitDefinition, pixelData.colQubitDensities);
    let survivalRates =
        CircuitStats._extractColumnSurvivalRateStatsFromPixelDatas(pixelData.colNorms);
    let outputSuperposition = KetTextureUtil.pixelsToAmplitudes(
        pixelData.output,
        survivalRates.length === 0 ? 1 : survivalRates[survivalRates.length - 1]);

    let customStatsProcessed = new Map();
    for (let {col, row, out} of customStatsMap) {
        //noinspection JSUnusedAssignment
        let func = circuitDefinition.gateInSlot(col, row).customStatPostProcesser || (e => e);
        //noinspection JSUnusedAssignment
        customStatsProcessed.set(col+":"+row, func(pixelData.customStats[out], circuitDefinition, col, row));
    }

    return new CircuitStats(
        circuitDefinition,
        time,
        survivalRates,
        qubitDensities,
        outputSuperposition,
        customStatsProcessed);
}

As you can see, it's quite a lot of details to have to deal with.

If you want something scriptable, I recommend a library intended for that such as liquid or projectq.
 
  • #12
Thanks for the info.

Liquid -- I've seen their web page, I'll go back and see if it can be scripted in a browser (probably not).

projectQ -- New to me, must check it out.
 
  • #13
Strilanc said:
You can play with it at algorithmicassertions.com/quirk

I compare it to some other simulators in this blog post.
What a fantastic tool ! Thanks a lot for sharing it. I think there is a way I could get an answer for some of my question I posted on this thread using your tool. I found this in a blog link of yours that seems to answer my question about 4 entangled photons.

The problem I have is that on each "path" the final step is still expressed in QM terms, and there does not seems to have a "logic gate" that could compare correlation after measurement on two paths (or does "QFT" does that ?)

Please understand I am just a programmer with no formal physics education, just in case you feel like being too technical :nb)
 
  • #14
You can use controls to condition displays on other qubits. Like this.
 

Similar threads

  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 7 ·
Replies
7
Views
3K
  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 65 ·
3
Replies
65
Views
11K