parameters: (hi, mat, acting_on)
return_statement: return mat_sorted, acting_on_sorted
docstring: Reorders the matrix resulting from a kronecker product of several
      operators in such a way to sort acting_on.
  
      A conceptual example is the following:
      if `mat = Â ⊗ B̂ ⊗ Ĉ` and `acting_on = [[2],[1],[3]`
      you will get `result = B̂ ⊗ Â ⊗ Ĉ, [[1], [2], [3]].
  
      However, essentially, A,B,C represent some operators acting on
      thei sub-space acting_on[1], [2] and [3] of the hilbert space.
  
      This function also handles any possible set of values in acting_on.
  
      The inner logic uses the Fock.all_states(), number_to_state and
      state_to_number to perform the re-ordering.
docstring_summary: Reorders the matrix resulting from a kronecker product of several
      operators in such a way to sort acting_on.
docstring_tokens: Reorders the matrix resulting from a kronecker product of several operators in such a way to sort acting_on .
function: def _reorder_kronecker_product(hi, mat, acting_on):
      """
      Reorders the matrix resulting from a kronecker product of several
      operators in such a way to sort acting_on.
  
      A conceptual example is the following:
      if `mat = Â ⊗ B̂ ⊗ Ĉ` and `acting_on = [[2],[1],[3]`
      you will get `result = B̂ ⊗ Â ⊗ Ĉ, [[1], [2], [3]].
  
      However, essentially, A,B,C represent some operators acting on
      thei sub-space acting_on[1], [2] and [3] of the hilbert space.
  
      This function also handles any possible set of values in acting_on.
  
      The inner logic uses the Fock.all_states(), number_to_state and
      state_to_number to perform the re-ordering.
      """
      acting_on_sorted = np.sort(acting_on)
      if np.array_equal(acting_on_sorted, acting_on):
          return mat, acting_on
  
      # could write custom binary <-> int logic instead of using Fock...
      # Since i need to work with bit-strings (where instead of bits i
      # have integers, in order to support arbitrary size spaces) this
      # is exactly what hilbert.to_number() and viceversa do.
  
      # target ordering binary representation
      hi_subspace = Fock(hi.shape[acting_on_sorted[0]] - 1)
      for site in acting_on_sorted[1:]:
          hi_subspace = Fock(hi.shape[site] - 1) * hi_subspace
  
      # find how to map target ordering back to unordered
      acting_on_unsorted_ids = np.zeros(len(acting_on), dtype=np.intp)
      for (i, site) in enumerate(acting_on):
          acting_on_unsorted_ids[i] = np.argmax(site == acting_on_sorted)
  
      # now it is valid that
      # acting_on_sorted == acting_on[acting_on_unsorted_ids]
  
      # generate n-bit strings in the target ordering
      v = hi_subspace.all_states()
  
      # convert them to origin (unordered) ordering
      v_unsorted = v[:, acting_on_unsorted_ids]
      # convert the unordered bit-strings to numbers in the target space.
      n_unsorted = hi_subspace.states_to_numbers(v_unsorted)
  
      # reorder the matrix
      mat_sorted = mat[n_unsorted, :][:, n_unsorted]
  
      return mat_sorted, acting_on_sorted
function_tokens: def _reorder_kronecker_product ( hi , mat , acting_on ) : acting_on_sorted = np . sort ( acting_on ) if np . array_equal ( acting_on_sorted , acting_on ) : return mat , acting_on # could write custom binary <-> int logic instead of using Fock... # Since i need to work with bit-strings (where instead of bits i # have integers, in order to support arbitrary size spaces) this # is exactly what hilbert.to_number() and viceversa do. # target ordering binary representation hi_subspace = Fock ( hi . shape [ acting_on_sorted [ 0 ] ] - 1 ) for site in acting_on_sorted [ 1 : ] : hi_subspace = Fock ( hi . shape [ site ] - 1 ) * hi_subspace # find how to map target ordering back to unordered acting_on_unsorted_ids = np . zeros ( len ( acting_on ) , dtype = np . intp ) for ( i , site ) in enumerate ( acting_on ) : acting_on_unsorted_ids [ i ] = np . argmax ( site == acting_on_sorted ) # now it is valid that # acting_on_sorted == acting_on[acting_on_unsorted_ids] # generate n-bit strings in the target ordering v = hi_subspace . all_states ( ) # convert them to origin (unordered) ordering v_unsorted = v [ : , acting_on_unsorted_ids ] # convert the unordered bit-strings to numbers in the target space. n_unsorted = hi_subspace . states_to_numbers ( v_unsorted ) # reorder the matrix mat_sorted = mat [ n_unsorted , : ] [ : , n_unsorted ] return mat_sorted , acting_on_sorted