Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

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

  1. May 23, 2016 #1

    Strilanc

    User Avatar
    Science Advisor

    (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: Apr 20, 2017
  2. jcsd
  3. May 23, 2016 #2

    jedishrfu

    Staff: Mentor

    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?
     
  4. May 23, 2016 #3
    10/10 for beautiful GUI.
    I'm not sure what I am looking at though.
     
  5. May 23, 2016 #4

    Strilanc

    User Avatar
    Science Advisor

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

    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.

    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.
     
  6. May 23, 2016 #5
    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.
     
  7. May 23, 2016 #6

    jedishrfu

    Staff: Mentor

  8. May 24, 2016 #7

    Strilanc

    User Avatar
    Science Advisor

  9. Apr 20, 2017 #8
    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?
     
  10. Apr 20, 2017 #9

    Strilanc

    User Avatar
    Science Advisor

    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.
     
  11. Apr 20, 2017 #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?
     
  12. Apr 20, 2017 #11

    Strilanc

    User Avatar
    Science Advisor

    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 (Text):

    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 (Text):

    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.
     
  13. Apr 20, 2017 #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.
     
  14. Apr 21, 2017 #13

    Boing3000

    User Avatar
    Gold Member

    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)
     
  15. Apr 21, 2017 #14

    Strilanc

    User Avatar
    Science Advisor

    You can use controls to condition displays on other qubits. Like this.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Quirk: A drag-and-drop in-browser quantum circuit simulator
Loading...