-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement a complex lattice to check scaling #13
Comments
Another thing to note is that there are sometimes different unit cell definitions which produce the same lattice. Would be great if could support this, too (as LatticePhysics.jl) does, since this is relevant for a lot of simulations. |
@mbeach42 tried Update: Yeah, I think we need to consider implementing a unit cell interface or a lattice type called In order to allow extending the unit cells as custom type (since I suppose nobody want to write a long type parameter if the unit cell is too complicated), we need an extra type hierarchy for unit cells, e.g |
Let me try to summarize the approaches taken (so far) by Lattices.jl and LatticePhysics.jl, they way I see it. Lattices.jl:
Status
LatticePhysics.jl
Minimal exampleusing LatPhysUnitcellLibrary, LatPhysLatticeConstruction
uc = getUnitcellHoneycomb()
lt = getLatticePeriodic(uc, 5)
# plotting
using Plots, LatPhysPlottingPlots
plot(lt) Status
Ok, this took a while, I'll comment on this later. Eventually we should try to get the best out of both worlds. |
The obvious use case would be the Kitaev model. Or any other model with edge-dependent interactions. It could also be (ab)used to cache previous results, which is what I'm doing in my classical Monte Carlo simulation for a 4-spin interaction. (Though I'm not using LatticePhysics for this) |
Right. I've crossed out this line in my posting above. The general question here is, what we mean by a lattice within the scope of this package.
LatticePhysics.jl follows the second definition: for a 2x2 periodic square lattice it returns 16 directed edges (twice the number of undirected edges). ALPS, in principle, also has a lattice as a directed graph with possible extra information attached to sites and edges (the xml definition files have edges with "source" and "target" information). However, if I create a 2x2 periodic square lattice I only get 8 directed edges (as for On a side note, while both LatticePhysics.jl and ALPS use linear indexes in bonds, Lattices.jl currently returns cartesian indexes: julia> edges(Square(2,2)) |> collect
8-element Array{Tuple{Tuple{Int64,Int64},Tuple{Int64,Int64}},1}:
((1, 1), (2, 1))
((2, 1), (1, 1))
((1, 2), (2, 2))
((2, 2), (1, 2))
((1, 1), (1, 2))
((2, 1), (2, 2))
((1, 2), (1, 1))
((2, 2), (2, 1)) |
As for directed graph, you can always get its edges by simply inverse the order of undirected graph for (a, b) in edges(lattice)
# edge ->
a => b
# edge <-
b => a
end The original design of this package is partly inspired by graph packages in
This is the default output of iterators, since that is what you got in the first place during calculation. But you can get its linear index by indexing the lattice with it, e.g DefinitionLattice here in this package defines a certain geometric object, which can be used to specify connections or interactions etc. Type Hierarchies
All the lattices type above assumes to represent a special kind of undirect graph, since we can always simply iterate through a geometric region (e.g edges, sites, neighbors) by iterate the same edge with different order twice. IIUC, I think the reason why ALPS or LatticePhysics uses Why do we need specialized types? (Or why should we put some info in the type)This is because these types can be used for further dispatching which enables people to write only a few lines with multiple dispatch. Moreover, in many cases, type information can also be used for high performance implementation. The implementation of But this is not useful if you want to iterate through one lattice over and over again. But I don't think this is an issue related to lattices itself, A practical reason for this is, if we store the bonds and sites (or just adjacency matrix) in our lattice type, when we calculate the faces or other region (in the future, e.g super edges as super graph), the iteration should still be cached, which make the implementation repeated. To follow the DRY (don't repeat yourself) principal, I think this should be separated. FYI. Part of this infrastructure is implemented in Interfaces
The interfaces mainly just ask for iteratbles, which make it very flexible and extensible. |
ping @janattig |
First of all, thanks @crstnbr for making the nice comparison and bringing me into the discussion as well. Let me make some comments in the following as well:
These are actually two different questions:
As for both my opinion is YES, since 1. you need to distinguish between different sites / bonds in nearly every physics case apart from lattices with only one site per unitcell and 2. most notably in the context of complex hopping / interaction as this introduces signs into the Hamiltonian matrix later on as is e.g. needed for Majorana models.
Although this is true, this is unfortunately not solving the problem of defining a convention of directionality. |
Thanks for the comment! this is very helpful, since I don't have as much experience on this direction as you. @ffreyer However, I still have some question that I'm not sure, can you provide more description for
I didn't mean it shouldn't. But the abstraction is made at different level:
This design is actually used in many Julia packages already such as graphs. The LightGraphs.jl defines the most basic geometric structure of a graph, and then other packages will be built based on this package such as weighted graph (like you mentioned labels, weights are one kind of labels) SimpleWeightedGraphs.jl, StaticGraphs.jl, and if you like more generic labels, there's MetaGraph. What I mean there is we can always define an extra type hierarchy based on undirected lattice type by simply wrap it in a Since lattices in principal is very similar to graphs (but not the same), I believe we can adopt similar design in the abstraction. Moreover, this allows us to make use of Plot Receipts which is the official API of Plots instead of putting all the plot definition inside the core, which make it much easier to interact with different plotting backends. |
I think you meant to ping @janattig. |
What I would like about this is that the user could step into the picture at whatever level of abstraction he wants: If he doesn't need labels, he gets a simpler lattice without labels. The question to me is how much extra effort this would take. I reckon that it could be sometimes easier to immediately label sites during construction rather than taking an unlabeled lattice and adding labels retrospectively. But maybe should simply try and see? |
Adding labes to sites or bonds can probably be done in a Node or Edge constructor respectively. For example, we could have a Similarly, we can add an |
I mean that every edge |
I think concerning the labeling it is much easier to provide sort of default labels when no label is needed by the user than to insert labels on a pre-existing structure later on. |
The extra effort is just one line But I agree. I'm trying this in #17 , feel free to comment. I think the reason why doing this is because of the maintenance (flexibility for developers), as some of you might already notice, graph packages in JuliaGraphs are not developed by a single person, but a few people separately with a common interface, and this design will allow people to define their own staff separately, regarding to this package would eventually be some generic public package, it worth it to pay a bit more effort to make it easier to extend (flexible).
Yes, this is exactly what struct BaseLattice <: AbstractLattice
end
struct LabelLattice <: AbstractLattice
lattice::BaseLattice
labels::LabelType
end Although, actual implementation will be different from this, but this is just an equivalent way of implementing inheritance in Julia, this is equivalent to the following code in C++ (or Python) class BaseLattice {
# interface about geometry
}
class LabelLattice: public BaseLattice {
LabelType labels
# interface about the labels
} The share the same interface for lattices, and in fact, nothing else except one line
Yes, this is the cache iterator. In principal it should be equivalent to LatticePhysics's lattice in performance and storage complexity. |
I wonder if the approach taken in this package "scales" to larger, complex, higher-dimensional lattices. Currently, there is no explicit unit cell concept, all sites are at integer positions (#10) and boundary conditions are implemented explicitly.
Perhaps, we should try implementing a complex lattice, where generating all the lattice iterators is non-trivial to convince ourselves that the abstract concepts hold in such a case. What do you think? @mbeach42 @Roger-luo
(EDIT: We could consider the monster lattice (10,3,c), for example: https://github.com/janattig/LatPhysUnitcellLibrary.jl/blob/master/src/unitcells_3d/10_3_c.jl)
The text was updated successfully, but these errors were encountered: