classiq 0.36.0__py3-none-any.whl → 0.37.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +1 -0
- classiq/_internals/api_wrapper.py +24 -6
- classiq/_internals/authentication/device.py +6 -3
- classiq/_internals/authentication/token_manager.py +21 -5
- classiq/_internals/client.py +7 -2
- classiq/_internals/config.py +12 -0
- classiq/_internals/host_checker.py +1 -1
- classiq/_internals/jobs.py +3 -1
- classiq/_internals/type_validation.py +3 -6
- classiq/analyzer/analyzer.py +1 -0
- classiq/analyzer/rb.py +3 -5
- classiq/applications_model_constructors/chemistry_model_constructor.py +42 -67
- classiq/applications_model_constructors/grover_model_constructor.py +27 -18
- classiq/exceptions.py +5 -0
- classiq/execution/jobs.py +13 -4
- classiq/executor.py +3 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +0 -6
- classiq/interface/analyzer/result.py +0 -4
- classiq/interface/backend/backend_preferences.py +2 -2
- classiq/interface/backend/quantum_backend_providers.py +1 -1
- classiq/interface/execution/resource_estimator.py +7 -0
- classiq/interface/execution/result.py +5 -0
- classiq/interface/executor/register_initialization.py +3 -1
- classiq/interface/executor/vqe_result.py +1 -0
- classiq/interface/generator/ansatz_library.py +3 -3
- classiq/interface/generator/arith/argument_utils.py +4 -4
- classiq/interface/generator/arith/arithmetic.py +4 -2
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +11 -5
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
- classiq/interface/generator/arith/arithmetic_operations.py +7 -0
- classiq/interface/generator/arith/arithmetic_param_getters.py +97 -16
- classiq/interface/generator/arith/arithmetic_result_builder.py +13 -3
- classiq/interface/generator/arith/binary_ops.py +8 -10
- classiq/interface/generator/arith/extremum_operations.py +2 -2
- classiq/interface/generator/arith/number_utils.py +20 -23
- classiq/interface/generator/arith/register_user_input.py +3 -1
- classiq/interface/generator/arith/unary_ops.py +9 -13
- classiq/interface/generator/expressions/atomic_expression_functions.py +2 -0
- classiq/interface/generator/expressions/expression.py +7 -2
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +22 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -12
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +63 -3
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +143 -17
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +41 -16
- classiq/interface/generator/functions/native_function_definition.py +3 -3
- classiq/interface/generator/model/constraints.py +3 -3
- classiq/interface/generator/model/preferences/preferences.py +13 -9
- classiq/interface/generator/noise_properties.py +5 -5
- classiq/interface/generator/qpe.py +5 -5
- classiq/interface/generator/quantum_function_call.py +5 -3
- classiq/interface/generator/randomized_benchmarking.py +5 -3
- classiq/interface/generator/visitor.py +1 -2
- classiq/interface/hardware.py +1 -1
- classiq/interface/helpers/custom_pydantic_types.py +6 -0
- classiq/interface/model/{modular_addition_operation.py → inplace_binary_operation.py} +16 -2
- classiq/interface/model/native_function_definition.py +2 -24
- classiq/interface/model/operator_synthesis_data.py +6 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +8 -4
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +9 -5
- classiq/interface/model/quantum_expressions/control_state.py +38 -0
- classiq/interface/model/quantum_expressions/quantum_expression.py +21 -11
- classiq/interface/model/quantum_function_call.py +81 -6
- classiq/interface/model/quantum_function_declaration.py +3 -3
- classiq/interface/model/quantum_if_operation.py +95 -0
- classiq/interface/model/resolvers/function_call_resolver.py +1 -1
- classiq/interface/model/validations/handles_validator.py +42 -15
- classiq/interface/server/routes.py +10 -6
- classiq/model/function_handler.pyi +86 -86
- classiq/model/model.py +1 -0
- classiq/qmod/__init__.py +6 -1
- classiq/qmod/builtins/__init__.py +13 -1
- classiq/qmod/builtins/classical_execution_primitives.py +109 -0
- classiq/qmod/builtins/classical_functions.py +68 -0
- classiq/qmod/builtins/functions.py +88 -18
- classiq/qmod/builtins/operations.py +60 -35
- classiq/qmod/classical_function.py +40 -0
- classiq/qmod/declaration_inferrer.py +5 -2
- classiq/qmod/qmod_variable.py +17 -10
- classiq/qmod/quantum_callable.py +24 -3
- classiq/qmod/quantum_expandable.py +131 -21
- classiq/qmod/quantum_function.py +12 -2
- classiq/qmod/symbolic.py +182 -107
- classiq/qmod/symbolic_expr.py +11 -10
- classiq/qmod/symbolic_type.py +8 -0
- classiq/quantum_functions/decorators.py +2 -4
- classiq/quantum_functions/function_library.py +1 -0
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/METADATA +1 -1
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/RECORD +90 -82
- classiq/interface/model/local_variable_declaration.py +0 -7
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/WHEEL +0 -0
@@ -57,6 +57,7 @@ def get_params(
|
|
57
57
|
*,
|
58
58
|
node_id: str,
|
59
59
|
args: List[RegisterOrFloat],
|
60
|
+
machine_precision: int,
|
60
61
|
output_size: Optional[int] = None,
|
61
62
|
inplace_arg: Optional[str] = None,
|
62
63
|
target: Optional[RegisterArithmeticInfo] = None
|
@@ -64,35 +65,52 @@ def get_params(
|
|
64
65
|
operation = id2op(node_id)
|
65
66
|
if target and not operation_allows_target(operation):
|
66
67
|
raise ClassiqArithmeticError(_TARGET_ERROR_MESSAGE)
|
67
|
-
validate_operation_arg_types(operation, args)
|
68
|
+
validate_operation_arg_types(operation, args, machine_precision)
|
68
69
|
return params_getter_map[operation](
|
69
|
-
*args,
|
70
|
+
*args,
|
71
|
+
machine_precision=machine_precision,
|
72
|
+
output_size=output_size,
|
73
|
+
inplace_arg=inplace_arg,
|
74
|
+
target=target,
|
70
75
|
)
|
71
76
|
|
72
77
|
|
73
78
|
def or_params_getter(
|
74
79
|
left_arg: RegisterOrInt,
|
75
80
|
right_arg: RegisterOrInt,
|
81
|
+
machine_precision: int,
|
76
82
|
output_size: Optional[int] = None,
|
77
83
|
inplace_arg: Optional[str] = None,
|
78
84
|
target: Optional[RegisterArithmeticInfo] = None,
|
79
85
|
) -> ArithmeticOperationParams:
|
80
|
-
return BitwiseOr(
|
86
|
+
return BitwiseOr(
|
87
|
+
left_arg=left_arg,
|
88
|
+
right_arg=right_arg,
|
89
|
+
output_size=output_size,
|
90
|
+
machine_precision=machine_precision,
|
91
|
+
)
|
81
92
|
|
82
93
|
|
83
94
|
def and_params_getter(
|
84
95
|
left_arg: RegisterOrInt,
|
85
96
|
right_arg: RegisterOrInt,
|
97
|
+
machine_precision: int,
|
86
98
|
output_size: Optional[int] = None,
|
87
99
|
inplace_arg: Optional[str] = None,
|
88
100
|
target: Optional[RegisterArithmeticInfo] = None,
|
89
101
|
) -> ArithmeticOperationParams:
|
90
|
-
return BitwiseAnd(
|
102
|
+
return BitwiseAnd(
|
103
|
+
left_arg=left_arg,
|
104
|
+
right_arg=right_arg,
|
105
|
+
output_size=output_size,
|
106
|
+
machine_precision=machine_precision,
|
107
|
+
)
|
91
108
|
|
92
109
|
|
93
110
|
def xor_params_getter(
|
94
111
|
left_arg: RegisterOrInt,
|
95
112
|
right_arg: RegisterOrInt,
|
113
|
+
machine_precision: int,
|
96
114
|
output_size: Optional[int] = None,
|
97
115
|
inplace_arg: Optional[str] = None,
|
98
116
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -100,6 +118,7 @@ def xor_params_getter(
|
|
100
118
|
return BitwiseXor(
|
101
119
|
left_arg=left_arg,
|
102
120
|
right_arg=right_arg,
|
121
|
+
machine_precision=machine_precision,
|
103
122
|
output_size=output_size,
|
104
123
|
inplace_arg=inplace_arg,
|
105
124
|
)
|
@@ -107,12 +126,14 @@ def xor_params_getter(
|
|
107
126
|
|
108
127
|
def invert_params_getter(
|
109
128
|
arg: RegisterOrInt,
|
129
|
+
machine_precision: int,
|
110
130
|
output_size: Optional[int] = None,
|
111
131
|
inplace_arg: Optional[str] = None,
|
112
132
|
target: Optional[RegisterArithmeticInfo] = None,
|
113
133
|
) -> ArithmeticOperationParams:
|
114
134
|
return BitwiseInvert(
|
115
135
|
arg=arg,
|
136
|
+
machine_precision=machine_precision,
|
116
137
|
output_size=output_size,
|
117
138
|
inplace=inplace_arg is not None,
|
118
139
|
)
|
@@ -120,12 +141,14 @@ def invert_params_getter(
|
|
120
141
|
|
121
142
|
def usub_params_getter(
|
122
143
|
arg: RegisterOrInt,
|
144
|
+
machine_precision: int,
|
123
145
|
output_size: Optional[int] = None,
|
124
146
|
inplace_arg: Optional[str] = None,
|
125
147
|
target: Optional[RegisterArithmeticInfo] = None,
|
126
148
|
) -> ArithmeticOperationParams:
|
127
149
|
return Negation(
|
128
150
|
arg=arg,
|
151
|
+
machine_precision=machine_precision,
|
129
152
|
output_size=output_size,
|
130
153
|
inplace=inplace_arg is not None,
|
131
154
|
)
|
@@ -134,6 +157,7 @@ def usub_params_getter(
|
|
134
157
|
def adder_params_getter(
|
135
158
|
left_arg: RegisterOrFloat,
|
136
159
|
right_arg: RegisterOrFloat,
|
160
|
+
machine_precision: int,
|
137
161
|
output_size: Optional[int] = None,
|
138
162
|
inplace_arg: Optional[str] = None,
|
139
163
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -141,6 +165,7 @@ def adder_params_getter(
|
|
141
165
|
return Adder(
|
142
166
|
left_arg=left_arg,
|
143
167
|
right_arg=right_arg,
|
168
|
+
machine_precision=machine_precision,
|
144
169
|
inplace_arg=inplace_arg,
|
145
170
|
output_size=output_size,
|
146
171
|
)
|
@@ -149,46 +174,71 @@ def adder_params_getter(
|
|
149
174
|
def multiplier_params_getter(
|
150
175
|
left_arg: RegisterOrFloat,
|
151
176
|
right_arg: RegisterOrFloat,
|
177
|
+
machine_precision: int,
|
152
178
|
output_size: Optional[int] = None,
|
153
179
|
inplace_arg: Optional[str] = None,
|
154
180
|
target: Optional[RegisterArithmeticInfo] = None,
|
155
181
|
) -> ArithmeticOperationParams:
|
156
|
-
return Multiplier(
|
182
|
+
return Multiplier(
|
183
|
+
left_arg=left_arg,
|
184
|
+
right_arg=right_arg,
|
185
|
+
machine_precision=machine_precision,
|
186
|
+
output_size=output_size,
|
187
|
+
)
|
157
188
|
|
158
189
|
|
159
190
|
def power_params_getter(
|
160
191
|
left_arg: RegisterArithmeticInfo,
|
161
192
|
right_arg: int,
|
193
|
+
machine_precision: int,
|
162
194
|
output_size: Optional[int] = None,
|
163
195
|
inplace_arg: Optional[str] = None,
|
164
196
|
target: Optional[RegisterArithmeticInfo] = None,
|
165
197
|
) -> ArithmeticOperationParams:
|
166
|
-
return Power(
|
198
|
+
return Power(
|
199
|
+
left_arg=left_arg,
|
200
|
+
right_arg=right_arg,
|
201
|
+
machine_precision=machine_precision,
|
202
|
+
output_size=output_size,
|
203
|
+
)
|
167
204
|
|
168
205
|
|
169
206
|
def min_params_getter(
|
170
207
|
left_arg: RegisterOrFloat,
|
171
208
|
right_arg: RegisterOrFloat,
|
209
|
+
machine_precision: int,
|
172
210
|
output_size: Optional[int] = None,
|
173
211
|
inplace_arg: Optional[str] = None,
|
174
212
|
target: Optional[RegisterArithmeticInfo] = None,
|
175
213
|
) -> ArithmeticOperationParams:
|
176
|
-
return Min(
|
214
|
+
return Min(
|
215
|
+
left_arg=left_arg,
|
216
|
+
right_arg=right_arg,
|
217
|
+
machine_precision=machine_precision,
|
218
|
+
output_size=output_size,
|
219
|
+
)
|
177
220
|
|
178
221
|
|
179
222
|
def max_params_getter(
|
180
223
|
left_arg: RegisterOrFloat,
|
181
224
|
right_arg: RegisterOrFloat,
|
225
|
+
machine_precision: int,
|
182
226
|
output_size: Optional[int] = None,
|
183
227
|
inplace_arg: Optional[str] = None,
|
184
228
|
target: Optional[RegisterArithmeticInfo] = None,
|
185
229
|
) -> ArithmeticOperationParams:
|
186
|
-
return Max(
|
230
|
+
return Max(
|
231
|
+
left_arg=left_arg,
|
232
|
+
right_arg=right_arg,
|
233
|
+
machine_precision=machine_precision,
|
234
|
+
output_size=output_size,
|
235
|
+
)
|
187
236
|
|
188
237
|
|
189
238
|
def sub_params_getter(
|
190
239
|
left_arg: RegisterOrFloat,
|
191
240
|
right_arg: RegisterOrFloat,
|
241
|
+
machine_precision: int,
|
192
242
|
output_size: Optional[int] = None,
|
193
243
|
inplace_arg: Optional[str] = None,
|
194
244
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -196,6 +246,7 @@ def sub_params_getter(
|
|
196
246
|
return Subtractor(
|
197
247
|
left_arg=left_arg,
|
198
248
|
right_arg=right_arg,
|
249
|
+
machine_precision=machine_precision,
|
199
250
|
inplace_arg=inplace_arg,
|
200
251
|
output_size=output_size,
|
201
252
|
)
|
@@ -204,84 +255,105 @@ def sub_params_getter(
|
|
204
255
|
def equal_params_getter(
|
205
256
|
left_arg: RegisterOrFloat,
|
206
257
|
right_arg: RegisterOrFloat,
|
258
|
+
machine_precision: int,
|
207
259
|
output_size: Optional[int] = None,
|
208
260
|
inplace_arg: Optional[str] = None,
|
209
261
|
target: Optional[RegisterArithmeticInfo] = None,
|
210
262
|
) -> ArithmeticOperationParams:
|
211
|
-
return Equal(
|
263
|
+
return Equal(
|
264
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
265
|
+
)
|
212
266
|
|
213
267
|
|
214
268
|
def not_equal_params_getter(
|
215
269
|
left_arg: RegisterOrFloat,
|
216
270
|
right_arg: RegisterOrFloat,
|
271
|
+
machine_precision: int,
|
217
272
|
output_size: Optional[int] = None,
|
218
273
|
inplace_arg: Optional[str] = None,
|
219
274
|
target: Optional[RegisterArithmeticInfo] = None,
|
220
275
|
) -> ArithmeticOperationParams:
|
221
|
-
return NotEqual(
|
276
|
+
return NotEqual(
|
277
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
278
|
+
)
|
222
279
|
|
223
280
|
|
224
281
|
def greater_than_params_getter(
|
225
282
|
left_arg: RegisterOrFloat,
|
226
283
|
right_arg: RegisterOrFloat,
|
284
|
+
machine_precision: int,
|
227
285
|
output_size: Optional[int] = None,
|
228
286
|
inplace_arg: Optional[str] = None,
|
229
287
|
target: Optional[RegisterArithmeticInfo] = None,
|
230
288
|
) -> ArithmeticOperationParams:
|
231
|
-
return GreaterThan(
|
289
|
+
return GreaterThan(
|
290
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
291
|
+
)
|
232
292
|
|
233
293
|
|
234
294
|
def greater_equal_params_getter(
|
235
295
|
left_arg: RegisterOrFloat,
|
236
296
|
right_arg: RegisterOrFloat,
|
297
|
+
machine_precision: int,
|
237
298
|
output_size: Optional[int] = None,
|
238
299
|
inplace_arg: Optional[str] = None,
|
239
300
|
target: Optional[RegisterArithmeticInfo] = None,
|
240
301
|
) -> ArithmeticOperationParams:
|
241
|
-
return GreaterEqual(
|
302
|
+
return GreaterEqual(
|
303
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
304
|
+
)
|
242
305
|
|
243
306
|
|
244
307
|
def less_than_params_getter(
|
245
308
|
left_arg: RegisterOrFloat,
|
246
309
|
right_arg: RegisterOrFloat,
|
310
|
+
machine_precision: int,
|
247
311
|
output_size: Optional[int] = None,
|
248
312
|
inplace_arg: Optional[str] = None,
|
249
313
|
target: Optional[RegisterArithmeticInfo] = None,
|
250
314
|
) -> ArithmeticOperationParams:
|
251
|
-
return LessThan(
|
315
|
+
return LessThan(
|
316
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
317
|
+
)
|
252
318
|
|
253
319
|
|
254
320
|
def less_equal_params_getter(
|
255
321
|
left_arg: RegisterOrFloat,
|
256
322
|
right_arg: RegisterOrFloat,
|
323
|
+
machine_precision: int,
|
257
324
|
output_size: Optional[int] = None,
|
258
325
|
inplace_arg: Optional[str] = None,
|
259
326
|
target: Optional[RegisterArithmeticInfo] = None,
|
260
327
|
) -> ArithmeticOperationParams:
|
261
|
-
return LessEqual(
|
328
|
+
return LessEqual(
|
329
|
+
left_arg=left_arg, right_arg=right_arg, machine_precision=machine_precision
|
330
|
+
)
|
262
331
|
|
263
332
|
|
264
333
|
def logical_and_params_getter(
|
265
334
|
*arg: List[RegisterOrFloat],
|
335
|
+
machine_precision: int,
|
266
336
|
output_size: Optional[int] = None,
|
267
337
|
inplace_arg: Optional[str] = None,
|
268
338
|
target: Optional[RegisterArithmeticInfo] = None
|
269
339
|
) -> ArithmeticOperationParams:
|
270
|
-
return LogicalAnd(args=arg, target=target)
|
340
|
+
return LogicalAnd(args=arg, target=target, machine_precision=machine_precision)
|
271
341
|
|
272
342
|
|
273
343
|
def logical_or_params_getter(
|
274
344
|
*arg: List[RegisterOrFloat],
|
345
|
+
machine_precision: int,
|
275
346
|
output_size: Optional[int] = None,
|
276
347
|
inplace_arg: Optional[str] = None,
|
277
348
|
target: Optional[RegisterArithmeticInfo] = None
|
278
349
|
) -> ArithmeticOperationParams:
|
279
|
-
return LogicalOr(args=arg, target=target)
|
350
|
+
return LogicalOr(args=arg, target=target, machine_precision=machine_precision)
|
280
351
|
|
281
352
|
|
282
353
|
def lshift_params_getter(
|
283
354
|
left_arg: RegisterArithmeticInfo,
|
284
355
|
right_arg: int,
|
356
|
+
machine_precision: int,
|
285
357
|
output_size: Optional[int] = None,
|
286
358
|
inplace_arg: Optional[str] = None,
|
287
359
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -289,6 +361,7 @@ def lshift_params_getter(
|
|
289
361
|
return LShift(
|
290
362
|
left_arg=left_arg,
|
291
363
|
right_arg=right_arg,
|
364
|
+
machine_precision=machine_precision,
|
292
365
|
inplace_arg=inplace_arg,
|
293
366
|
output_size=output_size,
|
294
367
|
)
|
@@ -297,6 +370,7 @@ def lshift_params_getter(
|
|
297
370
|
def rshift_params_getter(
|
298
371
|
left_arg: RegisterArithmeticInfo,
|
299
372
|
right_arg: int,
|
373
|
+
machine_precision: int,
|
300
374
|
output_size: Optional[int] = None,
|
301
375
|
inplace_arg: Optional[str] = None,
|
302
376
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -304,6 +378,7 @@ def rshift_params_getter(
|
|
304
378
|
return RShift(
|
305
379
|
left_arg=left_arg,
|
306
380
|
right_arg=right_arg,
|
381
|
+
machine_precision=machine_precision,
|
307
382
|
inplace_arg=inplace_arg,
|
308
383
|
output_size=output_size,
|
309
384
|
)
|
@@ -312,6 +387,7 @@ def rshift_params_getter(
|
|
312
387
|
def clshift_params_getter(
|
313
388
|
left_arg: RegisterArithmeticInfo,
|
314
389
|
right_arg: int,
|
390
|
+
machine_precision: int,
|
315
391
|
output_size: Optional[int] = None,
|
316
392
|
inplace_arg: Optional[str] = None,
|
317
393
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -319,6 +395,7 @@ def clshift_params_getter(
|
|
319
395
|
return CyclicShift(
|
320
396
|
left_arg=left_arg,
|
321
397
|
right_arg=-right_arg,
|
398
|
+
machine_precision=machine_precision,
|
322
399
|
inplace_arg=inplace_arg,
|
323
400
|
output_size=output_size,
|
324
401
|
)
|
@@ -327,6 +404,7 @@ def clshift_params_getter(
|
|
327
404
|
def crshift_params_getter(
|
328
405
|
left_arg: RegisterArithmeticInfo,
|
329
406
|
right_arg: int,
|
407
|
+
machine_precision: int,
|
330
408
|
output_size: Optional[int] = None,
|
331
409
|
inplace_arg: Optional[str] = None,
|
332
410
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -334,6 +412,7 @@ def crshift_params_getter(
|
|
334
412
|
return CyclicShift(
|
335
413
|
left_arg=left_arg,
|
336
414
|
right_arg=right_arg,
|
415
|
+
machine_precision=machine_precision,
|
337
416
|
inplace_arg=inplace_arg,
|
338
417
|
output_size=output_size,
|
339
418
|
)
|
@@ -342,6 +421,7 @@ def crshift_params_getter(
|
|
342
421
|
def modulo_params_getter(
|
343
422
|
left_arg: RegisterArithmeticInfo,
|
344
423
|
right_arg: int,
|
424
|
+
machine_precision: int,
|
345
425
|
output_size: Optional[int] = None,
|
346
426
|
inplace_arg: Optional[str] = None,
|
347
427
|
target: Optional[RegisterArithmeticInfo] = None,
|
@@ -349,6 +429,7 @@ def modulo_params_getter(
|
|
349
429
|
return Modulo(
|
350
430
|
left_arg=left_arg,
|
351
431
|
right_arg=right_arg,
|
432
|
+
machine_precision=machine_precision,
|
352
433
|
output_size=output_size,
|
353
434
|
inplace_arg=inplace_arg,
|
354
435
|
)
|
@@ -80,18 +80,28 @@ class ArithmeticResultBuilder:
|
|
80
80
|
for predecessor_node in graph.predecessors(node)
|
81
81
|
]
|
82
82
|
if graph.out_degree(node) == 0:
|
83
|
-
return cls._get_node_result(
|
84
|
-
|
83
|
+
return cls._get_node_result(
|
84
|
+
graph, args, node, machine_precision=machine_precision
|
85
|
+
)
|
86
|
+
node_results[node] = cls._get_node_result(
|
87
|
+
graph, args, node, machine_precision=machine_precision
|
88
|
+
)
|
85
89
|
raise ClassiqArithmeticError("Expression has no result")
|
86
90
|
|
87
91
|
@classmethod
|
88
92
|
def _get_node_result(
|
89
|
-
cls,
|
93
|
+
cls,
|
94
|
+
graph: nx.DiGraph,
|
95
|
+
args: List[RegisterOrConst],
|
96
|
+
node: str,
|
97
|
+
*,
|
98
|
+
machine_precision: int,
|
90
99
|
) -> RegisterArithmeticInfo:
|
91
100
|
return arithmetic_param_getters.get_params(
|
92
101
|
node_id=node,
|
93
102
|
args=args,
|
94
103
|
output_size=graph.nodes[node].get(OUTPUT_SIZE, None),
|
104
|
+
machine_precision=machine_precision,
|
95
105
|
).result_register
|
96
106
|
|
97
107
|
@staticmethod
|
@@ -253,8 +253,8 @@ class Adder(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
253
253
|
)
|
254
254
|
integer_part_size = number_utils.bounds_to_integer_part_size(lb, ub)
|
255
255
|
fraction_places = max(
|
256
|
-
|
257
|
-
|
256
|
+
self._compute_fraction_places(self.left_arg),
|
257
|
+
self._compute_fraction_places(self.right_arg),
|
258
258
|
)
|
259
259
|
size_needed = integer_part_size + fraction_places
|
260
260
|
return RegisterArithmeticInfo(
|
@@ -277,8 +277,8 @@ class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
277
277
|
)
|
278
278
|
integer_part_size = number_utils.bounds_to_integer_part_size(*bounds)
|
279
279
|
fraction_places = max(
|
280
|
-
|
281
|
-
|
280
|
+
self._compute_fraction_places(self.left_arg),
|
281
|
+
self._compute_fraction_places(self.right_arg),
|
282
282
|
)
|
283
283
|
size_needed = integer_part_size + fraction_places
|
284
284
|
return RegisterArithmeticInfo(
|
@@ -327,7 +327,7 @@ class Subtractor(InplacableBinaryOpParams[RegisterOrConst, RegisterOrConst]):
|
|
327
327
|
return self.inplace_arg == ArgToInplace.LEFT
|
328
328
|
|
329
329
|
def _expected_negation_output_size(self) -> int:
|
330
|
-
return
|
330
|
+
return self._compute_fraction_places(self.right_arg) + min(
|
331
331
|
self.result_register.integer_part_size,
|
332
332
|
number_utils.bounds_to_integer_part_size(
|
333
333
|
*(-bound for bound in argument_utils.bounds(self.right_arg))
|
@@ -357,9 +357,9 @@ class Multiplier(BinaryOpWithFloatInputs):
|
|
357
357
|
output_name = "product"
|
358
358
|
|
359
359
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
360
|
-
fraction_places =
|
360
|
+
fraction_places = self._compute_fraction_places(
|
361
361
|
self.left_arg
|
362
|
-
) +
|
362
|
+
) + self._compute_fraction_places(self.right_arg)
|
363
363
|
extremal_values = [
|
364
364
|
left * right
|
365
365
|
for left in argument_utils.bounds(self.left_arg)
|
@@ -583,9 +583,7 @@ class Modulo(EffectiveUnaryOpParams[int]):
|
|
583
583
|
) -> int:
|
584
584
|
repr_qubits_float = math.log2(right_arg)
|
585
585
|
repr_qubits = round(repr_qubits_float)
|
586
|
-
assert (
|
587
|
-
abs(repr_qubits - repr_qubits_float) < 10**-8
|
588
|
-
), NOT_POWER_OF_TWO_ERROR_MSG
|
586
|
+
assert abs(repr_qubits - repr_qubits_float) < 10**-8, NOT_POWER_OF_TWO_ERROR_MSG
|
589
587
|
output_size = values.get("output_size")
|
590
588
|
if output_size is not None:
|
591
589
|
repr_qubits = min(repr_qubits, output_size)
|
@@ -61,8 +61,8 @@ class Extremum(ArithmeticOperationParams):
|
|
61
61
|
argument_utils.integer_part_size(self.right_arg),
|
62
62
|
)
|
63
63
|
fraction_places = max(
|
64
|
-
|
65
|
-
|
64
|
+
self._compute_fraction_places(self.left_arg),
|
65
|
+
self._compute_fraction_places(self.right_arg),
|
66
66
|
)
|
67
67
|
required_size = integer_part_size + fraction_places
|
68
68
|
bounds = (
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Tuple, Union
|
2
2
|
|
3
|
-
|
3
|
+
MAXIMAL_MACHINE_PRECISION: int = 20
|
4
4
|
MAX_FRACTION_PLACES: int = 8
|
5
5
|
|
6
6
|
|
@@ -42,7 +42,7 @@ def _get_fraction_places(*, binary_value: str, machine_precision: int) -> int:
|
|
42
42
|
|
43
43
|
|
44
44
|
def get_int_representation_and_fraction_places(
|
45
|
-
float_value: float, *, machine_precision: int
|
45
|
+
float_value: float, *, machine_precision: int
|
46
46
|
) -> Tuple[int, int]:
|
47
47
|
int_val = signed_int_to_unsigned(int(float_value * 2**machine_precision))
|
48
48
|
if int_val == 0:
|
@@ -54,9 +54,7 @@ def get_int_representation_and_fraction_places(
|
|
54
54
|
return int_val, fraction_places
|
55
55
|
|
56
56
|
|
57
|
-
def fraction_places(
|
58
|
-
float_value: float, *, machine_precision: int = MAX_FRACTION_PLACES
|
59
|
-
) -> int:
|
57
|
+
def fraction_places(float_value: float, *, machine_precision: int) -> int:
|
60
58
|
int_val = signed_int_to_unsigned(int(float_value * 2**machine_precision))
|
61
59
|
if int_val == 0:
|
62
60
|
return 0
|
@@ -70,7 +68,7 @@ def _bit_length(integer_representation: int) -> int:
|
|
70
68
|
|
71
69
|
|
72
70
|
def binary_string(
|
73
|
-
float_value: float, *, machine_precision: int =
|
71
|
+
float_value: float, *, machine_precision: int = MAXIMAL_MACHINE_PRECISION
|
74
72
|
) -> str:
|
75
73
|
int_val, _ = get_int_representation_and_fraction_places(
|
76
74
|
float_value=float_value, machine_precision=machine_precision
|
@@ -83,32 +81,24 @@ def binary_string(
|
|
83
81
|
return bin_rep[::-1] + extension_bit * size_diff
|
84
82
|
|
85
83
|
|
86
|
-
def integer_part_size(
|
87
|
-
float_value: float, *, machine_precision: int = MAX_FRACTION_PLACES
|
88
|
-
) -> int:
|
84
|
+
def integer_part_size(float_value: float) -> int:
|
89
85
|
int_val, fraction_places = get_int_representation_and_fraction_places(
|
90
|
-
float_value=float_value, machine_precision=
|
86
|
+
float_value=float_value, machine_precision=MAXIMAL_MACHINE_PRECISION
|
91
87
|
)
|
92
88
|
return max(_bit_length(int_val) - fraction_places, 0)
|
93
89
|
|
94
90
|
|
95
|
-
def size(float_value: float, *, machine_precision: int
|
91
|
+
def size(float_value: float, *, machine_precision: int) -> int:
|
96
92
|
int_val, fraction_places = get_int_representation_and_fraction_places(
|
97
93
|
float_value=float_value, machine_precision=machine_precision
|
98
94
|
)
|
99
95
|
return max(_bit_length(int_val), fraction_places)
|
100
96
|
|
101
97
|
|
102
|
-
def bounds_to_integer_part_size(
|
103
|
-
lb: float, ub: float, *, machine_precision: int = MAX_FRACTION_PLACES
|
104
|
-
) -> int:
|
98
|
+
def bounds_to_integer_part_size(lb: float, ub: float) -> int:
|
105
99
|
lb, ub = min(lb, ub), max(lb, ub)
|
106
|
-
ub_integer_part_size: int = integer_part_size(
|
107
|
-
|
108
|
-
)
|
109
|
-
lb_integer_part_size: int = integer_part_size(
|
110
|
-
float_value=lb, machine_precision=machine_precision
|
111
|
-
)
|
100
|
+
ub_integer_part_size: int = integer_part_size(float_value=ub)
|
101
|
+
lb_integer_part_size: int = integer_part_size(float_value=lb)
|
112
102
|
if lb == 0:
|
113
103
|
return ub_integer_part_size
|
114
104
|
if ub == 0:
|
@@ -118,8 +108,15 @@ def bounds_to_integer_part_size(
|
|
118
108
|
|
119
109
|
|
120
110
|
def limit_fraction_places(number: float, *, machine_precision: int) -> float:
|
121
|
-
|
122
|
-
|
111
|
+
orig_bin_rep = binary_string(number, machine_precision=MAXIMAL_MACHINE_PRECISION)[
|
112
|
+
::-1
|
113
|
+
]
|
114
|
+
orig_fractions = fraction_places(
|
115
|
+
number, machine_precision=MAXIMAL_MACHINE_PRECISION
|
116
|
+
)
|
117
|
+
removed_fractions = max(orig_fractions - machine_precision, 0)
|
123
118
|
return binary_to_float(
|
124
|
-
bin_rep=
|
119
|
+
bin_rep=orig_bin_rep[: len(orig_bin_rep) - removed_fractions],
|
120
|
+
fraction_part_size=orig_fractions - removed_fractions,
|
121
|
+
is_signed=number < 0,
|
125
122
|
)
|
@@ -7,6 +7,8 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
|
|
7
7
|
HashablePydanticBaseModel,
|
8
8
|
)
|
9
9
|
|
10
|
+
from classiq.exceptions import ClassiqValueError
|
11
|
+
|
10
12
|
|
11
13
|
class RegisterArithmeticInfo(HashablePydanticBaseModel):
|
12
14
|
size: pydantic.PositiveInt
|
@@ -30,7 +32,7 @@ class RegisterArithmeticInfo(HashablePydanticBaseModel):
|
|
30
32
|
return tuple(bounds) # type: ignore[return-value]
|
31
33
|
size = values.get("size")
|
32
34
|
if not isinstance(size, int):
|
33
|
-
raise
|
35
|
+
raise ClassiqValueError("RegisterUserInput must have an integer size")
|
34
36
|
is_signed: bool = values.get("is_signed", False)
|
35
37
|
lb = 0 if not is_signed else -(2 ** (size - 1))
|
36
38
|
ub = 2**size - 1 if not is_signed else 2 ** (size - 1) - 1
|
@@ -19,13 +19,12 @@ class UnaryOpParams(ArithmeticOperationParams):
|
|
19
19
|
arg: RegisterArithmeticInfo
|
20
20
|
inplace: bool = False
|
21
21
|
|
22
|
-
@classmethod
|
23
22
|
@abc.abstractmethod
|
24
|
-
def _expected_result_size(
|
23
|
+
def _expected_result_size(self) -> pydantic.PositiveInt:
|
25
24
|
pass
|
26
25
|
|
27
26
|
def actual_result_size(self) -> int:
|
28
|
-
return self.output_size or self._expected_result_size(
|
27
|
+
return self.output_size or self._expected_result_size()
|
29
28
|
|
30
29
|
def garbage_output_size(self) -> pydantic.NonNegativeInt:
|
31
30
|
return int(self.is_inplaced()) * max(
|
@@ -73,9 +72,8 @@ class UnaryOpParams(ArithmeticOperationParams):
|
|
73
72
|
class BitwiseInvert(UnaryOpParams):
|
74
73
|
output_name = "inverted"
|
75
74
|
|
76
|
-
|
77
|
-
|
78
|
-
return arg.size
|
75
|
+
def _expected_result_size(self) -> pydantic.PositiveInt:
|
76
|
+
return self.arg.size
|
79
77
|
|
80
78
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
81
79
|
return RegisterArithmeticInfo(
|
@@ -88,12 +86,11 @@ class BitwiseInvert(UnaryOpParams):
|
|
88
86
|
class Negation(UnaryOpParams):
|
89
87
|
output_name = "negated"
|
90
88
|
|
91
|
-
|
92
|
-
|
93
|
-
if arg.size == 1:
|
89
|
+
def _expected_result_size(self) -> pydantic.PositiveInt:
|
90
|
+
if self.arg.size == 1:
|
94
91
|
return 1
|
95
|
-
return arg.fraction_places + number_utils.bounds_to_integer_part_size(
|
96
|
-
*(-bound for bound in arg.bounds)
|
92
|
+
return self.arg.fraction_places + number_utils.bounds_to_integer_part_size(
|
93
|
+
*(-bound for bound in self.arg.bounds)
|
97
94
|
)
|
98
95
|
|
99
96
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
@@ -118,8 +115,7 @@ class Sign(UnaryOpParams):
|
|
118
115
|
raise ValueError("Sign output size must be 1")
|
119
116
|
return 1
|
120
117
|
|
121
|
-
|
122
|
-
def _expected_result_size(cls, arg: RegisterArithmeticInfo) -> pydantic.PositiveInt:
|
118
|
+
def _expected_result_size(self) -> pydantic.PositiveInt:
|
123
119
|
return 1
|
124
120
|
|
125
121
|
def _get_result_register(self) -> RegisterArithmeticInfo:
|
@@ -11,6 +11,8 @@ SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS = {
|
|
11
11
|
"get_type",
|
12
12
|
"struct_literal",
|
13
13
|
"get_field",
|
14
|
+
"fraction_digits",
|
15
|
+
"is_signed",
|
14
16
|
"molecule_problem_to_hamiltonian",
|
15
17
|
"fock_hamiltonian_problem_to_hamiltonian",
|
16
18
|
"molecule_ground_state_solution_post_process",
|
@@ -4,6 +4,9 @@ from typing import Any, Mapping, Optional, Type
|
|
4
4
|
import pydantic
|
5
5
|
from pydantic import PrivateAttr
|
6
6
|
|
7
|
+
from classiq.interface.generator.arith.arithmetic_expression_validator import (
|
8
|
+
DEFAULT_SUPPORTED_FUNC_NAMES,
|
9
|
+
)
|
7
10
|
from classiq.interface.generator.expressions.atomic_expression_functions import (
|
8
11
|
SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS,
|
9
12
|
)
|
@@ -32,8 +35,10 @@ class Expression(HashablePydanticBaseModel):
|
|
32
35
|
|
33
36
|
@pydantic.validator("expr")
|
34
37
|
def validate_expression(cls, expr: str) -> str:
|
35
|
-
supported_functions =
|
36
|
-
|
38
|
+
supported_functions = (
|
39
|
+
SUPPORTED_ATOMIC_EXPRESSION_FUNCTIONS
|
40
|
+
| set(SYMPY_SUPPORTED_EXPRESSIONS)
|
41
|
+
| set(DEFAULT_SUPPORTED_FUNC_NAMES)
|
37
42
|
)
|
38
43
|
validate_expression_str(expr, supported_functions=supported_functions)
|
39
44
|
return expr
|