# QN conserving MPS

**URL:** <https://itensor.discourse.group/t/qn-conserving-mps/471>\
**Category:** ITensor Julia Questions\
**Created:** [October 16, 2022, 5:54pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471 "2022-10-16T17:54:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![JoexGibbs](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/joexgibbs/32/155_2.png) [@JoexGibbs](https://itensor.discourse.group/u/JoexGibbs)\
**Post date:** [October 16, 2022, 5:54pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471/1 "2022-10-16T17:54:49Z")

</div>

I have two questions about ITensor’s quantum number conserving MPS.

1. I would like to generate several MPS from a particular QN subspace, however when I run randomMPS I keep getting the same MPS outputted e.g.

```auto
using ITensors
N = 5

sites = siteinds("Qubit", N; conserve_number=true)
state = [isodd(n) ? "1" : "0" for n=1:N]

psi0 = randomMPS(sites, state)
psi1 = randomMPS(sites, state)

println(inner(psi0', psi1))

```

This produces an output of exactly 1.0, signifying psi0 = psi1.  
How do I generate different states from the subspace?

1. Is there a reference that describes the method used to sample from a particular subspace?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [October 16, 2022, 8:18pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471/2 "2022-10-16T20:18:56Z")

</div>

It’s a good question. A sort of non-intuitive aspect of the `randomMPS` function is that by default it just makes `randomMPS` of bond dimension (or `maxdim`) of \chi=1. For non-QN-conserving MPS these will be be random, just the product of random vectors, but for the QN conserving case they will always be the same.

So to get different random MPS while preserving QNs, call the `randomMPS` with a `linkdims` argument that is greater than one, like this:

```auto
 psi0 = randomMPS(sites, state; linkdims=2)

```

or some other value of `linkdims` that is as large as you like. You can inspect the dimensions of the bond or link indices afterward by doing:

```auto
@show linkdims(psi0)

```

Finally, the current method of making random QN-conserving MPS is to:

1. make a product state corresponding to the `state` array that is passed into the function
2. act with a brick-wall circuit of random unitaries on it
3. truncate the result to the requested bond dimension

The random unitaries are not totally random, but are chosen from an ensemble that conserves the QNs defined by the site indices.

In the future, I plan to improve this algorithm by switching the circuit not to be brick-wall but another layout. The drawback of the brick wall circuit currently used is that the randomMPS have connected correlation functions that go exactly to zero beyond a certain spatial distance, rather than decaying exponentially to all distances. But they are still useful enough for purposes like initializing calculations.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [October 16, 2022, 8:31pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471/3 "2022-10-16T20:31:21Z")

</div>

P.S. the extra prime (`'`) in the part of your code involving `inner` is not needed. The MPS have the same site indices so should be contracted by calling

```auto
inner(psi0,psi1)

```

If you use `inner(psi0',psi1)` you’ll notice it still works but ITensor prints out a very long warning. This is because the code currently figures out what you mean and changes the indices to match for you, but this behavior is deprecated and we plan to remove it in the future.

---

<div class="post-metadata">

**Author:** ![JoexGibbs](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/joexgibbs/32/155_2.png) [@JoexGibbs](https://itensor.discourse.group/u/JoexGibbs)\
**Post date:** [October 17, 2022, 6:21pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471/4 "2022-10-17T18:21:47Z")

</div>

This makes a lot of sense, however are there not multiple \chi=1 states that could be randomly chosen aka the computational basis states spanning the basis?

Regarding the choice of layout, if the current brick wall circuit as you say have correlation functions that incorrectly go to zero, does that mean currently that randomMPS for conserve\_number=true is not able to fully sample from the whole subspace even for large circuit depths?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [October 17, 2022, 7:12pm UTC](https://itensor.discourse.group/t/qn-conserving-mps/471/5 "2022-10-17T19:12:00Z")

</div>

While there are multiple \chi=1 states possible, the one used is the one specified by the `state` array passed to the function. (I had tried once to just automate this part by letting the user pass a single QN, being the total QN sector desired, but I found some surprising corner cases where it was quite difficult to automatically determine a product state with the requested QN!)

I think what you said is technically correct about the current approach not sampling from the whole subspace (note that this only applies to the case with QNs – the dense case uses a better algorithm). However this should become less and less of an issue as you increase the `linkdims` parameter to larger values, because then the circuit depth used is also larger. Another way to fix this issue would be to repeatedly apply a brick wall circuit of fixed depth a few times and repeatedly truncate back to the desired linkdim value.

How much of an issue these limitations are really depends on the purpose you need a random MPS for, though. If it’s just for initializing a calculation the current approach may be perfectly fine. On the other hand if it’s for something like studying statistical distributions of random MPS then one would need to ensure that the randomization procedure is really correctly sampling the MPS.
