In my job I’m almost entirely surrounded by men.
I work as a Machine Learning Engineer at Silverpond. It’s definitely the best place I’ve ever worked, but there’s one area that we’re actively trying to improve: recruiting women into roles as software engineers and machine learning engineers.
In this post I’ll cover some ideas I’ve had along these lines.
When I’ve been involved in recruiting people, in recent history, it’s tended to be almost entirely by word of mouth. My process is:
This actually works very well, but only because I tend to go to a lot of events, and I meet a lot of people. The one key problem with this approach is: I mostly end up recommending men.
I think that the reason for this can be somewhat explain by various cognitive biases (notably, “Ingroup bias”), and so I’ve been thinking about how to address it.
I was pointed at the few articles along these lines, and I’ll summarise them here:
Avoiding the ‘merit trap’  Chief Executive Women and Male Champions of Change
Beginning with Ourselves  Airbnb
How blind auditions help orchestras to eliminate gender bias  The Guardian, and How Companies Are Taking Unconscious Bias Out of the Hiring Equation  LinkedIn Talent Blog
Our experiences in elevating the representation of women in leadership  Male Champions of Change
Concretely, what I’m going to do in this regard — getting more diverse applicants into the top of our “hiring funnel” — is:
and during the interview process, I think the following ideas are useful to keep in mind:
This is kind of a Part1 of my thoughts on this topic. I’ve had this post sitting in drafts for a while, so I thought I’d publish it. I expressed some related ideas in our blog. Let’s see how it progresses over the next few months.
]]>This post is the second of a threepart series on the paper An adaptive attack on Wiesner’s quantum money. The other parts are:
Now that we’re familiar with the Wiesner’s original scheme for quantum money, we can take a look at the “bomb testing” attack presented in the paper. The paper actually introduce two attacks, one more general than the other, but I’ll focus on the less general one; the bomb testing attack, because it’s more fun.
But before we see how it’s applied, let’s take a look at the bomb testing idea, because it’s very cool.
The task is: Can you determine a test that separates the live bombs from the dud ones?
Classically, one approach would be to simply attempt to detonate each bomb. If the bomb goes off, then it was a live bomb, and if it doesn’t, it wasn’t! Simple enough, but it leaves us with no good bombs to actually use.
Quantumly, it turns out there is something we can do that actually lets us know if the bomb is live or not, and keeps the bomb undetonated!
In this model, we suppose that our bombs are configured like so:
Live bomb: Has a singlephoton detector. If a photon hits, it, it explodes.  Dud bomb: Does not have a photon detector. The photon will pass unchanged through this bomb, and the bomb itself does not explode. 
We then recall the operation of a MachZender Interferometer.
Due to the release of (yet another) Python framework for quantum simulation ProjectQ, I was inspired to revisit the paper An adaptive attack on Wiesner’s quantum money from a few years back.
This post will form the first post of a threepart series on the paper, and the background necessary to understand the part of it I’ll cover. We’ll learn about:
Wiesner’s Quantum Money scheme is one of the earliest ideas in quantum computing. The fundamental idea is that (unknown) quantum states cannot be copied arbitrarily and hence make an “unforgable” form of money: it shouldn’t be possible to duplicate a “quantum” bill.
Money, in Wiesner’s scheme, is created by the bank. The bank holds a serial number and a secret “key” that the bank uses to verify each note that it hands out. When given a note, the bank can determine if it is valid by referring back to this secret key.
The important steps are:
Money generation: Done by the bank here; the bank creates money by randomly picking a quantum state, called it \(\$\rangle\), and handing that state to the customer, and recording the state it generated by matching it to the serial number of the note.
Money verification: When someone wishes to spend money, the bank verifies it.
Let’s take a look in detail. We’ll first need to recall some standard quantum states:
\[ \begin{aligned} 0\rangle &= \left( \begin{array}{c} 1 \\ 0 \end{array} \right), \\ 1\rangle &= \left( \begin{array}{c} 0 \\ 1 \end{array} \right), \\ +\rangle &= \frac{1}{\sqrt{2}} \left( 0\rangle + 1\rangle \right), \\ \rangle &= \frac{1}{\sqrt{2}} \left( 0\rangle  1\rangle \right). \end{aligned} \]
The first two states, \(\{0\rangle, 1\rangle\}\) form a basis^{1} – the computational basis – for a single qubit, and the second two, \(\{+\rangle, \rangle\}\) form a different, orthogonal, basis – the Hadamard basis.
The crucial idea to understanding the scheme is that in quantum mechanics, measurement can irreversibly destroy a given quantum state, changing it to be a completely different one.
To measure a given state in quantum mechanics is to first fix a set of potential measurement outcomes, and then “look” at the given state, and see which one of these outcomes the state when in. Let’s see an example.
Suppose we have a single qubit in some unknown state:
\[ \begin{aligned} \psi\rangle &= \alpha 0\rangle + \beta 1\rangle \end{aligned} \]
We can measure the qubit in either the computational basis or the Hadamard basis.
Computational basis. Noting that it is already express in terms of the computationl basis, if we measure it in the computational basis, the Born rule for measurement says that we will get the state \(0\rangle\) with probabily \(\alpha^2\) and the state \(1\rangle\) with probabily \(\beta^2\).
Hadamard basis: Note that \(0\rangle = \frac{1}{\sqrt{2}} \left( +\rangle + \rangle \right)\) and \(1\rangle = \frac{1}{\sqrt{2}} \left(+\rangle  \rangle \right)\) so we can rewrite \(\psi\rangle\) as \[ \begin{aligned} \psi\rangle &= \frac{\alpha + \beta}{\sqrt{2}} +\rangle + \frac{\alpha  \beta}{\sqrt{2}} \rangle \end{aligned} \] and so, again by the Born rule, we would achieve outcome \(+\rangle\) with probability \(\left\frac{\alpha + \beta}{\sqrt{2}}\right^2\) and \(\rangle\) with probability \(\left\frac{\alpha  \beta}{\sqrt{2}}\right^2\).
The point to note here is that the final state is different depending on which basis we measured it in. Wiesner used this fact to build a (hopefully) unforgable form of money.
Money generation: To withdraw money from a bank in Wiesner’s scheme, the bank performs the following steps:
Money verification: To verify a given piece of money, the bank proceeds as follows:
Having the same money state returned, instead of a new one each time validation succeeds, is critical to the success of the forging approach of arXiv:1404.1507.
Let’s look at an example. Suppose we have withdrawn some money from the bank, and the state we’ve been given (but can’t see) is
\[ \begin{aligned} \$\rangle &= +100\rangle. \end{aligned} \]
There are six qubits, and we can see the bases that each has been prepared in, but if we’re simply the customer we don’t know this information.
Our goal is to create a state \(F\rangle\) that the bank will also verify as valid.
Noting that if we measure either \(+\rangle\) or \(\rangle\) in the computational basis, we’ll get \(0\rangle\) with 50% probability or \(1\rangle\) with 50% probability, one approach is simply to build \(F\rangle\) by the following technique:
In our example, we can see that this will work 50% of the time for the first qubit of \(\$\rangle\), 100% of the time for the 2nd, 3rd and 4th qubits, and again 50% of the time for the last two qubits. So for this state, this approach will succeed with probability \(\left( \frac{1}{2} \right)^3 = \frac{1}{8}\). Pretty bad odds.
In an earlier paper, Molina Vidick and Watrous show that in a model where the attacker doesn’t interact with the bank after receiving the note, the best attack that one can mount results in a success probability of \(\left(\frac{3}{4}\right)^n\), where \(n\) is the number of qubits in the money state. This is better than my approach here, but if we set \(n\) to be of modest size, say \(n = 10\), then this approach will succeed at most 5 times out of 100; still not particularly good. If we had 100 twenty dollar notes, we could attempt to forge them, and we’d end up with a total of \(2 \times 5 \times 20 = \$200\) instead of the original \(\$2,000\) we started with.
We’ve seen that Wiesner’s original scheme for quantum money doesn’t appear to be forgable with our first ideas. In the next post we’ll learn about a very cool technique in quantum mechanics, the ElitzurVaidman bomb tester, and then we’ll see how it can be used to beat Wiesner’s scheme!
A onequbit basis is a set of states such that any state involving one qubit can be written as a linear combination of either of the elements in the basis.↩
(This post requires a background in the basics of quantum computing (and neural networks). Please have a read of the first part of Introduction to quantum computing and the surface code if you’d like to get up to speed on the quantum parts, Neural networks and Deep Learning is a good introduction to the other part.)
Recently, I’ve been spending a lot of time thinking about machine learning, and in particular deep learning. But before that, I was mostly concerning myself with quantum computing, and specifically the algorithmic/theory side of quantum computing.
In the last few days there’s been a flurry of papers on quantum machine learning/quantum neural networks, and related topics. Infact, there’s been a fair bit of research in the last few years (see the Appendix at the end for a few links), and I thought I’d take this opportunity to have a look at what people are up to.
The papers we’ll be discussing are:
But first, let’s take a look at the paper that got me interested in machine learning in the first place!
The paper, Quantum algorithms for supervised and unsupervised machine learning by Lloyd, Mohseni and Rebentrost in 2013, was one of my first technical exposures to machine learning. It’s an interesting one because it demonstrates that for certain types of clustering algorithms there is a quantum algorithm that exhibits an exponential speedup over the classical counterpart.
Aside: Gaining complexitytheoretic speedups is the central task of (quantum) complexity theory. The speedup in this paper is interested, but it “only” demonstrates a speedup on a problem that is already known to be efficient^{1} for classical computers, so it doesn’t provide evidence that quantum computers are fundamentally more powerful than classical ones, by the standard notions in computer science.
The Supervised clustering
problem that is tackled in the paper is as follows:
Given some vector \(\vec{u} \in \mathbb{R}^N\), and two sets of vectors \(V\) and \(W\), then given \(M\) representative samples from \(V\): \(\vec{v}_j \in V\) and \(\vec{w}_k \in W\), figure out which set \(\vec{u}\) should go in to, by comparing the distances to these vectors.
In pictures it looks like so:
Classically, if we think about where we’d like to put \(\vec{u}\), we could compare the distance to all the points \(\vec{v_1}, \vec{v_2}, \vec{v_3}\) and to all the points \(\vec{w_1}, \vec{w_2},\vec{w_3}\). In the specific example I’ve drawn, doing so will show that, out of the two sets, \(\vec{u}\) belongs in \(V\).
In general, we can see that, using this approach, we would need to look at all \(M\) data points, and we’d need to compare each dimension of the \(N\) dimensions of each vector \(\vec{v_j}, \vec{w_k}, \vec{u}\); i.e. we’d need to look at at least \(M\times N\) pieces of information. In other words, we’d compute the distance
\begin{align*} d(\vec{u}, V) = \left \vec{u}  \frac{1}{M}\sum_{j=1}^{M} \vec{v_j} \right \end{align*}By looking at the problem slightly more formally, we find that classically the best known algorithm takes “something like”^{2} \(\texttt{pol}y(M\times N)\) steps, where “\(\texttt{poly}\)” means that the true running time is a polynomial of \(M\times N\).
Quantumly, the paper demonstrates an algorithm that lets us solve this problem in “something like” \(\log(M\times N)\) time steps. This is a significant improvement, in a practical sense. To get an idea, if we took \(100\) samples from a \(N = 350\)dimensional space, then \(M\times N = 35,000\) and \(\log(M \times N) \approx 10\).
The quantum algorithm works by constructing a state in a certain state so that, when measured, the distance that we wanted, \(d(\vec{u}, V)\), is the probability that we achieve a certain measurement outcome. In this way, we can build this certain state, and measure it, several times, and use this information to approximate the required distances. And, the paper shows that this whole process can be done in “something like” a running time of \(\log(M\times N)\).
There’s more contirbutions in the paper than just this; so it’s worth a look if you’re interested.
So this paper is pretty cool. We can get a feel for what it’s doing by first considering the following network:
This network has two inputs, \(x_1, x_2\), three learnable weights, \(w_1, w_2, w_3\), one output value \(y\), and an activation function \(f\).
Classically one would feed in a series of training examples \((x_1, x_2, y)\) and update the weights according to some loss function to achieve the best result for the given data.
Quantumly, there are some immediate problems with doing this, if we switch the inputs \(x\) to be quantum states, instead of classical real variables.
The problems are:
The way this paper solves these problems is to transition Figure 2 from a classical nonreversible network to a reversible quantum one:
The final network takes in an arbitrary quantum state of two qubits, \(x_1, x_2\), and then adjoins an ancilla state \(0\rangle\), applies some unitary operation \(U\), and emits a combined final state \(\psi\rangle^{\text{Out}}_{x_1,x_2,y}\) where the final qubit \(y\) contains the result we’re interested in.
At this point, one might reasonably ask: How is this different to a quantum circuit? It appears to me that the only difference is that \(U\) is actually unknown, and it is trainable! Note that this is also a somewhat radical difference from classical neural networks: there, we don’t normally think of the activation functions (defined as \(f\) above) as trainable parameters; but quantumly, in this paper, that’s exactly how we think of them!
It turns out that unitary matrices can be parameterised by a collection of real variables \(\alpha\). Consider an arbitrary unitary matrix operating on two qubits, then \(U\) can be written as:
\begin{align*} U = \exp\left[ i \left( \sum_{j_1,j_2=0,0}^{3,3} \alpha_{j_1, j_2} \times \left(\sigma_{j_1} \otimes \sigma_{j_2}\right) \right) \right] \end{align*}where \(\sigma_i, i \in {1,2,3}\) are the usual Pauli matrices and \(\sigma_0\) is the \(2\times 2\) identity matrix. So one can then make these parameters \(\alpha_{j_1, j_2}\) the trainable parameters! It turns out that in the paper they don’t train these parameters explicitly, instead they pick a less general way of writing down unitary matricies, and they construct, by hand, a unitary for two qubits. It’s not clear why they’ve done this, and it would not be fun to have to build a special trainable unitary matrix for each node/neuron of your architecture depending on its input.
Update: KwokHo kindly corrected me that they do indeed train directly on this form of unitary matricies, and that the simplification they do in the paper is used to investigate the loss surface.
In any case, the main contribution of this paper seems to me to be the idea that we can learn unitary matricies for our particular problem. They go on to demonstrate that this idea works to build a quantum autoencoder, and to make a neural network discover unitary matricies that perform the quantum teleportation protocol.
One view is that trying to learn arbitrary unitary matrices that perform a task really well will become too hard as the number neurons grows. If we had a large network, with potentially millions of internal, neurons (and hence unitaries) to learn, then it might be more effective to fix unitaries and instead focus on learning the weights.
However, it’s a promising technique that would be fun to try out.
Those of you familiar with neural networks will know that the central idea used to train them is Gradient Descent. We recall that gradient descent lets us known how to modify some vector \(x\) so that it does “better” when evaluated with some cost function \(C(x, y)\) where \(y\) is some known good answer. I.e. \(x\) might be a probability of liking some object, and \(y\) might be the true probability, and \(C(x,y) = xy^2\).
The paper supposes we have some quantum state \(x\rangle = \sum_{j=1}^N x_j j\rangle\) (where \(j\rangle\) is the \(j\)’th computationalbasis state), and some cost function \(C(x\rangle, y\rangle)\) that tells us how good \(x\rangle\) is. The question is, given we can evaluate \(C(x\rangle, y\rangle)\), how can we best work out to modify \(x\rangle\) to do better?
If this was entirely classical, we could just calculate the gradient of \(C\) with respect to the variables \(x_j\), and then propose a new set of \(x_j\)’s. However, we can’t inspect all these values quantumly, so we need to do something else.
In the paper, they demonstrate an approach that requires a few copies of the current state \(x^{(t)}\rangle\), but will produce a new state \(x^{(t+1)}\rangle\) such that (with objective/loss function \(f\)):
\begin{align*} x^{(t+1)}\rangle = x^{(t)}\rangle  \eta \nabla f\left(x^{(t)}\right)\rangle \end{align*}for some step size \(\eta\). That is, it’s a step in the (hopefully) right direction, as per normal gradient descent!
So one direction to take this paper would be to build a “fully quantum” neural network like so:
where we make the weights quantum states, and the weights are multiplied onto the inputs as a dotproduct. This would require that the weight state is the same size as the input state; but that should be possible because we’re the ones building the network structure.
Update: The idea about multiplying weights in didn’t make any sense; a much more sensible idea would be to prepare something like \(w_i\rangle\langle w_i\) and enact this on the input \(x_k\) and then apply the fixed unitary.
We could then not worry about learning unitary matrices, and analogously to standard neural networks, just pick some unitary \(U\) that “works well” in practice, maybe by just defining quantum analogues of some common activation functions, perhaps say the ReLU or ELU.
Overall I think that the quantum gradient descent algorithm should be useful for training neural networks, and maybe some cool things will come from it. There are some natural direct extensions of this work; namely to extend the implementation to the more practical variations.
This paper came out only a few days after the Wan et al paper that we covered above, that also discussed autoencoders, so I thought it was worth a glance to see if this team did things differently.
This paper again takes the approach of not concerning itself with weights and instead focuses on learning a good unitary matrix \(U\) with a specific cost function.
They take a different approach in how they build their unitaries. Here they have a “programmable” quantum circuit, where they consider the parameters defining this circuit as the ones that can be trained. Given that these parameters are classical, and loss function they calculate is classical, no special optimisation techniques are needed.
It appears that the building blocks are being put together to start doing some serious work on quantum machine learning/quantum deep networks. Google and Microsoft are already heavily investing in quantum computers, Google in particular has something it calls the “Quantum A.I. Lab”, and there are even independent quantum computer manufacturing groups.
It seems like there are lots of options on which way to direct efforts in the quantum ML world, and with these recent developments on quantum ML techniques, the time appears to be right to be getting into quantum deep learning!
More interesting quantum machine learning papers:
Here efficient means that the problem is in the complexity class caled \(\textbf{P}\). Problems that are efficient for quantum computers are in the complexity class \(\textbf{BQP}\). One of the main outstanding questions in the field is “Are quantum computers more powerful than classical ones?” and this can be phrased as comparing the class \(\textbf{P}\) and \(\textbf{BQP}\).↩
“Something like” x here is a very informal term for the more formal statement that the running time is \(O(x)\). See Big O Notation for more.↩
For the past few months at work we’ve been putting up a Chalkboard in front of the office with jokes on it.
Today marks the 50th joke, so to celebrate I’m writing up the complete list. Most of the jokes here were ones we made up without looking at the internet; but occasionally, in an effort to have two new jokes every day, we picked some classics.
Q: What kind of parade did the astronauts throw for the computers after the mission?
A: A Turing tape parade!
Q: Why was the maths book sad?
A: It had too many problems.
Q: What did the AI say to the category theorist?
A: Does not commute!
(from Andy Kitchen)
Q: How did the OR programmer solve a MIP while also eating?
A: By using a brunch and bound technique.
[“hip”, “hip”]
Q: What do measure theorists and programmers have in common?
A: They both enjoy continuous integration.
Old mathematicians never die, they just lose some of their functions.
Q: Why did the computer keep sneezing?
A: It had a virus.
Q: Why wasn’t the complex beer successful?
A: People had trouble ordering it!
Q: Why did the functional programmer return her TV?
A: Because it was immutable.
Q: What do ruby and librarians have in common?
A: They both have explicit return policies.
A shepherd was out in the field counting her sheep; she counted 96 but when she rounded them up she had 100.
(from Two Lost Boys)
Q: Why was the computer owner so successful at sheep husbandry?
A: She had excellent RAM.
Q: Why couldn’t the formal system complete it’s homework?
A: It was trying to be consistent.
404: Joke Not Found.
Q: How does a lumberjack mathematician cut down trees?
A: With her Axiom.
Q: Why did the programmer go to her bookshelf before leaving her house?
A: She needed to get her keys from the dictionary.
Q: Why don’t you want to fight an OR consultant?
A: They are experts at duals.
Q: What did the Linux system administer for the programmer’s head cold?
A: Sudo ephedrine
Q: How did the physicist fix her car when it was failing intermittently?
A: She used statistical mechanics!
Q: Why was the bad python programmer so rich?
A: Because everytime his code failed he got a raise.
Q: What do python programmers and event planners have in common?
A: They both like to decorate functions.
Q: Why is 0 the boss?
A: Because no other number can go above it!
Q: What did the mathematician say when they discovered a new prime number?
A: That’s odd.
Q: Why did the lowrank matrix go to the psychologist?
A: Because it was having an identity crisis!
Q: What is a floating point numbers favourite type of tennis?
A: Doubles!
Q: What does a blender and the Kalman filter hav in common?
A: They both perform a smoothing function!
Q: What is the mathematicians favourite kitchen item?
A: Derivasieve.
Q: Why don’t elephants use computers?
A: Scared of the mouse.
Q: Why was the OR consultant unwell?
A: She want on a benders.
Q: What is a statisticians favourite genre of music?
A: Drum and Bayes.
Q: What is a pet store operatores favourite state in a multiplayer game?
A: The Parrot optimal state.
Q: What is the enterprise java programmers favourite business book?
A: Scalaing up!
Q: What function is a tree hugger most concerned by?
A: \(\log(n)\).
Q: What is a garbologists favourite optimisation problem?
A: Bin packing.
Q: What is a choirs favourite design pattern?
A: The Singleton pattern!
Q: What do you call a mathematician that has lots of statues in her garden?
A: Polygnomial.
Q: What do fashion designers and Haskell programmers have in common?
A: They love pattern matching!
Q: How did the mathematician impress at the dance party?
A: By showing off her step function!
No joke provided; the CurryHoward isomorphism allows us to generate a programming joke from the maths joke.
Q: Why was the mathematician unhappy when she turned 24?
A: She now had a lot of factors to consider.
Q: Why was the programmer so poor?
A: Syntax.
Q: Why was the ML programmer late to the conference?
A: She spent too much time in the “train” stage.
Q: What number is good value?
A: 241
Exercise: What number is best value?
Q: Why couldn’t the python programmer get into her house?
A: Key error.
Q: How did the programmer get out of the deep end of the pool?
A: She made a pull request!
Q: Why was the ML researcher tired of shopping?
A: She was overfitting.
Q: How did the programmer get to the bottom of the ocean?
A: By subroutine!
]]>Q: How do you order citrus?
A: Use the real number lime.
In this post we’ll see how to setup a CI build that generates Windows executables for stackbased Haskell projects.
So imagine you love Haskell and you have written a Haskell program, you’ve hosted it on GitHub and you’ve dilligently set up a CI build on Travis that uses stack to build/test/etc.
Now, because stack is great and life is good, people can build your project from the source largely without issue. But suppose now that you’d like to provide Windows binaries for download. It so happens that we live in an age where this is completely automatable! Let’s see how.
The essence of my approach is to use the CI system AppVeyor (essentially like a Travis for Windows), and the following appveyor.yml
file (full file below, I’ll go through details next):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 

Details:
ssh
based git submodules to https
based ones, that can be cloned without needing to mess about with ssh keys.haskmas.exe
file that we will mark as an artifactHASKMAS_VERSION
to the value of the output of the command stack exec  haskmas v
. This is my “hack” to obtain the cabalversion of the haskmas
library, which I use as part of the tag that gets released on the GitHub releases pagehaskmas.exe
as an artifact; this means AppVeyor will hang on to it after the build completes.haskmas<cabal_version_of_haskmas>
to the GitHub releases page! (Note: probably we would want to be a bit more elaborate about when we push to the releases page; making sure that we include proper release notes, etc.)You can see from the releases on the haskmas
project istelf that I fumbled around with this setup a bit. Mostly I observed that the manual release process on AppVeyor doesn’t quite operate the way I’d’ve hoped; but in any case AppVeyor is a pretty convenient service; it’s very nice to see something for Windows in this space.
I based my configuration off of the one for the stack tool itself. Note that there is some mention of caching in there that might speed up the build (my build takes ~17 minutes on AppVeyor compared to ~2 minutes on travis).
Allinall, technical details about automatically pushing releases aside, AppVeyor+stack is a really nice way to build Windows binaries from exactly the same source as your linux binaries. The only outstanding item to do is to combine artifacts from travis and AppVeyor into a single entity that can be released dually; but on the other hand tooling could always be written to perform this semimanually, from your working computer, when you are ready to release.
The repo is here: haskmas. As a side benefit, I made the haskmas program take command line arguments to control how it operates! So now you don’t need to compile it to get a tree of arbitrary depth!
]]>At the last Melbourne Haskell Meetup we got into the spirit by making Christmas trees in Haskell.
However, I recently have access to a 3D printer, and I’ve long wanted an excuse to try and use ImplicitCAD, so I set about trying to make a 3D version of Lyndon’s logo.
So of course, I love stack I created a new simple
project with stack new
and got started.
It turns out that ImplicitCAD
has a pretty nice and reasonably intuitive interface (similar to the code that one would write into OpenSCAD).
I built the 3D version of the logo by moving around rectangles, and by extruding a handdrawn shape.
The cool thing about generating this image in fullyfeature programming language is that I can build a tree of any size I like!
Here’s the (pretty verbose) code that gets me a tree of arbitrary depth:
ntree :: Integer > SymbolicObj3
ntree n = finalObj
where
dec = 0.8
ratios = 0 : [dec^j  j < [0..(n2)]]
 build up logo structure
((lx, ly, lz), objs) = foldl f ((0, 0, 0), []) (zip [0..(n1)] ratios)
 position of logos
(x,y,z) = (40, 4, 0)
f :: ((ℝ, ℝ, ℝ), [SymbolicObj3]) > (Integer, Float) > ((ℝ, ℝ, ℝ), [SymbolicObj3])
f ((x', y', z'), xs) (j, r) =
let newPos = (x' + r*x, y' + r*y, z' + r*z)
s = dec ^ j
loc = if (even j) then R else L
obj3 = translate newPos $ scale (s, s, s) (logoBauble loc)
in (newPos, obj3 : xs)
 star
(a,b,c) = (40.5, 24.5, 0)
starScale = dec ** (fromIntegral (n3))
posScale = dec ** (fromIntegral n)
starObj = translate (lx + (posScale * a), ly + (posScale * b), lz + (posScale * c))
$ scale (starScale, starScale, starScale) star
finalObj = union (starObj : objs)
Running this with \(n = 5\) gives result in the following render in OpenSCAD:
So there you have it! You can view the source code here: github.com/silky/haskmas or download a readytoprint STL from Thingiverse.
Have a happy Haskmas! :)
]]>Today I’m announcing a (very) alpha version of my webbased reference management system, superreference!
Superreference is a system which:
Here’s a screenshot of the main (only) page:
Superreference is built around my workflow for getting the latest papers.
A highlevel overview of my workflow is:
bibtex
data for the file somehowAll the while I’d like to maintain a list of “papers I’m currently reading” and have them available on my tablet.
Items 13 take place outside of superreference. My workflow for finding new papers and saving them on my computer is a little specialised, but happily you don’t need to follow this protocol if you want to get utility out of superreference — you simply need a bibtex
file to point it at.
Here’s my new paper obtaining workflow (yours may be different):
Let’s suppose now you have a One True bibtex file called all.bib
.
Grab yourself down a copy of the repository by following the instructions to configure it to point to this bibtex file.
Once you have the environment set up you can run a dev server with yesod devel
. You will then be able to visit the website! Supposing you pointed the config file at your all.bib
file, you will then be looking at all your interesting papers! If there’s a link associated with the entry, a link will be displayed, and if there is a PDF file, clicking on the entry name will open the PDF (with it’s location given by the file
entry in the relevant bibtex entry).
You can click the star
link to move the PDF up into the “currently reading” section. (Note: At the moment there is no visual indication of this, but it will be shown next time the page loads.)
Currently there is a lot of outstanding work to do on superreference; but it’s in a working state for me, so I thought I should release it.
If you have any feature requests/improvements/etc feel free to log an issue (or a pull request) over at the repository: superreference.
]]>Oftentimes one needs to write a document with math symbols in it. The standard tool of choice is some variant of TeX, either writing it online in one of the growinglist of collaborative editors:
But one program, that runs locally, that I can’t stop using is LyX.
I really like LyX because of the “Whatyouseeis(pretty much)whatyouget” nature of it.
One thing I wanted to share was a small technique that I used to get a version number in all of the pdfs that I generated from my LyX documents. The idea was that when I sent my document to obtain feedback from various interested parties, I could easily see which version they had commented on.
What I wanted as a footer that would be included on every page, that contained the version number.
The approach is:
\usepackage{fancyhdr}
\pagestyle{fancy}
\cfoot{\tiny{VERSION}}
\rfoot{\thepage}
\rhead{}
Makefile
. My Makefile
looks like so:BUILD_NUMBER_FILE := buildnumber.txt
BUILD_NUMBER := $(shell cat $(BUILD_NUMBER_FILE))
BUILD_DATE := $(shell date +%d%b%Y)
VER_STRING := $(BUILD_DATE)build$(BUILD_NUMBER)
LYXFILE := coolness
TEMPDIR := /tmp
all: pdf
# Switch in the new version number, compile with LyX and
# bring it here.
pdf: buildnumber
sed "s/VERSION/$(VER_STRING)/g" $(LYXFILE).lyx >$(TEMPDIR)/$(LYXFILE).lyx
lyx e pdf2 $(TEMPDIR)/$(LYXFILE).lyx
cp $(TEMPDIR)/$(LYXFILE).pdf .
# Build number file. Increment each build.
buildnumber:
@if ! test f $(BUILD_NUMBER_FILE); then echo 0 > $(BUILD_NUMBER_FILE); fi
@echo $$(($$(cat $(BUILD_NUMBER_FILE)) + 1)) > $(BUILD_NUMBER_FILE)
make
command and profit!Note that there is a buildnumber.txt
file that is incremented on each build, so you don’t need to do that manually.
I’ve put together a sample project here, so you can clone that gist and type make
and see it in action!
Behold, a colourful GHCi (install it for yourself):
This is done by using a simple little sed
wrapper around the ordinary ghci interactive
, see here for the script.
Note in particular the quirk that we must capture any SIGINT
that gets sent through and discard it, when we are invoking sed
, otherwise sed
itself will quit and our GHCi session will break.
You can use it cabal repl
(being mindful of this bug) by using cabal repl withghc=ghcicolor
. I’ve bound an alias repl
to this.
(Note: original credit for this goes to rhysd)
]]>