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

1. May 23, 2016

### Strilanc

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

### 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?

3. May 23, 2016

### rootone

10/10 for beautiful GUI.
I'm not sure what I am looking at though.

4. May 23, 2016

### Strilanc

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.

5. May 23, 2016

### rootone

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.

6. May 23, 2016

### Staff: Mentor

7. May 24, 2016

### Strilanc

8. Apr 20, 2017

### Swamp Thing

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?

9. Apr 20, 2017

### Strilanc

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. Apr 20, 2017

### Swamp Thing

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. Apr 20, 2017

### Strilanc

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 {colQubitDensities, colNorms, customStats, customStatsMap} = advanceStateWithCircuit(
new CircuitEvalContext(
time,
0,
numWires,
Controls.NONE,
controlTex,
new Map()),
circuitDefinition,
true);
controlTex.deallocByDepositingInPool("controlTex in _fromCircuitAtTime_noFallback");
}

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. Apr 20, 2017

### Swamp Thing

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. Apr 21, 2017

### Boing3000

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

14. Apr 21, 2017

### Strilanc

You can use controls to condition displays on other qubits. Like this.