Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simulation error: negative row index found #45

Open
diehoq opened this issue Apr 15, 2024 · 0 comments
Open

Simulation error: negative row index found #45

diehoq opened this issue Apr 15, 2024 · 0 comments

Comments

@diehoq
Copy link
Contributor

diehoq commented Apr 15, 2024

The following function performs modular inversion of a number:

    u = qrisp.QuantumFloat(n)
    u[:] = p
    v = qrisp.QuantumFloat(n)
    v[:] = x
    r = qrisp.QuantumModulus(2*p)
    r[:] = 0
    s = qrisp.QuantumModulus(2*p)
    s[:] = 1

    for _ in range(2*n):
        swap = qrisp.QuantumBool()
        swap[:] = True
        with v == 0 as v_is_zero:
            qrisp.cyclic_shift(r)
            v_is_zero.flip()
            swap.flip()
            with q_eval_expr_1(u, v):
                qrisp.swap(u, v)
                qrisp.swap(r, s)
                swap.flip()
            with q_eval_expr_2(u, v):
                v -= u
                s += r
            with qrisp.invert():
                qrisp.cyclic_shift(v)
            qrisp.cyclic_shift(r)
            with swap:
                qrisp.swap(u, v)
                qrisp.swap(r, s)
        swap.uncompute()
        
    larger = qrisp.QuantumBool()
    r.__class__ = qrisp.QuantumFloat
    larger[:] = r > p
    r.__class__ = qrisp.QuantumModulus

    with larger:
         r-=p 
         
    inv = qrisp.QuantumModulus(2*p) #maybe just use a quantum float
    inv[:] = p-r  
    return u,v,r,s,inv

It works perfectly when the input is classical:

t = qrisp.QuantumModulus(p)
t[:] = 2
to_montgomery(t, p)
print(t)
res = kaliski_swaps_check(t, p, p.bit_length())
qrisp.multi_measurement(res)

which produces the output {(1, 0, 1, 5, 4),1.0} , as expected. However when fetched with a superposition, the following code produces an error:

t = qrisp.QuantumModulus(p)
t[:] = 2
qrisp.h(t[1])
to_montgomery(t, p)
#print(t)
res = kaliski_swaps_check(t, p, p.bit_length())
qrisp.multi_measurement(res)

ERROR:

{ "name": "ValueError", "message": "negative row index found", "stack": "--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[66], line 1 ----> 1 qrisp.multi_measurement(res)

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\misc\utility.py:735, in multi_measurement(qv_list, shots, backend)
731 compiled_qc.measure(qubits, cl_reg)
733 # counts = execute(qs_temp, backend, basis_gates = basis_gates,
734 # noise_model = noise_model, shots = shots).result().get_counts()
--> 735 counts = backend.run(compiled_qc, shots)
736 counts = {k: counts[k] for k in sorted(counts)}
738 # Convert the labeling bistrings of counts into list of labels

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\default_backend.py:37, in DefaultBackend.run(self, qc, shots, token)
35 def run(self, qc, shots, token = ""):
---> 37 return run(qc, shots, token)

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\simulator.py:156, in run(qc, shots, token, iqs, insert_reset)
150 iqs.disentangle(qubit_indices[0])
152 # If the operation is unitary, we apply this unitary on to the required
153 # qubit indices
154 else:
--> 156 iqs.apply_operation(instr.op, qubit_indices)
158 # If all measurements have been performed, break
159 if measurement_counter == measurement_amount:

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\quantum_state.py:78, in QuantumState.apply_operation(self, operation, qubits)
75 unitary = operation.get_unitary()
77 # Apply the matrix
---> 78 entangled_factor.apply_matrix(unitary, qubits)
80 if entangled_factor.tensor_array.data.dtype == xp.dtype("O"):
81 return

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\tensor_factor.py:94, in TensorFactor.apply_matrix(self, matrix, qubits)
89 reshaped_tensor_array = self.tensor_array.reshape(
90 (matrix.shape[0], 2self.n // matrix.shape[0])
91 )
93 # Apply matrix
---> 94 self.tensor_array = tensordot(
95 matrix, reshaped_tensor_array, axes=(1, 0), contract_sparsity_threshold=0.05
96 ).reshape(2
self.n)

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\bi_arrays.py:1356, in tensordot(a, b, axes, contract_sparsity_threshold)
1352 mp_wrapper()
1354 return res
-> 1356 return a.contract(b, axes[0], axes[1])

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\bi_arrays.py:575, in SparseBiArray.contract(self, other, axes_self, axes_other)
573 res.thread.start()
574 else:
--> 575 mp_wrapper()
577 return res

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\bi_arrays.py:542, in SparseBiArray.contract..mp_wrapper()
537 def mp_wrapper():
538 # Build up sparse matrices
539 sr_matrix_self = self.build_sr_matrix(
540 (contraction_size, self.size // contraction_size), transpose=True
541 )
--> 542 sr_matrix_other = other.build_sr_matrix(
543 (contraction_size, other.size // contraction_size)
544 )
546 # Perform sparse matrix multiplication
548 res_sr_matrix = sparse_matrix_mult(sr_matrix_self, sr_matrix_other)

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\qrisp\simulator\bi_arrays.py:426, in SparseBiArray.build_sr_matrix(self, shape, transpose)
424 # Create sparse matrix
425 if not transpose:
--> 426 res = coo_array((self.data, (row, col)), shape=shape)
427 else:
428 res = coo_array((self.data, (col, row)), shape=shape[::-1])

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\scipy\sparse\_coo.py:204, in _coo_base.init(self, arg1, shape, dtype, copy)
201 if dtype is not None:
202 self.data = self.data.astype(dtype, copy=False)
--> 204 self._check()

File c:\Users\dpolimen\anaconda3\envs\venvABqiskitprovider\lib\site-packages\scipy\sparse\_coo.py:295, in _coo_base._check(self)
293 raise ValueError('column index exceeds matrix dimensions')
294 if self.row.min() < 0:
--> 295 raise ValueError('negative row index found')
296 if self.col.min() < 0:
297 raise ValueError('negative column index found')

ValueError: negative row index found"
}

Note that the function to_montgomery is just an in-place multiplication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant