3232 from qualtran .resource_counting import BloqCountT , SympySymbolAllocator
3333
3434
35- def get_qroam_cost (
35+ def qroam_cost (x , data_size : int , bitsize : int , adjoint : bool = False ):
36+ # See appendix B of https://arxiv.org/pdf/1902.02134
37+ if adjoint :
38+ return data_size / x + x
39+ else :
40+ return data_size / x + bitsize * (x - 1 )
41+
42+
43+ def qroam_cost_dirty (x , data_size : int , bitsize : int , adjoint : bool = False ):
44+ # See appendix A of https://arxiv.org/pdf/1902.02134
45+ if adjoint :
46+ return data_size / x + x
47+ else :
48+ return 2 * (data_size / x - 1 ) + 4 * bitsize * (x - 1 )
49+
50+
51+ def get_optimal_log_block_size_clean_ancilla (
52+ data_size : int , bitsize : int , adjoint : bool = False , qroam_block_size : Optional [int ] = None
53+ ) -> int :
54+ if qroam_block_size is None :
55+ if adjoint :
56+ log_blk = 0.5 * np .log2 (data_size )
57+ qroam_block_size = 2 ** log_blk
58+ else :
59+ log_blk = 0.5 * np .log2 (data_size / bitsize )
60+ assert log_blk >= 0
61+ qroam_block_size = 2 ** log_blk
62+ k = np .log2 (qroam_block_size )
63+ k_int = np .array ([np .floor (k ), np .ceil (k )])
64+ return int (k_int [np .argmin (qroam_cost (2 ** k_int , data_size , bitsize , adjoint ))])
65+
66+
67+ def get_qroam_cost_clean_ancilla (
3668 data_size : int , bitsize : int , adjoint : bool = False , qroam_block_size : Optional [int ] = None
3769) -> int :
3870 """This gives the optimal k and minimum cost for a QROM over L values of size M.
@@ -51,22 +83,8 @@ def get_qroam_cost(
5183 """
5284 if qroam_block_size == 1 :
5385 return data_size - 1
54- if adjoint :
55- if qroam_block_size is None :
56- log_blk = 0.5 * np .log2 (data_size )
57- qroam_block_size = 2 ** log_blk
58- value = lambda x : data_size / x + x
59- else :
60- if qroam_block_size is None :
61- log_blk = 0.5 * np .log2 (data_size / bitsize )
62- assert log_blk >= 0
63- qroam_block_size = 2 ** log_blk
64- value = lambda x : data_size / x + bitsize * (x - 1 )
65- k = np .log2 (qroam_block_size )
66- k_int = np .array ([np .floor (k ), np .ceil (k )])
67- k_opt = k_int [np .argmin (value (2 ** k_int ))]
68- val_opt = np .ceil (value (2 ** k_opt ))
69- return int (val_opt )
86+ k_opt = get_optimal_log_block_size_clean_ancilla (data_size , bitsize , adjoint , qroam_block_size )
87+ return int (np .ceil (qroam_cost (2 ** k_opt , data_size , bitsize , adjoint )))
7088
7189
7290@frozen
@@ -96,7 +114,7 @@ def signature(self) -> Signature:
96114 return Signature .build (sel = (self .data_size - 1 ).bit_length (), trg = self .target_bitsize )
97115
98116 def build_call_graph (self , ssa : 'SympySymbolAllocator' ) -> Set ['BloqCountT' ]:
99- cost = get_qroam_cost (
117+ cost = get_qroam_cost_clean_ancilla (
100118 self .data_size ,
101119 self .target_bitsize ,
102120 adjoint = self .is_adjoint ,
0 commit comments