@@ -138,93 +138,55 @@ end
138138# XOR between two Pauli different non-identity strings gives the third one. Ignores signs or any coefficient.
139139_bitpaulimultiply (pstr1:: PauliStringType , pstr2:: PauliStringType ) = pstr1 ⊻ pstr2
140140
141-
142-
143141# Shift to the right and truncate the first encoded Pauli string. Just a utility function.
144142_paulishiftright (pstr:: PauliStringType ) = pstr >> 2
145143
144+ # Computing bit shift index from Pauli site index
145+ # this is is the amount we need to shift to get to the target Pauli
146+ _bitshiftfromsiteindex (siteindex:: Integer ) = 2 * (siteindex - 1 )
147+
148+ # a site is represented by two bits
149+ # using Bits.jl implementation of mask
150+ _paulimask (:: Type{T} , n_sites) where T = mask (T, 2 * n_sites)
146151
152+ _pauliwindowmask (:: Type{T} , index1:: Integer , index2:: Integer ) where T = _paulimask (T, index2 - index1 + 1 ) << _bitshiftfromsiteindex (index1)
147153
148154# This function extracts the Pauli at position `index` from the integer Pauli string.
149155function _getpaulibits (pstr:: PauliStringType , index:: Integer )
150- # we need to shift the integer by 2 * (index - 1), then the first two bits are target Pauli
151- bitindex = 2 * (index - 1 )
152-
153- # shift to the right
154- shifted_pstr = (pstr >> bitindex)
155-
156- # AND with 3 (00000011) to get the first two bits
157- return shifted_pstr & typeof (pstr)(3 )
156+ return _getpaulibits (pstr, index, index)
158157end
159158
159+ # This function extracts the Pauli from `index1` to `index2`.
160+ function _getpaulibits (pstr:: PauliStringType , index1:: Integer , index2:: Integer )
161+ T = typeof (pstr)
160162
161- # Gets the bit at index `bitindex` in the integer Pauli string.
162- function _getbit (pauli:: Integer , bitindex:: Integer )
163- # return integer with ...000[bit].
163+ bitindex = _bitshiftfromsiteindex (index1)
164164
165- # shift by bitindex
166- shifted_pauli = (pauli >> bitindex)
165+ # shift to the right
166+ shifted_pstr = (pstr >> bitindex)
167167
168- # AND with 1 to get first bit
169- return shifted_pauli & typeof (pauli)(1 )
168+ # creates all 1s mask of length n bits
169+ # AND to get the first n bits
170+ return shifted_pstr & _paulimask (T, index2 - index1 + 1 )
170171end
171172
172173
173174# This function sets the Pauli at position `index` in the integer Pauli string to `target_pauli`.
174175function _setpaulibits (pstr:: PauliStringType , target_pauli:: PauliType , index:: Integer )
175- # we need to shift the integer by 2 * (index - 1), then the first two bits are target Pauli
176- bitindex = 2 * (index - 1 )
177-
178- # read bits of the pauli
179- b1 = _getbit (target_pauli, 0 )
180- b2 = _getbit (target_pauli, 1 )
181-
182- # insert them into the pstr
183- pstr = _setbit (pstr, b1, bitindex)
184- pstr = _setbit (pstr, b2, bitindex + 1 )
185- return pstr
176+ return _setpaulibits (pstr, target_pauli, index, index)
186177end
187178
188179
189- # Sets a bit at index `bitindex` in the integer Pauli string to the value of `target_bit`.
190- function _setbit (pstr:: PauliStringType , target_bit:: Integer , bitindex:: Integer )
191- # set bit at bitindex to bit
192-
193- if target_bit == true # set to one
194- pstr = _setbittoone (pstr, bitindex)
195- else
196- pstr = _setbittozero (pstr, bitindex)
197- end
198- return pstr
199- end
200-
201-
202- # Sets a bit at index `bitindex` in the integer Pauli string to 1.
203- function _setbittoone (pstr:: Integer , bitindex:: Integer )
204- # set bit at bitindex to 1
205-
206- # shift ...00100... to bitindex
207- shifted_onebit = (typeof (pstr)(1 ) << bitindex)
208-
209- # OR with pauli string to make sure that that bit is 1
210- return pstr | shifted_onebit
211- end
212-
213-
214-
215- # Sets a bit at index `bitindex` in the integer Pauli string to 0.
216- function _setbittozero (pstr:: Integer , bitindex:: Integer )
217- # set bit at bitindex to 0
180+ # This function sets the Pauli from `index1` to `index2` to `target_pstr`.
181+ function _setpaulibits (pstr:: PauliStringType , target_pstr:: PauliStringType , index1:: Integer , index2:: Integer )
182+ T = typeof (pstr)
218183
219- # flip all bits
220- pstr = ~ pstr
184+ bitindex = _bitshiftfromsiteindex (index1)
221185
222- # set target bit to one
223- pstr = _setbittoone (pstr, bitindex)
186+ window_mask = _pauliwindowmask (T, index1, index2)
224187
225- # flip all bits back, only the target bit is 0
226- pstr = ~ pstr
227- return pstr
188+ # set bits to target pstr
189+ return (pstr & ~ window_mask) | (T (target_pstr) << bitindex)
228190end
229191
230192
@@ -234,10 +196,10 @@ end
234196
235197 # length is the number of bits in the integer
236198 n_bits = min (bitsize (pstr), 2_048 ) # for max 1024 qubits.
237- mask = zero (pstr )
199+ mask = zero (T )
238200 for ii in 0 : (n_bits- 1 )
239201 if ii % 2 == 0
240- mask = _setbittoone ( mask, ii)
202+ mask = mask | ( T ( 1 ) << ii)
241203 end
242204 end
243205 return mask
0 commit comments