A Qubit DSL?


I’ll take a crack at it :slight_smile: Any reference document or example you could link me too?


Not really, adding new syntax to the language isn’t really something that happens often enough for there to be a guide. But basically the thing to do is to think about which function calls you want it to end up as, and then make sure that you can get from the syntax form to the function call form by only looking at the syntax itself (e.g. you can’t look at types).


Ok sounds good, thanks.


I ended up writing something very brief: https://d38jwhuvz77yxg.cloudfront.net/dirac_spec.pdf, which could at least maybe be a starting point for any discussion. I realize the syntax is basically mathematical notation, and I don’t know much about the limitations in Julia with respect to this. I wouldn’t really call this a design or implementation spec, rather it’s more of just a ‘this would be desirable’ spec. At any rate, it would be good to hear from people regarding how possible/impossible this would be in Julia.


I have to wonder if it might not be sufficient to have Bra and Ket types and allow their composition in various ways. Writing Bra(ϕ) and Ket(ψ) and Bra(ϕ)*Ket(ψ) or BraKet(ϕ,ψ) doesn’t seem like the end of the world. The ⟨ϕ|ψ⟩ notation is cool but it doesn’t seem strictly necessary to have a quantum mechanics DSL. If one absolutely must have something like the traditional bra-ket notation, then I think you need dedicated versions of | for bra, ket and bra-ket combinations. Perhaps ⟪ϕ⟧ and ⟦ψ⟫ and ⟪ϕ,ψ⟫.


I do agree that it would be really nice to have |ψ⟩ et cetera lower to something, but I am certainly quite biased on that matter as my background is primarily in quantum field theory. I do think that having ⟨args...⟩ lower to, for example vev(args...) would also be useful in contexts other than quantum mechanics.

I do think that if this gets done the lowering rules should be pretty general. Bear in mind that in the general case the Hilbert space is not required to be finite dimensional or even separable, so I don’t think we should assume that kets can be represented as a Julia AbstractVector (which always have a finite, integer length).

My suggestion would be

  • |args...⟩ lower to ket(args...)
  • ⟨args...| lowers to bra(args...)
  • ⟨bra_args...|ket_args...⟩ lowers to braket(tuple(bra_args...), tuple(ket_args...))
  • ⟨bra_args...|O|ket_args...⟩ lowers to braket(tuple(bra_args...), O, tuple(ket_args...))
  • ⟨args...⟩ lowers to vev(args...)

and that, with the possible exception of vev, that none of these functions be defined in Base. That would allow package developers to assign them as needed and not have any constraints on what the underlying data structures are called. One objection I anticipate is that this might be considered encouraging type piracy, and I’m not sure I have a good defense for that.

Support additional brackets

Certainly not the end of the world :slight_smile:. I guess the idea here is sort of inline with the APL’ish–language as a tool of thought, in that the Dirac notation helps enable a certain way of thinking about things. Unlike APL though, the notation is widely used and already understood, people familiar with it would be able to use it straight away, and reading and understanding programs would be easier.

I guess the thing is this is an idea for a tool for doing algorithms research and exploring the idea of being able to write and execute equations. I realize it’s a big lift from the perspective of an already well-defined language, I was just interested in exploring what the possibilites might be.

These look pretty good! I also considered \phi\rangle alone without the |, and possibly something then like \langle\psi \ \ \mathbf{A} \ \ \phi\rangle . It’s really the angle brackets that are the most intuitive and informational, I think it’s probably ok to do away with | entirely.

My understanding is that to attempt to do something like this, I would need to wrap things in strings like r" "? Is it possible to have a preprocessor do this? Or is there a better way?


Note that QuDirac’s macros are just syntax sugar for this (http://qudiracjl.readthedocs.io/en/release-0.1/d_str/), except that state products lower to * rather than a new Dirac-notation-specific method.

One of the problems with building a Dirac notation system is that the mathematical notation is often used in a manner that doesn’t locally convey computationally relevant assumptions (e.g. orthogonality, notion of basis, separability, factor selection etc.). QuDirac attempted to address some of these problems by providing features like inner product types, act_on, etc.

I get emails periodically requesting an updated version of QuDirac. If I could start over on the package, though, I’d probably take a drastically different approach; keep the current QuDirac’s DSL-like features, throw away the eager computation parts, and use its label-based approach to make a nice DSL for constructing tensor computation graphs. Basically make a nice, quantum-specific front-end to existing backends like TensorFlow, TACO, etc. Might be a worthwhile project, but certainly not something I have time to undertake :stuck_out_tongue:


This is very interesting, what do you think are the main advantages of this approach versus the one currently implemented?


I fail to see what this notation brings in the context of a programming language, especially one with first class linear algebra support. The bra ket thing is a nice enough pun, but is writing x’Ay really that much more annoying? Really I find linear algebra notation better: for instance you can represent many wavefunctions as a rectangular matrix, write overlap matrices as X’X, etc.


QuDirac was developed more for doing symbolic calculations, and is not at all efficient for nontrivial numeric work. The way I/my advisor at the time used it was to set up problems, step through some algebraic calculations, etc., then convert to normal Julia arrays to do actual number crunching. This workflow was essentially just a poor, manual version of the now-popular DSL --> computation graph --> execution engine approach.


I don’t think anyone is claiming that this would be anything more than a fun feature. If it weren’t for bras and kets being difficult to parse because of the mismatched delimiter (especially one that is already used like |) I think it would be more “yes, of course let’s do that”.

Regardless of what you think about Dirac notation generally, one thing that I suspect everyone will probably agree should definitely be done is making ⟨x⟩ lower to vev(x) or expectation(x) or whatever. This is something that would be nice to have for everyone and since \langle, \rangle are currently unused it doesn’t cost anything.

Again, I’m also a little hesitant to make the identification of kets with AbstractVector. AbstractVectors live in Hilbert space, but not all Hilbert spaces can be described by AbstractVector. Even a simple harmonic oscillator has an infinite dimensional hilbert space! Therefore if we do introduce Dirac notation I do not think it should be bound to standard finite-dimensional linear algebra by default.

That said, I agree, being able to write Julia programs with standard linear algebra notation isn’t a bad state of affairs at all. At least we don’t have any ghastly np.dot or the silliness of matrix multiplication being a hadamard product by default.


It certainly isn’t! At the end of the day being able to experiment with algorithms efficiently is the absolute must-have

This is certainly a valid perspective, in the end it’s just a way of thinking about things. Here is one take on it though for anyone that may be curious http://algassert.com/post/1629. Another take on it is Marvin Chester’s Primer of Quantum Mechanics.


This makes sense, part of the goal definitely needs to be powerful numeric capabilities as you say. I’ll keep thinking about it, thanks for your comments!


Soon after julia 0.7 stabilizes / is released, i plan to release a julia package for working with tensors and tensor networks. I am also aware of other efforts currently being undertaking to bring more tensor network stuff to Julia.


If you would like to collaborate on either of those projects, I’d be very interested in doing so.

I have somewhat extensive field theory background and a little extraneous knowledge of things that are connected to tensor networks but I really want to get to know more about them.


Just a thought, but what about if we wrote bras and kets like[x]⟩ and ⟨[x]? This seems like a really nice compromise that would free us up to do all sorts of fancy metaprogramming for bra-ket notation.

My first thought was to do the nicer looking [x⟩ and ⟨x] but this would play havoc with the paren-matching features in people’s text editors… I suppose Juno could be taught to play nicely with it though.

A possibly even better alternative! \rfloor and \lfloor give us and respectively. Hence, we can write
which is pretty attractive as it doesn’t use up any in use characters. The only problem is that one has to type latex extensions for the two delimiters of the bra or ket or four delimiters for a braket ie. \langle \rfloor \lfloor \rangle. However, one could easily make a Juno extension such that if one types \ket or something then it autocompletes to ⌊⟩ with the cursor already in the middle of the ket.


This seems to be as close to the actual notation as possible without problematic characters. Are there disadvantages to this as opposed to [x]\rangle in terms of metaprogramming?


I’ve actually already started messing around with some lattice gauge theory, though it’s been a while since I’ve worked on it. Since it was mainly for fun my plan was to do pure gauge (and maybe scalars later), as that case is really quite simple, fermions are what make it so damn complicated!

A couple of observations I had from my early efforts:

  • I really wanted to do it in arbitrary dimensions, partially because I figured I’d save on computing power in some of my experiments by doing only 3 dimensions. It also would have been interesting from a physics standpoint: I’m pretty hazy on what pure SU(N) looks like in 3 dimensions. There is no conformal anomaly as the theory isn’t even classically conformal, but to lowest order there is still a negative \beta function, so it should still confine. I actually surveyed the literature a little to see what work has been done but didn’t find too much (although I’m pretty sure it’s a well-understood topic). It’s really fascinating that the mass gap is controlled by \alpha in the 3-dimensional theory, but by \Lambda_{QCD} in the 4-dimensional theory! (Which leads me to believe that maybe the 3-d theory doesn’t actually look the way I think it does). Anyway, from a programming standpoint, doing arbitrary dimensions with decent performance is quite a pain. I started out using StaticVectors which seemed like a viable approach.
  • When starting on the metropolis algorithm, I quickly encountered an interesting and difficult programming problem that I don’t think is normally considered when doing lattice gauge theory in lower level languages: Given some functional S[\phi_{i}(x)] in the general case what is the most efficient way of computing S[\phi_{i}(x)'] where the \phi s only differ at a single lattice site? I’m pretty sure that the usual approach to this is to compute the change analytically and manually programming it in. This being Julia, however, I really wanted to find a general way of doing it so that users could enter their own action (after all, I was going to have to play with the action quite a bit myself if I started off with the lowest order Wilson action and then went to higher orders). The approach I decided on was to think of every functional as a mapreduce. As long as the reducer is invertable there is a straightforward way of minimally computing the changes. This seems like a sound method but lattice gauge theory really does seem like a worst case scenario for this (Wilson loops that share edges generate lots of terms). This is about where I left off.

Anyway, as far as getting involved in collaborative efforts go, I think I’d be more interested in contributing to tensor network stuff. I’ve read at least the beginnings of a few reviews, but I’m still not too sure what the actual numerical problems that tensor networks are useful for look like! If you have some specific problems in mind I’d be very interested to hear about them (although of course we should try to make any tensor network package as general as possible)!

Tensor networks have also gotten me to be even more curmudgeon-y about the abuse of the term “tensor” in the popular culture now. I kind of want to go to Google and demand that they change the name of TensorFlow to ArrayFlow or BackpropFlow or something more reasonable :laughing:.


Look at