So welcome back after the coffee break. So now in the second part of today's lecture, we will now dive into the questions of symmetries, like what role they play and what we can do with them and how to deal with them in an exactingization code. So as an example, I've written down a Hamiltonian here. That way, that's the sum over bonds on a lattice. So ij are pairs of sites. There's an interaction here, which we call jxy, which couples x and y component over here. We think about the spin-a-half problem in such a way. And then there's a coupling in the z-spin direction, which is possibly different. So that's a so-called x-axe model. And then we can ask ourselves, what are the symmetries, which this problem has? So one thing which you can see by rewriting the Hamiltonian, the sx, the sy part, is that it actually only involves spin-flip operation. So you can rewrite that as jxy divided by 2 times s plus s minus ij and s minus s plus. So then it's obvious that it conserves total sc. So that's the reason why we considered such a c conservation previously in the first lecture. And so therefore, you can actually restrict yourself to give an sc-sector. Respectively, you can treat all the sc-sectors one after the other and accumulate the lowest energies in each of the sc-sector and figure out in what sector the ground state actually is. And that symmetry is actually simple to implement, because for example, while constructing the complete basis, you actually check each basis state where it has the correct sc, which you desire to look into and do discard all states which should not satisfy that constraint. And then you register only those states in your Hilbert space having the correct sc as a basis state. And then typically, if you're working on a regular lattice, like on, for example, a torus lattice, a square lattice with periodic boundary conditions, then the Hamiltonian has additional symmetries. So one thing is the lattice, but the order is also that the couplings have to be symmetric on the lattice operations. And then you have a substantial symmetry group in addition, which can be a few hundred elements large. So in many cases, but it's not exclusive, but in many cases, if you have regular lattices, you have a translation symmetry group, which is a billion. And then you have a point group symmetry in addition. And then the full space group is roughly the product of the two groups. And we'll spend some time now to explain how what the technology is to actually implement these symmetries. But then at particular points, you have additional symmetries. For example, if you take this xxc Hamiltonian and you put the sc, the jz coupling, strictly equal to jxy, then this model does not only have this sc symmetry, but actually it requires a full su2 symmetry with the full spin conservation. So then where the total su2 spin s, which is also conserved, and so you would think that it's actually quite natural to include as many symmetries in your code as possible. But actually it turns out that it's not so simple to implement on the same footing the conservation of lattice symmetries, like of momenta and discrete angular momentum, together with the su2 symmetry of the spin space. So typically it's not that it's mathematically impossible. It's possible to do that. That's not a problem. But it just turns out that the code where you do basis reduction with both becomes so complicated and inefficient that it's not used in production applications. That's the main challenge. But if one someone has a clever idea how to combine that, I think there is still room for this reduction. But it's not something which people do for large scale computations. So you can do, I mean, I will mostly talk about how to implement the space group symmetry. But you can also actually and drop the space group symmetry and only work with total spin. That's also something which people sometimes do. So for su2 spin, you don't gain a lot. Because if you look, for example, at the system sizes we have, like in the 30, the 40, or 50 spins for spin and a half, then the number, if you say, for example, I want to restrict to the global singlet sector, if you look by how much the singlet sector is smaller than the overall element space, you're roughly in the same order of magnitude as the gain you get by using point group symmetries. So they don't differ by a lot. Of course, if you could combine both of them, it would be interesting. But that's technically challenging. But something which is an interesting development is that in the group of Frederick Miele and Losan, they recently came up with a way to use S2N symmetries. So if you're interested in S2N symmetric spin, Hamiltonians, their reduction to actually work in a singlet sector is much bigger. And then you can actually, by choosing not to implement lattice symmetries, but to implement S2N spin symmetry, you can actually start the larger systems by using that reduction, then using the path, using lattice symmetries. So that there are applications where it's actually, it pays off to implement the full S2N symmetry. But for S2N, it's not that impressive. It's mostly when n gets larger that you really gain something beyond calculation. If it's not the full S2N symmetry, but only the diagonal conservations of flavors, but still uses a point group symmetry. But some additional remnant of the S2N symmetry is that if you're at a c equals 0 in that model, so if you have as many up as down spins and your Hamiltonians of that type, you actually have a so-called spin flip symmetry. In particle language, it's more like a particle hole symmetry, where each configuration is basically mapped onto its conjugate in terms of occupations or spins. And that's a symmetry for any of the JC values, even if JC is not one. But if JC is actually one, so if you're looking at the Heisenberg model and you're implementing this symmetry, which is simple to implement in your computational basis, then you're actually able to discriminate between even and odd spins. So this is a Z-tooled-like symmetry. It has eigenvalues plus or minus 1. It actually splits your SU2 representations into even and odd sectors. And so even though you're not able to get full SU2 block reduction, you can still, using this discrete symmetry, you can still use kind of divide Hilbert space in half. And that's something which is simple to implement and which is worth looking into. So here you get an idea about the symmetries which one typically encounters. And they just now have a look at how spatial symmetries come around and appear. So actually, spatial symmetries are important for two reasons. The one which is clearly a computational aspect is that they are important for the reduction of Hilbert space. Because as it is obvious, if you have symmetries, you can block diagonalize your Hamiltonian. And after that, the block you still have to consider has a smaller linear dimension than the one where you have all blocks involved. And so you can reduce the computational effort for a single block. So that's one thing. But that's not the only reason why we're using symmetry. It's actually also that knowing eigenstates or eigenspectra with symmetry-resolved quantum numbers actually can teach us a lot about the physics at work. For example, you can learn about dispersion of excitations because you can see how excited states above the ground disperse as a function of, say, linear momentum or angle momentum. And you can also read off symmetry breaking tendencies. And this aspect will be part of tomorrow morning's lecture where we talk about spectroscopy. And as an example, you can actually look at the many-body energy spectrum of, say, a Heisenberg anti-ferromagnet on a square lattice. But just looking at the energy spectrum, you can already get quite convincing evidence that the system is likely to order magnetically in the thermodynamic limit. And you can do that by just looking at the structure of the low energy state. And that's something which is quite an interesting way to study ordering tendencies in complicated systems. And to give you an idea about some lattices, I mean, if you come from a quantum Monte Carlo or some other world, you're typically used, for example, if you have a square lattice, and a simulation cluster you would use would typically run some units in the x direction of your lattice and some units in the y direction. So like a 6 by 6 cluster and 8 by 8, which is quite natural. But actually, it turns out that you can look at other periodic tiling of your 2D systems, which still have the topology of the torus, but which have other number of lattice sites and just something like Lx times Ly. And this is a particular example. But this is a 40-site square lattice. And you can see that the rate boundary is the boundary of your simulation cell. And what is not obvious, perhaps if you see this the first time, is that you actually still have a lot of symmetries in that simulation cluster. So first of all, what are the colors of these sites? But this actually tells you that, for example, this orange site here has its periodic image here. So this is really the same site. It's identified. This is not the second one. This is also the same as this one and as this one. So this site appears four times, but actually each time it only contributes a quarter. And then this cyan point, that's also the same. They differ by a simulation cell, periodic kind of lattice vector, and the green one as well. And if you now start to count each of these colored points only once, and you add up all the sites which are clearly within the simulation cell, you see there are 40 spins, 40 lattice sites in there. And then you can periodically repeat that. I think it's obvious that you can cover the entire 2D plane with such tilted lattices, which is just that the translation from one simulation to the cell to the next is tilted with respect to the lattice axis, but that's not a problem. Something which is not so obvious, but you can actually also define really translation symmetry within the cluster by microscopic shift into the x or the y direction. And the boundary conditions are such that you can really consistently define the 40 translations within that cluster. And actually also, if you think about it, you can convince yourself that, for example, the cluster is actually also periodic, is consistent with rotations about the central site here. So you can make 90 degree rotations about the central site. And so it still has a discrete fourfold rotation symmetry like the square lattice actually has. So the only symmetry which the infinite square lattice has, which this cluster does not have, are reflection symmetries. So like if you reflect through such a lattice axis here, which runs either along x, y here, or x, or on the diagonal, they are not compatible with the shape of the cluster because then it gets flipped and it does not lie on top of each other. So reflections are not symmetries of this cluster, but all translations are and fourfold rotation symmetries. So overall, the space group of these 40 side square lattice has a translation group of 40 elements and the point group of four elements, these four rotations. So together, you have this cluster has 160 point group elements. And that's nice because if you're then working in a one-dimensional representation of that discrete space group, you can actually reduce the Hilbert space of your model after, say, spin reduction, AC reduction. You can get another factor, 160 reduction, because you're using, for example, a fixed momentum 0 and angular momentum around this lattice central side. You have four different choices of angular momentum. If you choose one, you get really a 160 factor reduction of your Hilbert space, which is quite welcome. And another example here is a magnetic molecule. So there exist magnetic molecules in nature which where the magnetic ions sit on the red sides of this interesting-looking structure. But this is a so-called icosidotic hydron. But this has 30 vertices, so 30 sides. And the point group of that object is the icosahedral group, which has 120 elements. So since the magnetic ions of that type exist, there's also some interest in studying the quantum spin models on these lattices. And here, you're also interested in using all kinds of now kind of spherical symmetries. These create spherical symmetries. And you can also use these symmetries and implement them.  I mean, you can generate them geometrically using some program. And then you can also think about the action of the symmetry groups. And then the computer can actually figure out the symmetry group for you. So you don't have to do that by hand necessarily. I mean, like here, there's a rotation axis through the center of this pentagon here. You have a five-fold rotation axis. And then you also have reflection symmetry planes and so on. And typically, I mean, since these are also molecules, I think you can also resort to looking to chemistry or crystallographic literature or software. And then you can extract information like that if you're doing simulation on similar molecules or so. So something I would like to show you a bit about how clusters are possible is that some people in my group have actually started doing a lattice catalog. So I can show you this quickly. So there's actually a systematic way to generate lattices for a different type. For example, here there are square lattices. And then I think they went up to, I think, 48 sites or something. And then you can actually click. For example, if you're saying you're interested in doing a spin model on some lattice and you say you could afford something like 20 sites. So for example, you can go here to square lattice 20. You click on it. And then you get a list of all these periodic tori of square lattices. And here we start with the most symmetric is typically listed first. So you see there's a certain convention how to label them, square lattice. It has a point group symmetry of C4. So actually, it also has a rotation at 20 translations. That's always obvious. But then it also has a fourfold rotation symmetry. It also tells you what are the high symmetry points in the Brillouin zone. So gamma is the center of the zone. M is a point. And here is pi pi, the one corner of the zone. And then there's x, which is like pi 0 here. And then it has a few other points in the discrete Brillouin zone of that cluster. And then depending on the phenomena you have in mind, you can check whether the cluster you, which is like this one, whether it has the high symmetry points which you require for the physics which wants to manifest. Or you can actually also try just to go through different types of cluster. And for example, figure out which one has the lowest energy because that might be an indication of the physics going on. And then I can also show you, for example, if you take a typical square lattice, which you would also choose, which is like a 6 by 6. So 36, you see there are many of them. And so the first one which pops up is just a standard 6 by 6 lattice. And here you can see the point group is lively larger. It's D4, which means that's a symmetry of the square lattice, which has four reflections in addition to four rotations. And therefore it has eight point group elements, 36 translations. So here the point group is already larger. And then you can also see the different k vectors you have in your discrete Brillouin zone here. And so that's quite nice. And perhaps in the future we'll make that lattice catalog available online. And so people can then perhaps refer to this library in somehow clarifying what simulation Torai they actually use for their ED simulations. And in the catalog there are also triangle lattice and Kagome and honeycomb lattices and so on. And one can extend that probably also to three dimensions and so on later. OK? Yeah, and so I mean it's a bit related to the question you had. I mean sometimes symmetries are not always easily visible. And then there are options to use graph of theoretical tools to determine the symmetry group. And so here some packages which came to my mind are on the one hand naughty. So naughty is a code which is actually able to figure out automorphisms of graphs. So a lattice model, like a lattice here, if you say you want to study a nearest neighbor model, you can actually write down an interaction graph where there are edges between sides which are coupled. And then you can ask, what is the symmetry group? The automorphism group of a graph with such edges, which might even have different colors. And then naughty is a code tool which actually is able to tell you how many symmetry operations the automorphism group of that graph has. And then it would tell you for that cluster that if you're looking at the nearest neighbor models where all bonds have the same colors or are there for the same, it would tell you that indeed this cluster has 160 elements. And so because sometimes it happens if you're looking at small clusters, sometimes they can have additional symmetries which are artificial.  And then you can think about whether you want to implement these additional symmetries or whether they're just an artifact of your small cluster. So one thing which is a curiosity, for example, if you're studying a four by four lattice, a four by four lattice, where here you always mean periodic boundary conditions in that direction, I mean here and in that direction the same way. So how many symmetries do you think this square lattice has? If you just consider it as a four by four square lattice, how many symmetries do you think it has? How much? 64. But this one is a, first of all, how many translations does it have? It has six translations. And since the simulation cell is really a four by four square, which is aligned with the lattice axis, the point group symmetry you have, which we expect, is actually also fourfold, has eight elements. Of course, the point group in addition has a cardinality of eight. So together this is 128 elements. That's your guess.  The question is, what is wrong with that cluster? Pardon me? That's how much we ran on data that's in a query. Yeah, I'm not aware about the diamond. But actually, I think it's like a four dimensional hyper cube.  It's basically a cube, which has eight sides. And then it's basically, it has another cube, which leaves like translated into the fourth dimension. I'm putting them next to each other, but it's actually meant to be like a step away in the fourth dimension. So you agree that this together gives already 16 sides, because it's two cubes. But then if you actually think about that they are connected in such a way here, then your coordination number is correct, because like on a cube, each side has coordination number three. But if you now link them with an additional bond into the fourth dimension, they have a coordination number four. So that also seems to match. And if you start to think about it, you actually figure out that this four by four by four lattice, which you put down on a square, equivalently, if you just consider nearest neighbor coupling, is actually the same as a four dimensional hyper cube. But if you think about the symmetry of a four dimensional hyper cube, I mean, for example, you will have rotation axis around the body diagonal of a cube, and that's a three-fold rotation axis. And that gives you a hand-waving argument why you have a factor three more symmetries here than you would expect by this consideration of a square cluster. So I mean, dangers like that are not always lurking around. But there are some innocently looking cluster like these four by four, which actually have more symmetries than you would naively expect. And that's just the properties of these kind of small clusters. And the impact of that is also interesting to know about, if you have a cluster which has more symmetries, it actually also means that the representation of your larger space group or point group actually also lead to larger representations. Irreusable representations are larger dimensions. And the effect is that if you, for example, study a spin-wave spectrum of a Heisenberg model on that cluster, you will see that in your energy spectrum there are points in the Brillouin zone having exactly the same energies, which are not required to be the same by the natural symmetries you have in mind, like if you would trace this version. So for example, what it turns out is that momenta pi over 2 pi over 2 and momentum pi 0, for that particular problem, they actually have exactly the same energy. And but that's something which, in general, you're not expecting. I mean, pi by half by half and pi 0 are not symmetry related on the square lattice symmetries. They are distinct points. They are expected to have different energies. But what happens is that since this cluster has actually a larger Heisen symmetry, this actually makes that these two representations are somehow merged into a larger representation of a larger symmetry group, and then they end up having the same energy. But then that's something which is a particularity of that cluster. And if you study the same model on larger and larger cluster, you see that, for example, these two energies actually split, and they have different values in the thermodynamic limit. But this is just some remark that you have to be cautious. And also, the 4 by 4 class is something that people do for Harvard models and other nearest neighbor models. But it's important to actually know that some of the aspects of this might be particular to that cluster. So it's important to know about these, in case you're ever looking into properties of these. Yes? Are you saying that if you were to like this, would you be able to look at it? No, it's not there, yeah. If you take this 40-side cluster, for example, or even a 6 by 6, a perfectly 6 by 6 cluster, it does not have this hypercube aspect. It's really a particularity of that 4 by 4, of that particular 16-side cluster. No, once you believe that and you make that embedding, you realize it's true. I mean, there are two ways. I mean, OK, this has been discussed in the literature before, so it was not my observation. But people have remarked that. But one way to go, in case you would not know about that, is that if you, for example, run north on a 4 by 4 cluster with nearest neighbor interactions, you will figure out that it has more symmetries than this 128 you would expect. It actually will tell you, I think, if you have this num, or even more, I forgot. But at least it's more than it has an additional rotation-free symmetry in addition. And this graph tool would tell you that this particular cluster has a larger symmetry group than you would expect. Yes? I don't see how you can use, at the same time, the north, the naive translational symmetry, and those additional translations in this situation. How can you use both at the same time? Which tool do you mean? The normal translation. Yes? And this, which is the transition. There are not two. I mean, the translation group is still generated by the naive single-step translation into x and y direction. I mean, these are just the, like, these twisted translations. Let's just tell you how the periodic boundary conditions are determined. Let's just tell you that this edge here is identified with that edge. But that's not the translation symmetry of your, that's not what I mean by translation. The translations are still generated by these steps here. But what is important is that somehow you glue that together that if you, like that side, if you shift it into x, it will shift to here, to here, to that one. And then by periodic boundary conditions, next time you shift it will appear here, here, here. And then you will come, then you go enter here. And then you will go like that. You come here. And then you're back. So you somehow see there is a, the translations are all generated by tx, but it will only close probably after 20 or so steps I think. So like there's a 20, like the order of that element is 20 in that case. And in the y direction it's the same. So the group has a particular structure. So it's not like if you take a six by six lattice, like you have two cyclic group spaces. You have a loop six in that direction. You have a loop six in that direction. Here it's a bit different. It's more like 20 times two or something like that. But it's still an abelian group. And you know how it's momentum look like. And everything's fine from that translation point of view. OK, there are more questions. So in the next step we would actually like to reduce the basis to really somehow keep less information about the Hilbert space, to really reduce the size of the Hilbert space. And so the first step is what we already discussed. Is that we build a list, a preliminary list of all allowed states, which satisfy what one might call diagonal constraints, like particle number or total AC. So that's what the case we discussed before. So we filter out all states which do not satisfy these kind of simple constraints. And now the idea is basically if you have translation symmetry and those of point group symmetries, the way we present our Hilbert space, these symmetries really act as permutation symmetries on the level of the occupation of our local states. Like in the spin chain here, for example, here we have a four-site spin chain with a cyclic translation group here. And so the symmetry really acts, OK, this is the identity, but this is a shift by one lattice side. But it really just permutes the lattice sides, the occupation of lattice sides here by shifting them one cyclically to the right. So like the zero moves to one position to the right. And that's kind of, I mean, this seems obvious, perhaps in this example, but it's important to know that here we somehow working with symmetries, it really leave the nature of the states invariant. They're just permuting them around on the lattice sides. But if you have something like a spin orbit symmetry, like if you have a relativistic thing, then actually, for example, you could imagine by doing a spatial rotation that you also have to rotate in spin space. But this is not taken into account here. So here we're not considering operations which are combined spin orbit operations. So if you would do a spatial rotation, and then you would also have to rotate spin, that's not in here. So in the spin space, so like in occupation number basis, nothing is happening apart from permuting the states which are already there. So it's in a powerful setting, but it does not encompass combined spin and spatial symmetries at the same time. And now the idea is basically, as you can see here, if you have this permutation, then basically, if you have a configuration, any configuration, if you apply symmetries onto them, you will generate a so-called orbit. You will generate a certain set of configurations which are all related to one configuration by one symmetry operation. And the idea is basically, instead of having all these different configurations, it's just different by a symmetry operation from a starting one. You would actually like to delete all of the other ones and just keep one. And that's the one which represents this whole orbit. And that's actually the reason why you can compress the Hilbert space. If you're able to only keep one state which represents the whole orbit, then you have basically made the compression with the factor of the size of the orbit. So here in that case, here for example, so we're back to some s equals 1 state on this four side chain. Now we're looking at it as a periodic ring. And we don't talk about reflections. Of course, although this has reflections, but here we're just considering the translation group aspect of it. So we have these four elements, the identity and the three shifts with one, two, and three lattice sides. And so if you take this always the same state here, we shift it. That's identity. We shift it here. It goes to the right. We shift it by two units. We shift it by three. And now we need to somehow define a rule by which we actually choose the so-called representative. And one natural choice is that as I stated here, is that we take a state, we apply all symmetry operations, and we keep it the state only as a representative if it's actually the smallest integer in this orbit. And so in this particular example, if you start with a state which has the leading bit set to zero, that's the smallest integer representation of all the ones generated here. So that state you would keep. That's the representative of that orbit. However, if you start, if you would take another state of that very same orbit, here we realize that this one is actually not the lowest image we have generated, because if you shift that one three times to the right, we get the same state. So this state here, we will discard. And only this one here is kept as a representative. So that's basically how it's really done in the code. You go through all the states. You apply all symmetries. And you keep the state if the one you start with is the lowest one among all you have visited when you apply the symmetries onto it. And then what you're doing conceptually is that you're basically building a delocalized state or a block state or a symmetric superposition of your state. And so that's written here a bit more mathematically here. So R is like the representative. So R is kind of a state in your Fox space, but one which is not yet symmetrized. And what you're doing here is basically you sum now over all the group elements of your symmetry group, large g. So g is the symmetry group. Small g is the element of the symmetry group. So you're summing over them. And then you apply g onto R. It has some action. It permutes the bits. And so you generate several other ket states. And then you have some phase here, some number, chi of g. And chi is a character of the representation you're working in. So I don't have time to actually do a course on group theory. But if you want groups have irreducible representation. So these are like, as the name says, irreducible blocks where the symmetry acts consistently within. And these irreducible representations have a number, some class function, which is called the character. And the character gives you a number for a certain representation. So chi is a function of the representation. And in simpler terms, if you have a translation group, a representation is like a choice of momentum. So different momentum sectors are different irreducible representation of translation group. And then the character here would just be like the Bloch factor. So like e to the ik times R, where R is like the element or has placed a role of the shift of g. And chi is then this Bloch factor. So that's like an example for a character of an irreducible representation. And for the expert, so like the formula as it's written down here, it actually applies only to irreducible representations of dimension one. If you're considering irreducible representations of a larger dimension, this formalism has to be changed somewhat. But I'm not talking about this because actually, not in all cases, but in many cases, you can actually get around the use of larger dimension representations and actually reduce the size of the symmetry group. And for the smaller group, still work with one-dimensional representation. And you're able to reconstruct the same information as working with a larger symmetry group but with irreducible dimensions which are larger than one-dimensional. OK. And so you see here, the basic idea is basically we build an orbit.  And then at the end, we want to normalize the state. So there's a trivial normalization here, which would take a square root of the number of group elements. And that has the effect that if basically in the orbit, we really generate a g-different states which are not the same, then it's clear that we have to normalize by square root g here. But what can happen is that some microscopic state is actually invariant on the sum of the elements of our symmetry group. And you will see examples of that. In that case, it actually means that here there will be a less number of ket states generated, but they actually have a double amplitude, which means that the probability amplitude will be square. So there might be a correction factor here. And this we call calligraphic n. And the calligraphic n, you can see here, it's given basically by the sum over all elements of g which leave g invariant. So it's like a stabilizer group or something. It's like a subgroup of g, which actually leaves the specific microscopic configuration invariant, that this is a subgroup of g. And so we sum up these phase factors here and take the square root, and this gives this correction factor. So you can see that states which have additional symmetries with respect to the symmetries at hand, they actually are normalized differently. And that's a bit tedious, but you really have to take care of that. Otherwise, your calculations are wrong. And you will now see basic some examples which make it clear in what cases this can happen. So again, now we study in somewhat detailed, just the very same four sides in a half ring with cyclic translations. Again, and now we also look at different AC sectors. So let us start now. So here we choose linear momentum to 0. So that actually means we're now making a definite choice for our representation. So basically, having zero momentum is choosing the completely symmetric representation of our four side translation group. So it basically means that this chi of g is just one for all g's. That's the zero momentum representation of the translation group, if you wish. So chi of g is always one here. And now we're looking at different states in our Hilbert space. For four spins, we have AC equals 2, AC equals 1, and 0. And here we also have minus 1 and minus 2, but they are the same, so I didn't put them. So if you have AC equals 2, so you see that that's the ferromagnet, all bits are the same. And it's obvious that this state is completely symmetric. Whatever permutation you would apply onto it, it's symmetric. And so it's obviously an example where g of r always equals r. So basically, the subgroup over which you're summing here is really the full group, actually. So here you're summing up all the characters. And therefore, there's a large correction factor for the norm here, because you actually here you have four different, the amplitude is actually four here. And then if you do the same for AC equals 1, we get back the state we have discussed before. So the representative is 0, 1, 1, 1. And since this, if you apply the translations, there will be four distinct states. This correction is actually one. And so this is a standard case. And in the AC equals 0 case, we have two different orbits. There is this orbit with a staggered occupation with up, down, sorry, down, up, down, up. It's like a nail state on four sides. And this is slightly symmetric, because as you can see, if you shift that state by two lattice sides, it's already invariant. So it gives you a different norm, because the state itself is more symmetric than the symmetry group. And therefore, it has a different norm factor. This is completely symmetric. This is only symmetric under two-step translation. So it has a correction factor, which is square root of 2. And there's another orbit in this AC equals 2, which is 0, 0, 1, 1. That has four different images, so n is 1. So that's one thing. So on the one hand, you have to worry about the norm correction factor. But now we go to finite momentum. For example, plus minus pi over 2. And now you can see that the norm can not only be modified. A state can actually also be absent from a sector. So here, for example, the ferromagnet, I mean, somehow it's clear, though. The ferromagnet is a single state. And now we have projected it into the zero momentum representation. So that state already has a fixed momentum by itself. So we cannot expect that state to have another momentum as well. It's only one state. It cannot appear in different irreducible representations. And what happens here is basically is that if you calculate this n here, if you sum over all the characters, which are basically 1i minus 1 and minus i for the four shifts, if you sum them up, these are four roots of unity, they add up to 0. So n, for this state, because it's the full group, and chi for momentum pi over 2 are these four characters I've mentioned, is n actually sums up to 0. And so you have to delete that state, which means the ferromagnet, s equals 2, there's no state at pi over 2 in that sector. Then this s equals 1, that state is present. That's fine. But among the two orbits in s equals 0, this one is actually deleted. It's not there as well. But the other orbit here, it's present. So we see that at this momentum, our Hilbert space looks slightly different than at zero momentum, because here we have now, say, four orbits in that list. But here, two out of the four orbits have been deleted. They are not there for that momentum. And then we're lacking the last momentum, which is momentum pi. Moment pi, it's yet different. So the ferromagnet, again, does not appear. The s equals 1, again, it appears. But the two orbits at s equals 0, they're both present. So you see the 0, 1, 0, 1 is still present. And that one as well. And so now we have basically decomposed our Hilbert space of a four-side chain into these different momentum sectors. And we have learned that the projection into symmetry sectors actually also can lead to cancellations that the state, a certain orbit, is only present in a subset of the irreducible representations and not all of them. And we have to really keep track for each orbit. We have to keep track whether it's actually canceled or whether it has a modified norm. We need to know that information for all of our representatives. Otherwise, the calculations are not correct. And now to make the thing, we have to now to check whether the decomposed Hilbert space really has the correct dimension. So we have four spins. So the overall Hilbert space needs to have 16 dimensions, 16. So here we have s equals plus 2 and minus 2. So we only have one state here at zero momentum. And you have another one for minus s equals minus 2. That gives 1 plus 1. So in the s equals 1, you have seen here that orbit really decomposes into four states, four different momenta like this. There are two momenta here, and that one is 4. And there's another one for minus s equals minus 1. It's 4 plus 4. Then we see that this state here, it only appears twice. Namely, once in this momentum and one in this second, it gives 2. And this one appears 4 times 4. And if you sum that up, you can convince yourself that it's 16. So we have kind of correctly redistributed the states into the grid of s c and momentum sectors. So you really need to know basically what this n is. For each orbit, you need to know this n. And we'll now see that this quantity enters again if we are now thinking about the structure of the Hamiltonian matrix. So if you think about what you have done, we have created the Hilbert space now with the representatives of their orbits and their respective norms. And now the question is basically, have you really kind of saved something? I mean, we have definitely saved space because you have compressed the Hilbert space size by the length of these orbits, which is typically, I mean, a question of typicalities. So if you look at this picture here, you see there are a lot of, so you see in this 4-4 side ring, if you look per momentum sector, you see here there are no cancellations. But here, like half of the Hilbert space is kind of gone. And here there's a little bit. But it actually turns out if you make your system larger and larger, these states which have either special norms or complete cancellations, they actually get rarer and rarer. So if they are still important, you have to keep track of them. But they will be more the exception. Most of the states in the Hilbert space are kind of look almost random, so they don't have remnant symmetries. So the generic case is really that this norm factor is one. And it's only this exceptional state which have additional symmetries under the symmetry group which make a difference. But they are really in the minority. So if you want to estimate the size of your Hilbert space per sector, it's really basically the size of the Hilbert space before applying spatial symmetries. And then you can roughly divide by the size of the symmetry group. And then you get quite a good estimate of how big your Hilbert space is in that sector. OK. And so with this r tilde, we basically mean that block state. We have just introduced one or two slides before. And the question is now, are we able to efficiently calculate the matrix elements? Like, what is the value of an orbit? Here, a block orbit r tilde. With another one s tilde, are we able to calculate the value of that matrix element efficiently? And so for our setting, we look now at an elementary so-called non-branching term in the Hamiltonian. So we have some h alpha, which is. And so a non-branching term basically means is that if we apply such a piece of the Hamiltonian onto a configuration in our Fox state, we just expect to have like one new state coming out. And in case there are more states coming out, we just chunk them up into different pieces which are all non-branching. So a non-branching term is either like a diagonalizing term or a spin-flip term, which flips in one to the other direction. They only give one definite result and not a linear combination. So this is not a real restriction, just that we chunk our Hamiltonian into pieces which are of that kind. That's possible. So we have such a piece here. So that's an operator here. We apply it onto the bit pattern r.  So this h alpha of r is a number. And then we get s out. So here you can see currently there is no tilde. So these are really just normal Fox state configurations here. And that's an amplitude. That's a number. And basically, there's a formula here. So we can now calculate these matrix elements among the representatives, basically, without double-expanding the block states. I mean, you can prove it, but then you can actually simplify it. And then the final formula actually looks like this so that the matrix element between two representatives of such a non-branching term in the Hamiltonian is actually given by the amplitude, which is this basic amplitude here. That's the number which comes from the Hamiltonian. And then there's a ratio of the two normalization factors which we introduce for the two n, r, and s. So that's the property of the states. And then there's one crucial aspect here. It's that there's a chi, so again, the character of the representation of an element which we call G star. And G star is basically the element which perhaps I have to tell you what happens here. If you have your Hilbert space and you have listed all your representatives, so the representative is always like the smallest bit pattern in your orbit. And if you apply an element of your Hamiltonian, you always start with that representative and you apply on it. But then when you do the spin flip on that representative, you get a new bit pattern. That bit pattern belongs to another orbit, possibly. But it's not clear whether the bit pattern you have in front of you, whether that one is actually the representative in that other orbit. You can very well end up with a bit pattern which is part of another orbit, but which is not the representative because there's no insight that if you flip it somewhere that it should really be the smallest integer in your orbit of the other orbit. And so what this element G star actually means is that there's an element, or there are many elements, but they have the same character. There are elements in the group G which actually bring back this non-representative S back onto its representative, so which somehow shifts it back into orbit. And this element G star does that. So we need to know which element brings back the element to the representative, and we need to have this associated character for it. And if you have that, then you now know the full matrix element which you have to put into your symmetrized Hamiltonian, and then that's basically solved the problem. However, so I mean, at least on the formula, we are fine. But now in your actual ED code, so if you have this possibly non-representative S, which we have obtained by just flipping some bits, for example, but the question is basically how do we actually find this associated representative S tilde, and how do we actually get this G star which brings S onto S tilde. So there are different strategies which are more or less clever or feasible. So the simple thing is just to do a brute force loop over all symmetry operations applied them onto S, and just check when you have the minimum one that's S prime. And then we also know what is the symmetry element which brings indeed S onto S tilde. But this does not require basically any memory, because you're just doing it. But of course, it's not very efficient, because for each of these operations, you basically have to do that as many times as you have symmetries, and you have seen a number of magnitudes for symmetry operations is like hundreds, 100, 200. That's easily possible if you're working on a decently large 2D lattice. So that's something you perhaps would like to avoid like applying all the symmetries again and again and again in order to figure out this element. So something you can do which requires some memory, but it's quite fast, is to prepare another lookup list relating each allowed configuration, so allowed means on the level of conserved AC configuration with the index of its representative, and also with the associated group element or the phase factor linking the two. That is quite fast, but the price you pay is that you need a list of the size of the non-spatially symmetrized Hilbert space, which means basically that you need a table which is as large as the Hilbert space with AC conservation taken into account, but not reduced by the number of spatial symmetries. So they can be pretty large, but it's still something you can afford often, and so I typically use these for intermediate size calculations. But now for specific lattices and also particular models like Hilbert models, you can also use tricks which factorize the symmetry group, the spatial symmetry group, for example, into sublattice conserving subgroups types of sublattice exchange. And then I don't describe explicitly how that is done, but I just tell you that there are such techniques where you can actually figure out these A-steels are quite fast, so you find that. And then you can use a hash or a binary search in the list of all representative in order to get its index. So that doesn't need a lot of memory, and it's somehow balanced between. I mean, this is very fast, but uses quite a lot of memory. This uses no memory, but uses a lot of computing time, and this is somehow in between. You need some memory for some lookup table of sublattices, but they are still quite economic. However, you pay some price in looking up a representative list and so on to get its index. And then once you actually are able to efficiently calculate matrix elements, you can then think about the storage, as we have discussed already. You can store the Hamiltonian in sparse matrix format, and this gives very fast matrix vector multiplies, but is obviously limited by available memory, and the more matrix elements you had, the larger your matrix gets, so that can be a limiting factor. You can also store the Hamiltonian matrix elements on these in a sparse matrix format, but I'm not sure people do that these days, but in the past, when somehow the IO speed was still comparatively fast, compared with the CPU speed, then that was still fine, but I think in the meantime, the computing speed of the processors is much faster in comparison to the read speed that you can get from disk, so it's not clear that that's still something which is actually efficiently doable, and what I advocate, at least for the cutting edge calculations, is to recalculate the Hamiltonian matrix elements in each iterations on the fly, and where basically we want to devote the whole memory to the Lanzos vectors, and there are also strategies how you can parallelize that either using shared memory architectures or even using distributed memory architectures, but that part is a bit more involved, but it can be done, and giving decent hardware, it actually scales quite well. Okay, yes? Pardon me, if you? What's the matrix vector? They're basically the Lanzos algorithm, at some point it will call kind of the physics back end and ask, look, I have a vector in your Hilbert space, I apply h onto the vector, and then I'm just recalculating the matrix elements and given a vector, I calculate the matrix elements and I figure out, okay, that's my input in the vector, I put the matrix element and I store it in the result vector and you don't actually have to store the matrix, but you can really do this operation on the fly by only using local information and without storing the full matrix, and that's really where it's interesting that the Lanzos algorithm, as I mentioned before, it's not interested in addressing individual matrix elements of your matrix and doing something with it, but it just asks to deliver a matrix vector multiplication onto a vector which the Lanzos algorithm provides, but it's not interested in actually doing operations with the matrix elements. That's different, say, from a Jacobi diagonalization where you really, you go ahead, or a householder where you go ahead, you have your matrix and you do operations on the matrix, that's not how our Lanzos algorithm works, it works differently, and I will explain, just now come to that. Are there more questions at this stage? It's actually curious, you have seen, we already spent quite some time explaining issues about symmetries and lookup tables and so on, and they are kind of more involved, at least they are equally involved as the linear algebra back at which we come, and although sometimes people call the technique we're discussing using a Lanzos algorithm, actually this linear algebra part, the Lanzos algorithm is just one of many aspects of really workhorse exact diagonalization method. It's not just this, it's important, but it's not the only thing which requires investment, so if we really want to have a flexible tool, you have to think about these symmetries and other aspects, and the linear algebra back end in order to get the eigenvalues, it's just one aspect of it, but not the only one. So if you're kind of new to this business, there is a nice book which is actually also available online, which is called Template for the Solution of Algebraic Eigenvalue Problems, and they describe many different iterative algorithms for eigenvalue problems, yes? It depends again what you exactly, in which regime of system sizes or Hilbert space sizes you're operating. I think if you're just working on a workstation and using RPAC or something like that is perfectly fine, and also it has some built-in facility also to converge several eigenvalues with decent precision and so on, but the problem is a bit, it kind of times require larger numbers of lunchbox vectors, which might be more difficult to control. So if you're really doing 48 sites on a supercomputer, you really want to have strict control over how many lunchbox vectors, because they're so expensive, you really want to be sure that there's only two and not five of them allocated, because five would kill you, two is affordable, so you really want to have fine control on that, and then for these applications, we use our own Lanzos algorithm, but I mean, in the end it's quite simple. I mean, as we can see, there are just a few, a few basically neural algebra operations, and it's reasonably simple to write the simple Lanzos solver yourself, but it's perfectly fine to use RPAC on a, if you have a Python or something to use, or use this Fortran or C version of RPAC. Yeah, so coming back to this book, yeah, but there are many different algorithms described, and it's also the simple Lanzos algorithm is described in there, and I will briefly explain to what that does. So here, that's the algorithm basically in a nutshell. I will briefly explain also in the blackboard how it works in order to get an idea. So as I said, there are other algorithms like a Jacobi or a householder transformation, which really operate on the matrix, typically, and the Lanzos algorithm is not doing that. The Lanzos algorithm is actually part of a family of algorithms which are called Krilov algorithms, and we will see later in other examples which are genuine Krilov algorithm, why this is important, but somehow a Krilov algorithm or a Krilov space is an object which has two ingredients, basically. So there's like a starting vector which we call phi naught, so that's a vector in the Hilbert space. Here, now for this, it's typically a random vector, but it's one vector in the Hilbert space or in that subspace in which we're working. There's an operator, here it's our Hamiltonian page, and then the Krilov space, we might write that as caligraphic k with an index n, and then it has a Hamiltonian, an operator, and it also has a starting vector phi naught. And so the Krilov space is basically the span, the span of basically phi naught, like your starting vector, and then h times phi naught, and then h2 phi naught, and so on up to some power like h to the n applied on phi naught. So you can see the Krilov space, it needs a seed vector, a vector where you start, it's a vector in the Hilbert space, it needs an operator, the operator in our case is h, our Hamiltonian, and then it has a number which means basically how many powers of h do you apply onto your starting vector. And this space, so the span of these powers of h onto the starting vector, that generates a linear space, a vector space, and that's called the Krilov space. So I think it's simple and it's clear, so that's the Krilov space. And now curiously what the Lanzos algorithm actually does, it just takes a starting vector, and the Lanzos algorithm basically just builds a tree diagonal, builds an orthonormal basis in that Krilov space, and in that orthonormal basis, the Hamiltonian, so this operator in that tree diagonal, in that basis, which the Lanzos algorithm does, becomes tree diagonal. So I can write that like the Lanzos algorithm builds an orthonormal basis of this k and h of psi naught in which h is tree diagonal, which means the Hamiltonian written in the basis of, in this particular basis, which Lanzos algorithm generates as a form like alpha 0, alpha 1, and so on up to alpha n minus 1 or something, and either there are beta 1 to beta n minus 1, and here it's a metric, so it is also beta 1 to beta n minus 1, and the rest out there is all 0. So that's the first step. That's just to somehow put that into perspective. So the Lanzos algorithm in the first place does, or the Lanzos sequence, is actually generate you vectors, which, I mean, it starts with phi naught. That's like the first Lanzos vector, actually. And then it actually basically, it calculates h times psi naught, but that vector is not by itself orthogonal. It can have an overlap with phi naught. So in the first step, you're generating this vector, and then you're organizing it to phi naught, and then you normalize it. So there's a second vector, which is generated by that, but then it's auto-normalized to the first vector. And then you're doing another iteration, another application onto that auto-normalize, and then you back auto-organize it to the previous two, and so on. And it turns out that this particular choice, which the Lanzos algorithm makes, builds this auto-normal basis at the Hamiltonian h, and ends up being three diagonal in that particular basis, which the algorithm builds. So so far, there is no reason yet why we're talking actually about the properties of eigenvalues or so on, but formally that's what the Lanzos algorithm does. And this is an important part, because this will reappear later in other applications, like, for example, in time evolution and in calculation of spectral functions. And it's important to understand what the Lanzos algorithm does in that particular context. It's first of all, it's a way to three diagonalize an operator in a particular Krilov space, starting with some particular starting vector. So that's one thing, and here you can basically see in more detail what it's doing. So if you add some intermediate steps, so there are these Lanzos vectors phi n minus 1, so phi naught is our starting vector, and so on. And so we have a phi n. And then what our Lanzos algorithm asks us is to apply h onto phi n. So we're doing that, our back end does that, our Hilbert space implementation, and so on. So we're doing that, so we get that vector, and then we have to subtract beta n, which has been calculated at the previous step, minus the previous Lanzos vector here, so that's a phi prime. And then we calculate alpha n, which is the overlap of phi n with this phi n prime. That's alpha, this gives you the new alpha.  So we're kind of orthonormalizing it back to, with respect to phi n. And then we normalize this phi double prime. So we normalize it. And the new beta value which we get is basically the square root of the norm of this leftover phi double prime. So that's the norm, and then we normalize it, and this gives you the new Lanzos vector. And just that's the basic sequence. So basically, you have your current Lanzos vectors. You know the previous one. So you're applying h onto your current Lanzos vector. You're subtracting beta times the old one. You're calculating overlap. You're orthonormalizing it. You're normalizing it. And then you're done. Then you have your new Lanzos vector. And then you do that again. And in this particular way to proceed, you can show that your Hamiltonian projected into this current grid of space has this three diagonal form. So that's one step. And now we're coming to the question of why are we actually using that to do eigenvalue computation. What is now an interesting property, which is not so simple to actually prove? I mean, this part is simple to prove. But what is a curious property is that if you start with a random starting vector phi 0, and you do that, so what you can now do is that after each iteration, so after some finite n, you actually evaluate the spectrum of that small matrix. But you have to keep dimensions in mind. Like in a cutting edge application, these five vectors, they really live in a huge Hilbert space, like 10 to the 9, or 10 to the 11. So they are really huge. But these dimensions of this grid of spaces in typical applications are of the order of hundreds, just to give you an idea. But what you can basically do is after one iteration, after two, after three or so iterations, we can always plot the spectrum of that small matrix. It's called T matrix sometimes of this three diagonal matrix. It has a spectrum, and the number of eigenvalues increases after each iteration. And what it turns out now is that the spectrum of this small three diagonal matrix converges at the boundaries of the spectrum extremely rapidly to the spectrum of your full operator H, which lives in the huge Hilbert space. And this is illustrated here. So here there are iterations, which means that after each iteration, you diagonalize this T matrix, and we plot the spectrum on that axis. And so I guess this is a typical eigenvalue problem with the dimension of, say, millions or so. But it's still large compared to this. And what the bottom line is, that in the Lancher's algorithm, it turns out that the spectrum of this three diagonal matrix converges extremely rapidly to the ground state of the full problem. And so here this eigenvalue is converted to this is a linear scale, but actually the convergence after some time becomes really exponential. And then you're exponentially close to the physical eigenvalues of your huge matrix. And that's really the kind of the stunning feature of the Lancher's algorithm, is that it allows you to calculate the extreme eigenvalues of your full matrix H. I mean, the problem in the full Hilbert space with a number of iterations, which does not grow tremendously if you make your matrix larger. So even for this, say, 48-side calcumene, you actually get the convergence in the Hilbert space, which is like 10 to D11, with a number of iterations, which is like 2, 300s. And that's really the amazing property, which makes the Lancher's algorithm so interesting, is that you only need, like, of all the 2, 300 Lancher iterations in order to get to converge, like, the first one, or perhaps two or three, eigenvalues of a huge matrix. And that's the really kind of interesting aspect of the Lancher's algorithm. OK, are there questions so far? Yes? What if I have a good guess for a wave function, like a DMRG wave function? Yeah, that's a good suggestion. But actually, I think it turns out that it's not really so useful, because the Lancher's converges so quickly that even if you have a good energy, for example, like here, you still need, like, say, here, you need 150 iterations overall. But if you have a good guess, you just perhaps gain, like, 10, 15 iterations. So you really have to, like, have an excellent guess if you really want to save something. Otherwise, on this exponential scale, there's still a lot to be done, and you gain only very little. But the point you raise is important. I mean, if your initial state actually does not have overlap with your ground state, then it might actually take longer to converge. Because formally, like, if you're initially orthogonal, you will never have overlap with the ground state. But due to finite precision arithmetic, there are actually round-off errors which, after some time, actually make you still converge to the ground state. But then it might take substantially longer. So indeed, you have to be sure that your initial random vector, your draw, is really random enough that it has even some tiny overlap with the ground state, but some generic small overlap and not strictly zero because it's really by symmetry or something orthogonal to your initial state. Yeah, that's a good question. So what you do is that you diagonalize these three diagonal matrix, and you get the eigenvalues, and the eigenvalues are directly the eigenvalues of this. But the eigenvectors of this matrix are only eigenvectors which have a dimension like n, or dimension n.   So there are two ways to do it. If you want to save memory, what one typically does is that you do a Lanzos run until you converge.   For example, because you're using deterministic random numbers, which means you can regenerate your random vector because you know your seed. You can regenerate your starting vector. And now you know the linear combination. So now you're doing a second Lanzos run. You regenerate exactly the same Lanzos vectors, but now you sum them up with the linear combination you know.   Yeah, and then we know the linear combination. So we sum up the Lanzos vector. And then you get the eigenvector as the sum over the eigenvector over the Lanzos vector with the linear combination corresponding to the eigenvalue of that T matrix. Yeah, because something I didn't mention it, but something which you can convince yourself is that, I mean, you can see it from that algorithm here, is that at each step n, you only need access to the last Lanzos vector. And you're generating the new one. So like simultaneously in memory, you only need two or three Lanzos vectors, which means you can disregard the old ones. You don't need them if you're progressing. You don't need the old Lanzos vectors anymore. You just need two or three locally, like locally in n. So you can disregard rest. But indeed, if you want to have immediate access to the eigenvector, if you have converged the eigenvalues, you have to sum them up. But then it's again a question of memory. If you're doing medium-sized calculations, you can afford storing the Lanzos vector. Then you can build that linear combination immediately. Once the linear combination is known, you can sum up the Lanzos vector with the appropriate linear combination. But if you're having memory problems, then you have to somehow know the linear combination and start again and regenerate all Lanzos vectors. And then sum up the eigenvector while you're redoing the iterations. Yeah, it has to be the same. If it's not the same, things get wrong. But my remark regarding random numbers, so typically the initial vector is a random vector. But it's not completely random, but it's using some computer, I mean some pseudo random numbers, which means if you put the same seed to your random number generator, it will exactly generate the same random sequence again. So if you initialize your random number generator in the first run with some seed, it will be pseudo random. And then you will do your Lanzos. But then you can just reset the seed of your random number generator after your first Lanzos convergence. And then it will regenerate exactly the same so you do random starting vector. So you don't have to store it, but you can regenerate it by giving the correct seed to your random number generator. Yeah, but we have to do it because how you get from one Lanzos vector to the next is by applying age. We still have to do that. But again, a little bit, we don't have to diagonalize this again. No, you're not interested in that. We already know what the teammates look like, but we don't know. In the first run, we have not known the final linear combination, so we were not able to accumulate the eigenvector on the fly because we didn't know the linear combination we end up with. Yeah, yeah, of course. But the thing is that you can either pay memory by storing the Lanzos vectors and you save on time, but you waste on memory. So it's really a trade-off. And depending on the machine and the problem size, you can decide to store the Lanzos vectors if you can. That's obviously a good choice. Then you get your solution fast. But if you cannot store it, there's still a way to do the calculation by simply redoing it again. Okay, yeah? No, no, that sounds small. I don't know what it was. This is just an extract from this book, but I don't go through it now again. So, okay, so at first sight, everything looks perfect, but once you're interested in calculating excited states, things get a bit more complicated with the Lanzos algorithm. And the one reason is that the Lanzos algorithm is very well-defined for infinite precision arithmetrics, and you can really formally prove that all these vectors which you generate are truly orthogonal. And even the one that iterations thousand is exactly orthogonal to the first one we started with. But if you're using finite precision arithmetrics, like the 64-bit double precision numbers, they have finite precision. And this somehow leads to sometimes to subtle problems. But not, I mean, they are not as severe as one might sometimes think. So what happens is that once the ground state of your t-matrix has converged, then the vectors in this Lanzos recursion tend to lose their orthogonality. And then as a consequence, fake new eigenvalues show up in the approximate spectrum. And so there are techniques by which you can remove them, but it's a bit more tedious. And that's basically where you're probably better off using some well-tested library which has this deletion of ghost eigenvalues or ghost eigenvalues than reinventing this yourself, because it might be that if your procedure is not working well, if you get wrong physical eigenvalues out, it's perhaps not very helpful. But this is just like putting an example to the extreme. So here I start with a starting state which is strictly orthogonal to the ground state. So I start, I run down, I converge to something which is a higher excited state, which is an excited state. But after sometimes due to this round off error, actually the state really collapses onto a physical eigenvalue. But what then happens is every now and then there are new eigenvalues like coming down. And then they tend to accumulate onto existing eigenvalues. And so by eye, you can actually see here what are the physical eigenvalues and which ones are not physical. Do you know which are which? But actually, like these really these blue straight lines, these are the physical eigenvalues. They are really the ones which are the correspond to true eigenvalues of your underlying operator of the Hamiltonian. But if you stop at some moment, for example here, close to 2,500, and you stop at the wrong moment, there's an eigenvalue here which has this almost vertical slope here. And if you stop at it without looking what happens as a function of lunch or situation, you might mistakenly take one of these eigenvalues as the physical eigenvalues and then that's wrong. But you can see that if you're actually looking for eigenvalues, for example, here, which have accumulated fake degeneracies, then these are probably the correct ones. And so these are part of these heuristics which you can do. But the first message actually is that if you're only interested in the ground state, then there is no ghost problem. Like the ground state is always physical. There's no problem that eigenvalues somehow violate variational principle or something. It's always that the lowest state is always fine and converges really to the ground state. And before conversion to the ground state, there are no ghost problems. They only appear once the ground state in your sector is converged and you go further on because you want to converge higher excited states. Then it might be that this ghost problem sets in. So if you're just converging for the ground state, you actually don't need this ghost emulation because nothing can go wrong from that point of view. And another conceptual important thing is to know is that this Lanzos algorithm is basically just propagating one vector through the Hilbert space. Like you start with one starting state and you propagate that one. And basically from the construction it does, it's actually not able to resolve multiple degenerate eigenvalues. You will basically, this Grilloff technique will basically only get one component into each degenerate subspace irrespective of the dimension of the degenerate subspace, which means that formally you can only get a list of eigenvalues, but you don't actually get their true degeneracies correctly. If you want to do that, you actually have to resort to so-called bound Lanzos techniques. So that's a generalization where you're not only starting with one vector, but with several vectors, which would then propagate as a bunch of vectors together. And then this algorithm is able to explore multi-dimensional degenerate subspaces. And so if you propagate five vectors, you're actually able to resolve degeneracies between one and five, say. You can see that how degenerate eigenvalues are, but with a simple Lanzos algorithm which just propagates one vector, that's not possible. But there are other methods like this for COVID Davidson technique, which are often used in the context of PMRG. They are able to resolve a multiple degenerate eigenvalues. And here it's also best if you actually are interested in calculating degeneracies of excited states and also a larger number of excited states. It's probably important that you use an implemented and well-tested library instead of doing it on your own. I mean, you can do it, but you have to be careful not making mistakes by doing it, okay? Yeah, and then we have full diagonalization. So this Lanzos is really about calculating the low-lying part or also the upper end of the spectrum. It converges on both sides, but typically we're interested in the low-energy properties, so for ground state properties. But if you're interested in, say, thermodynamics of quantum-many-body system or also in many-body localization where really eigenstates in the middle of the spectrum are important, then you would probably go for methods which do a full diagonalization. And then you can use LaPak, householder, ScalaPak or whatever method to diagonalize the spectrum. And then to have an idea, so if on a workstation or nowadays even a laptop, you can do a few thousand without too much problem. On a workstation a few 10,000 and if you want to do Hilbert space dimensions of a few hundred thousand, you already need a supercomputer to do that. So that gives you, so you can clearly see that for full matrix problems, that the Hilbert space dimensions you're able to treat completely are really basically a square root of what you're able to do using these lunchoes and just the individual eigenvalues at the boundary of the spectrum. So there's quite a drastic difference of what you can do. And also honestly, like if you're only doing kind of this type of computations, then I think a lot of the considerations about super efficient matrix vector multiplications are not so important because in these applications, like putting, setting up the matrix with the matrix elements is something which uses negligible amount of time compared to the actual full diagonalization of the matrix once it is filled. So if you're just interested in this kind of application as long as your matrix calculation is correct, the time is not that important because this full diagonalization method scale as the third power of the Hilbert space dimension so you can see that the third power of a hundred thousand really gives you a huge number. So it's clear that whereas the time to actually fill a sparse matrix is negligible compared to the time it takes the eigens over to calculate the full spectrum of a dense matrix. So it's clear that the goals and the challenges are really not the same if you're doing full diagonalization compared to this large scale lunchoes kind of only low lying eigenvalue calculation. So there are clearly different scopes. So it is 12 o'clock now, should I stop now and continue tomorrow? No, I think it's just started a new chapter. No, I think I'll stop here. Then we see. Okay, do we have questions? Why do you get the ground state eigenvalue out of the full matrix? Constructive. Yeah, I don't have any intuitive argument why you get the ground state so well. I think it's, I mean, there's mathematical theory behind it. I mean, I think historically it was that lunchoes, the lunchoes algorithm, he was really initially interested in a method to three diagonalize an operator or a matrix. So the lunchoes algorithm was about that. And only later people figured out that it's actually quite useful numerically. And then actually, I think in the sixties or so, people, mathematicians started to prove this very rapid convergence property. So it can be mathematically proven, but I don't have any intuitive argument to give you why we should expect this to happen. I think it's a bit of a surprise. Or I don't know whether someone else has another intuition, but at least I'm not having a nice intuition to tell. Yeah? Yeah, you have a notion of full diagonalization. If you recall, for example, if you're not quite sure what you're writing, if you're not quite sure what you're writing, you don't exploit its past. No. But you've got a way to form a full diagonalization, but still exploit its past here, so it's probably the matrix, it's past or not. Yeah, I'm not aware that the algorithm exists which do that, but I might not be not informed. But as far as I know, I think there's no, because the problem is also like, if you're interested, it might be that you can cheat around that if you're only interested in eigenvalues, but once you're interested in eigenfunctions, you really need, I mean, the set of eigenvectors gives you a dense matrix out, so at some point you really have to fill your matrix, so the sparseness is really something of your initial representation, but even in the computational basis, like eigenfunctions are not sparsed in some sensible way. Okay, good, then, see you tomorrow.