# kasdfl;akf
Written on a totally not sleep deprived brain. Also whenever something is written like `this` it's code and/or an object in Julia. For instance, when I write `Edge` I mean the Edge data structure from the Graphs package which has a source and a destination which can be written as `Edge(2, 3)`
```julia
struct Edge
src
dst
end
```
[A summary of what was going through my brain at time of writing can be found here](https://www.youtube.com/watch?v=zKJ6xGVzrnI)
## Stuff the computer needs to know to make a lattice
- Okay so to represent the lattice the computer needs to know the connectivity of the lattice for which we use a graph.
- The graph in the computer is represented as a list of vertices labelled by integers from 1 to $n$. The edges are represented by a list of `Edge` objects where the label of the source vertex is always smaller than the destination vertex. For instance, for an edge between vertex 2 and 3, it will always be `Edge(2, 3)`.
- That defines the graph, now to put spins on every vertex we use the MetaGraph data structure. Essentially, you have a data structure which stores a graph along with a list of properties of it's edges and vertices stored as [dictionaries](https://en.wikibooks.org/wiki/A-level_Computing/AQA/Paper_1/Fundamentals_of_data_structures/Dictionaries).
- Each vertex has a property `:val` and `:loc`. The `:val` is the value of the spin, the `:loc` is the location of the vertex on a 2D plane so that we can draw it.
Okay that's our lattice. Next is constructing a graph with the right connections to make a lattice. Easy three step process is
1. Make a line between two points
2. ???
3. Profit
Okay actually tho. So the approach is the define an order 0 to order 1 transformation for each edge and then given an order $n$ lattice to make an $n+1$ lattice, iterate over it's edges and apply that transformation. Easiest if I show you step by step. We represent points on a 2D plane as complex numbers because computers can very quickly work with them. Each point is a vertex/spin. To transform an arbitrary edge -
1. Start with an edge from spin $s = s_x + is_y$ (source) and $d = d_x + id_y$ (destination), and add two spins to your graph data structure.
2. Calculate the location of the new spins. To do this, consider the "vector" joining the source to the destination as $\Delta z = d - s$. The new spins will go one to the left and one to the right of this one, and I want them visually to be on the perpendicular bisector of the bond joining these spins, so the location of the new bonds are $i\Delta z/2$ and $-i\Delta z/2$. Lastly we have to shift these points from the center to the correct location so the final locations are $i\Delta z/2 + (s + \Delta z/2)$ and $-i\Delta z/2 + (s + \Delta z/2)$. I'll draw you a picture later if you want. Lets call these points $n_1$ and $n_2$.
3. Set the `:loc` of the new spins to be these locations calculated and the spin value `:val` to be whatever you want (random +1 or -1 or either one).
4. Connect $s$ to $n_1$ and $n_1$ to $d$, then connect $s$ to $n_2$ and $n_2$ to $d$.
5. Remove the edge from $s$ to $d$.
And that does the order $n$ to $n+1$ transformation for an edge. Do that for every edge and you're good to go.
## MCMC on these lattices
Some optimization techniques apart from the regular MCMC we had -
1. Pre-calculate the exponential values you expect. Sometimes this is too big of a pain to do, so I check if an exponential is precomputed and if not compute it and store it in a dictionary.
2. If your lattice has bonds of differing weights, you'll need to store a dictionary of the nearest neighbours to a given spin and what the weight of the bond between them is so that it's efficient to calculate the cost of flipping that spin.