classiq 0.91.1__py3-none-any.whl → 0.92.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.
Files changed (34) hide show
  1. classiq/__init__.py +13 -0
  2. classiq/_internals/config.py +1 -1
  3. classiq/analyzer/show_interactive_hack.py +1 -1
  4. classiq/applications/__init__.py +2 -6
  5. classiq/applications/qsp/__init__.py +7 -0
  6. classiq/applications/qsp/qsp.py +366 -0
  7. classiq/execution/jobs.py +18 -8
  8. classiq/interface/_version.py +1 -1
  9. classiq/interface/backend/backend_preferences.py +8 -8
  10. classiq/interface/executor/result.py +4 -0
  11. classiq/interface/generator/functions/builtins/internal_operators.py +1 -0
  12. classiq/interface/generator/generated_circuit_data.py +5 -17
  13. classiq/interface/generator/transpiler_basis_gates.py +1 -1
  14. classiq/interface/helpers/versioned_model.py +0 -2
  15. classiq/interface/interface_version.py +1 -1
  16. classiq/interface/model/bind_operation.py +0 -12
  17. classiq/interface/model/handle_binding.py +3 -0
  18. classiq/interface/model/skip_control.py +11 -0
  19. classiq/interface/model/statement_block.py +3 -0
  20. classiq/interface/server/routes.py +0 -3
  21. classiq/model_expansions/interpreters/generative_interpreter.py +15 -0
  22. classiq/model_expansions/quantum_operations/bind.py +14 -0
  23. classiq/model_expansions/quantum_operations/skip_control_verifier.py +20 -0
  24. classiq/open_library/functions/__init__.py +2 -0
  25. classiq/open_library/functions/qsvt.py +60 -6
  26. classiq/qmod/builtins/operations.py +16 -0
  27. classiq/qmod/native/pretty_printer.py +8 -0
  28. classiq/qmod/pretty_print/pretty_printer.py +5 -0
  29. classiq/qmod/quantum_expandable.py +29 -15
  30. classiq/synthesis.py +1 -1
  31. {classiq-0.91.1.dist-info → classiq-0.92.0.dist-info}/METADATA +4 -1
  32. {classiq-0.91.1.dist-info → classiq-0.92.0.dist-info}/RECORD +33 -30
  33. classiq/interface/ide/ide_data.py +0 -102
  34. {classiq-0.91.1.dist-info → classiq-0.92.0.dist-info}/WHEEL +0 -0
@@ -1,9 +1,6 @@
1
1
  from collections.abc import Mapping, Sequence
2
2
  from typing import Literal
3
3
 
4
- import pydantic
5
-
6
- from classiq.interface.exceptions import ClassiqValueError
7
4
  from classiq.interface.model.handle_binding import ConcreteHandleBinding, HandleBinding
8
5
  from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
9
6
 
@@ -49,12 +46,3 @@ class BindOperation(QuantumOperation):
49
46
  )
50
47
  for handle in self.out_handles
51
48
  ]
52
-
53
- @pydantic.field_validator("in_handles", "out_handles")
54
- @classmethod
55
- def validate_handle(cls, handles: list[HandleBinding]) -> list[HandleBinding]:
56
- for handle in handles:
57
- if not handle.is_bindable():
58
- raise ClassiqValueError(f"Cannot bind '{handle}'")
59
-
60
- return handles
@@ -382,6 +382,9 @@ FieldHandleBinding.model_rebuild()
382
382
  class HandlesList(ASTNode):
383
383
  handles: list["GeneralHandle"]
384
384
 
385
+ def __str__(self) -> str:
386
+ return f"[{', '.join(map(str, self.handles))}]"
387
+
385
388
 
386
389
  GeneralHandle = Union[ConcreteHandleBinding, HandlesList]
387
390
  HandlesList.model_rebuild()
@@ -0,0 +1,11 @@
1
+ from typing import TYPE_CHECKING, Literal
2
+
3
+ from classiq.interface.model.quantum_statement import QuantumOperation
4
+
5
+ if TYPE_CHECKING:
6
+ from classiq.interface.model.statement_block import StatementBlock
7
+
8
+
9
+ class SkipControl(QuantumOperation):
10
+ kind: Literal["SkipControl"]
11
+ body: "StatementBlock"
@@ -22,6 +22,7 @@ from classiq.interface.model.quantum_expressions.arithmetic_operation import (
22
22
  from classiq.interface.model.quantum_function_call import QuantumFunctionCall
23
23
  from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
24
24
  from classiq.interface.model.repeat import Repeat
25
+ from classiq.interface.model.skip_control import SkipControl
25
26
  from classiq.interface.model.variable_declaration_statement import (
26
27
  VariableDeclarationStatement,
27
28
  )
@@ -53,6 +54,7 @@ ConcreteQuantumStatement = Annotated[
53
54
  Action,
54
55
  Uncompute,
55
56
  SetBoundsStatement,
57
+ SkipControl,
56
58
  ],
57
59
  Field(..., discriminator="kind"),
58
60
  ]
@@ -69,3 +71,4 @@ WithinApply.model_rebuild()
69
71
  ClassicalIf.model_rebuild()
70
72
  NativeFunctionDefinition.model_rebuild()
71
73
  PhaseOperation.model_rebuild()
74
+ SkipControl.model_rebuild()
@@ -25,7 +25,6 @@ RB = "/rb"
25
25
  ANALYZER_DATA_TASK = f"{TASKS_SUFFIX}/data"
26
26
  ANALYZER_QASM_TASK = f"{TASKS_SUFFIX}/qasm"
27
27
  ANALYZER_GET_VISUAL_MODEL = "/get_visual_model"
28
- ANALYZER_GET_IDE_DATA = "/get_ide_data"
29
28
  IDE_EVENT_TASK = f"{TASKS_SUFFIX}/event"
30
29
  DATA_DOG_EVENT_TASK = f"{TASKS_SUFFIX}/data_dog_event"
31
30
 
@@ -33,14 +32,12 @@ ANALYZER_DATA_TASK_UPLOAD_FILE = f"{TASKS_SUFFIX}/data/file_upload"
33
32
  ANALYZER_DATA_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_DATA_TASK}"
34
33
  ANALYZER_QASM_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_QASM_TASK}"
35
34
  ANALYZER_GET_VISUAL_MODEL_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_GET_VISUAL_MODEL}"
36
- ANALYZER_GET_IDE_DATA_FULL_PATH = f"{ANALYZER_PREFIX}{ANALYZER_GET_IDE_DATA}"
37
35
  IDE_EVENT_TASK_FULL_PATH = f"{ANALYZER_PREFIX}{IDE_EVENT_TASK}"
38
36
  DATA_DOG_EVENT_TASK_FULL_PATH = f"{ANALYZER_PREFIX}{DATA_DOG_EVENT_TASK}"
39
37
 
40
38
  IDE_QASM_TASK = f"{TASKS_SUFFIX}/generated_circuit_from_qasm"
41
39
  IDE_QASM_FULL_PATH = f"{ANALYZER_PREFIX}{IDE_QASM_TASK}"
42
40
  TASKS_GENERATE_SUFFIX = TASKS_SUFFIX + "/generate"
43
- TASKS_VISUALIZE_SUFFIX = TASKS_SUFFIX + "/visualize"
44
41
  TASKS_VISUAL_MODEL_SUFFIX = TASKS_SUFFIX + "/visual_model"
45
42
  TASKS_SOLVE_SUFFIX = "/tasks/solve"
46
43
 
@@ -13,6 +13,7 @@ from classiq.interface.generator.functions.builtins.internal_operators import (
13
13
  INVERT_OPERATOR_NAME,
14
14
  POWER_OPERATOR_NAME,
15
15
  REPEAT_OPERATOR_NAME,
16
+ SKIP_CONTROL_OPERATOR_NAME,
16
17
  WITHIN_APPLY_NAME,
17
18
  )
18
19
  from classiq.interface.model.allocate import Allocate
@@ -43,6 +44,7 @@ from classiq.interface.model.quantum_lambda_function import (
43
44
  )
44
45
  from classiq.interface.model.quantum_statement import QuantumStatement
45
46
  from classiq.interface.model.repeat import Repeat
47
+ from classiq.interface.model.skip_control import SkipControl
46
48
  from classiq.interface.model.variable_declaration_statement import (
47
49
  VariableDeclarationStatement,
48
50
  )
@@ -84,6 +86,9 @@ from classiq.model_expansions.quantum_operations.handle_evaluator import HandleE
84
86
  from classiq.model_expansions.quantum_operations.repeat_block_evaluator import (
85
87
  RepeatBlockEvaluator,
86
88
  )
89
+ from classiq.model_expansions.quantum_operations.skip_control_verifier import (
90
+ SkipControlVerifier,
91
+ )
87
92
  from classiq.model_expansions.scope import Evaluated, Scope
88
93
  from classiq.model_expansions.scope_initialization import (
89
94
  add_constants_to_scope,
@@ -278,6 +283,16 @@ class GenerativeInterpreter(BaseInterpreter):
278
283
  def emit_invert(self, invert: Invert) -> None:
279
284
  BlockEvaluator(self, INVERT_OPERATOR_NAME, "body").emit(invert)
280
285
 
286
+ @emit.register
287
+ def emit_skip_control(self, skip_control: SkipControl) -> None:
288
+ CompositeEmitter[SkipControl](
289
+ self,
290
+ [
291
+ SkipControlVerifier(self),
292
+ BlockEvaluator(self, SKIP_CONTROL_OPERATOR_NAME, "body"),
293
+ ],
294
+ ).emit(skip_control)
295
+
281
296
  @emit.register
282
297
  def _emit_repeat(self, repeat: Repeat) -> None:
283
298
  self.emit_repeat(repeat)
@@ -25,6 +25,12 @@ if TYPE_CHECKING:
25
25
  from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
26
26
 
27
27
 
28
+ BIND_PATH_EXPR_MESSAGE = (
29
+ "Cannot use variable part (subscript, slice, or field access) in the source or "
30
+ "destination of a 'bind' statement"
31
+ )
32
+
33
+
28
34
  class BindEmitter(Emitter[BindOperation]):
29
35
  def __init__(
30
36
  self, interpreter: "BaseInterpreter", allow_symbolic_size: bool = False
@@ -60,6 +66,7 @@ class BindEmitter(Emitter[BindOperation]):
60
66
  evaluated_outputs: list[Evaluated] = [
61
67
  self._interpreter.evaluate(arg) for arg in bind.out_handles
62
68
  ]
69
+ self._validate_var_types(evaluated_inputs + evaluated_outputs)
63
70
  self._validate_handle_states(evaluated_inputs, evaluated_outputs)
64
71
  inputs: list[QuantumSymbol] = [
65
72
  input.as_type(QuantumSymbol) for input in evaluated_inputs
@@ -71,6 +78,13 @@ class BindEmitter(Emitter[BindOperation]):
71
78
  outputs = evaluate_types_in_quantum_symbols(outputs, self._current_scope)
72
79
  return inputs, outputs
73
80
 
81
+ def _validate_var_types(self, vars: list[Evaluated]) -> None:
82
+ path_expr_vars = [
83
+ var.value for var in vars if not var.value.handle.is_bindable()
84
+ ]
85
+ if len(path_expr_vars) > 0:
86
+ raise ClassiqExpansionError(BIND_PATH_EXPR_MESSAGE)
87
+
74
88
  def _validate_handle_states(
75
89
  self, inputs: list[Evaluated], outputs: list[Evaluated]
76
90
  ) -> None:
@@ -0,0 +1,20 @@
1
+ from classiq.interface.exceptions import ClassiqExpansionError
2
+ from classiq.interface.helpers.backward_compatibility import zip_strict
3
+ from classiq.interface.model.skip_control import SkipControl
4
+
5
+ from classiq.model_expansions.function_builder import FunctionContext
6
+ from classiq.model_expansions.quantum_operations.emitter import Emitter
7
+
8
+
9
+ class SkipControlVerifier(Emitter[SkipControl]):
10
+ def emit(self, skip_control: SkipControl, /) -> bool:
11
+ for op, block in list(
12
+ zip_strict(self._builder._operations, self._builder._blocks, strict=True)
13
+ )[::-1]:
14
+ if isinstance(op, FunctionContext):
15
+ break
16
+ if block in ("action", "apply"):
17
+ raise ClassiqExpansionError(
18
+ "skip_control cannot be used under within-apply's 'apply' block"
19
+ )
20
+ return False
@@ -53,6 +53,7 @@ OPEN_LIBRARY_FUNCTIONS = [
53
53
  qsvt_inversion,
54
54
  qsvt_lcu,
55
55
  qsvt_lcu_step,
56
+ gqsp,
56
57
  qaoa_mixer_layer,
57
58
  qaoa_cost_layer,
58
59
  qaoa_layer,
@@ -94,6 +95,7 @@ __all__ = [
94
95
  "encode_on_bloch",
95
96
  "exact_amplitude_amplification",
96
97
  "full_hea",
98
+ "gqsp",
97
99
  "grover_diffuser",
98
100
  "grover_operator",
99
101
  "grover_search",
@@ -1,7 +1,7 @@
1
- from classiq.qmod.builtins.functions.standard_gates import IDENTITY, RZ, H
1
+ from classiq.qmod.builtins.functions.standard_gates import IDENTITY, RZ, H, U, X, Z
2
2
  from classiq.qmod.builtins.operations import control, if_, invert, repeat, within_apply
3
3
  from classiq.qmod.qfunc import qfunc
4
- from classiq.qmod.qmod_parameter import CArray, CReal
4
+ from classiq.qmod.qmod_parameter import CArray, CInt, CReal
5
5
  from classiq.qmod.qmod_variable import QArray, QBit
6
6
  from classiq.qmod.quantum_callable import QCallable
7
7
  from classiq.qmod.symbolic import floor, min as qmin
@@ -267,8 +267,8 @@ def qsvt_lcu(
267
267
  Note: the two polynomials should have the same degree up to a difference of 1.
268
268
 
269
269
  Args:
270
- phase_seq_odd: A sequence of phase angles of length d+1 for the odd polynomial.
271
- phase_seq_even: A sequence of phase angles of length d+1 for the even polynomial.
270
+ phase_seq_odd: A sequence of phase angles of length d+(d%2) for the odd polynomial.
271
+ phase_seq_even: A sequence of phase angles of length d+(d+1)%2 for the even polynomial.
272
272
  proj_cnot_1: Projector-controlled-not unitary that locates the encoded matrix columns within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
273
273
  proj_cnot_2: Projector-controlled-not unitary that locates the encoded matrix rows within U. Accepts a quantum variable of the same size as qvar, and a qubit that is set to |1> when the state is in the block.
274
274
  u: A block encoded unitary matrix.
@@ -281,7 +281,7 @@ def qsvt_lcu(
281
281
  phase_seq_even[0], phase_seq_odd[0], proj_cnot_1, qvar, aux, lcu
282
282
  )
283
283
  repeat(
284
- count=floor((qmin(phase_seq_odd.len, phase_seq_even.len)) / 2),
284
+ count=floor((qmin(phase_seq_odd.len - 1, phase_seq_even.len - 1)) / 2),
285
285
  iteration=lambda index: qsvt_lcu_step(
286
286
  phase_seq_even[2 * index + 1 : 2 * index + 3],
287
287
  phase_seq_odd[2 * index + 1 : 2 * index + 3],
@@ -310,7 +310,7 @@ def qsvt_lcu(
310
310
  then=lambda: (
311
311
  u(qvar),
312
312
  projector_controlled_double_phase(
313
- phase_seq_even[phase_seq_even.len - 1],
313
+ phase_seq_even[phase_seq_even.len - 2],
314
314
  phase_seq_odd[phase_seq_odd.len - 1],
315
315
  proj_cnot_2,
316
316
  qvar,
@@ -329,3 +329,57 @@ def qsvt_lcu(
329
329
  ),
330
330
  )
331
331
  H(aux)
332
+
333
+
334
+ @qfunc
335
+ def _gqsp_r_gate(theta: CReal, phi: CReal, _lambda: CReal, q: QBit) -> None:
336
+ """
337
+ Implements the R gate from the paper https://arxiv.org/abs/2308.01501 using the U gate.
338
+ """
339
+ within_apply(lambda: X(q), lambda: U(2 * theta, phi, _lambda, 0, q))
340
+ Z(q)
341
+
342
+
343
+ @qfunc
344
+ def gqsp(
345
+ u: QCallable, aux: QBit, phases: CArray[CArray[CReal], 3], negative_power: CInt # type: ignore[valid-type]
346
+ ) -> None:
347
+ """
348
+ Implements Generalized Quantum Signal Processing (GQSP), which realizes a
349
+ (Laurent) polynomial transformation of degree d on the eigenvalues of the given
350
+ signal unitary `u`. The protocol is according to https://arxiv.org/abs/2308.01501
351
+ Fig.2.
352
+
353
+ Notes:
354
+ - The user is encouraged to use the function `gqsp_phases` to find `phases` that
355
+ correspond to the wanted polynomial transformation.
356
+ - Feasibility: the target polynomial must satisfy |P(e^{i*theta})| <= 1 for all
357
+ theta in [0, 2*pi). This ensures a unitary completion exists.
358
+ - Using `negative_power = m` (m >= 0) you can realize Laurent polynomials with
359
+ negative exponents: the implemented transform is equivalent to applying
360
+ z^{-m} * P(z) (i.e., shift the minimal degree to -m).
361
+ For ordinary (non-Laurent) polynomials, set `negative_power = 0`.
362
+
363
+ Args:
364
+ u: The signal unitary.
365
+ aux: Auxiliary qubit used for the phase rotations. Should start in |0>.
366
+ phases: 3 x (d+1) real array of angles: phases[0] = thetas, phases[1] = phis,
367
+ phases[2] = lambdas.
368
+ negative_power: Integer m in [0, d]. Encodes the minimal Laurent power -m of
369
+ the realized transformation.
370
+ """
371
+ degree = phases[0].len - 1
372
+ _gqsp_r_gate(phases[0][0], phases[1][0], phases[2][0], aux)
373
+ repeat(
374
+ degree,
375
+ lambda index: [
376
+ if_(
377
+ index + 1 <= degree - negative_power,
378
+ lambda: control(aux == 0, lambda: u()),
379
+ lambda: control(aux == 1, lambda: invert(u)),
380
+ ),
381
+ _gqsp_r_gate(
382
+ phases[0][index + 1], phases[1][index + 1], phases[2][index + 1], aux
383
+ ),
384
+ ],
385
+ )
@@ -45,6 +45,7 @@ from classiq.interface.model.quantum_function_declaration import (
45
45
  )
46
46
  from classiq.interface.model.quantum_lambda_function import QuantumLambdaFunction
47
47
  from classiq.interface.model.repeat import Repeat
48
+ from classiq.interface.model.skip_control import SkipControl
48
49
  from classiq.interface.model.statement_block import StatementBlock
49
50
  from classiq.interface.model.within_apply_operation import WithinApply
50
51
 
@@ -254,6 +255,20 @@ def control(
254
255
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(control_stmt)
255
256
 
256
257
 
258
+ @suppress_return_value
259
+ def skip_control(stmt_block: Union[QCallable, Callable[[], Statements]]) -> None:
260
+ _validate_operand(stmt_block)
261
+ assert QCallable.CURRENT_EXPANDABLE is not None
262
+ source_ref = get_source_ref(sys._getframe(1))
263
+ sc_stmt = SkipControl(
264
+ body=_operand_to_body(stmt_block, "stmt_block"),
265
+ source_ref=source_ref,
266
+ )
267
+ if is_generative_mode():
268
+ sc_stmt.set_generative_block("body", stmt_block)
269
+ QCallable.CURRENT_EXPANDABLE.append_statement_to_body(sc_stmt)
270
+
271
+
257
272
  @suppress_return_value
258
273
  def assign(expression: SymbolicExpr, target_var: QScalar) -> None:
259
274
  """
@@ -748,6 +763,7 @@ __all__ = [
748
763
  "power",
749
764
  "repeat",
750
765
  "reset_bounds",
766
+ "skip_control",
751
767
  "within_apply",
752
768
  ]
753
769
 
@@ -78,6 +78,7 @@ from classiq.interface.model.quantum_type import (
78
78
  QuantumNumeric,
79
79
  )
80
80
  from classiq.interface.model.repeat import Repeat
81
+ from classiq.interface.model.skip_control import SkipControl
81
82
  from classiq.interface.model.statement_block import StatementBlock
82
83
  from classiq.interface.model.variable_declaration_statement import (
83
84
  VariableDeclarationStatement,
@@ -311,6 +312,13 @@ class DSLPrettyPrinter(ModelVisitor):
311
312
  control += "\n"
312
313
  return control
313
314
 
315
+ def visit_SkipControl(self, op: SkipControl) -> str:
316
+ sc = f"{self._indent}skip_control {{\n"
317
+ sc += self._visit_body(op.body)
318
+ sc += f"{self._indent}}}"
319
+ sc += "\n"
320
+ return sc
321
+
314
322
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
315
323
  theta = f", {self.visit(op.theta)}" if op.theta.expr != "1.0" else ""
316
324
  phase = f"{self._indent}phase ({self.visit(op.expression)}{theta});\n"
@@ -78,6 +78,7 @@ from classiq.interface.model.quantum_type import (
78
78
  QuantumNumeric,
79
79
  )
80
80
  from classiq.interface.model.repeat import Repeat
81
+ from classiq.interface.model.skip_control import SkipControl
81
82
  from classiq.interface.model.statement_block import StatementBlock
82
83
  from classiq.interface.model.variable_declaration_statement import (
83
84
  VariableDeclarationStatement,
@@ -459,6 +460,10 @@ class PythonPrettyPrinter(ModelVisitor):
459
460
  )
460
461
  return f"{self._indent}control({self.visit(op.expression)}, {self._visit_body(op.body)}{control_else})\n"
461
462
 
463
+ def visit_SkipControl(self, op: SkipControl) -> str:
464
+ self._imports["skip_control"] = 1
465
+ return f"{self._indent}skip_control({self._visit_body(op.body)})\n"
466
+
462
467
  def visit_PhaseOperation(self, op: PhaseOperation) -> str:
463
468
  self._imports["phase"] = 1
464
469
  theta = f", {self.visit(op.theta)}" if op.theta.expr != "1.0" else ""
@@ -472,6 +472,34 @@ def _prepare_args(
472
472
  return result
473
473
 
474
474
 
475
+ def _validate_argument_names(
476
+ decl: QuantumFunctionDeclaration, arg_list: list[Any], kwargs: dict[str, Any]
477
+ ) -> None:
478
+ params = decl.positional_arg_declarations
479
+ param_names = {
480
+ mangle_keyword(param.name) for param in params if param.name is not None
481
+ }
482
+ pos_arg_names = {
483
+ mangle_keyword(param.name)
484
+ for param in params[: len(arg_list)]
485
+ if param.name is not None
486
+ }
487
+ for kwarg_name in kwargs:
488
+ if kwarg_name not in param_names:
489
+ raise ClassiqValueError(
490
+ f"{decl.name}() got an unexpected keyword argument {kwarg_name!r}"
491
+ )
492
+ if kwarg_name in pos_arg_names:
493
+ raise ClassiqValueError(
494
+ f"{decl.name}() got multiple values for argument {kwarg_name!r}"
495
+ )
496
+ total_args = len(arg_list) + len(kwargs)
497
+ if total_args != len(params):
498
+ raise ClassiqValueError(
499
+ f"{decl.name}() takes {len(params)} arguments but {total_args} were given"
500
+ )
501
+
502
+
475
503
  def _create_quantum_function_call(
476
504
  decl_: QuantumFunctionDeclaration,
477
505
  index_: Optional[Union[CParamScalar, int]] = None,
@@ -479,24 +507,10 @@ def _create_quantum_function_call(
479
507
  *args: Any,
480
508
  **kwargs: Any,
481
509
  ) -> QuantumFunctionCall:
482
- arg_decls = decl_.positional_arg_declarations
483
510
  arg_list = list(args)
511
+ _validate_argument_names(decl_, arg_list, kwargs)
484
512
  prepared_args = _prepare_args(decl_, arg_list, kwargs)
485
513
 
486
- if kwargs:
487
- bad_kwarg = next(iter(kwargs))
488
- if not all(arg_decl.name == bad_kwarg for arg_decl in arg_decls):
489
- raise ClassiqValueError(
490
- f"{decl_.name}() got an unexpected keyword argument {bad_kwarg!r}"
491
- )
492
- else:
493
- raise ClassiqValueError(
494
- f"{decl_.name}() got multiple values for argument {bad_kwarg!r}"
495
- )
496
- if arg_list:
497
- raise ClassiqValueError(
498
- f"{decl_.name}() takes {len(arg_decls)} arguments but {len(args)} were given"
499
- )
500
514
  function_ident: Union[str, OperandIdentifier] = decl_.name
501
515
  if index_ is not None:
502
516
  function_ident = OperandIdentifier(
classiq/synthesis.py CHANGED
@@ -69,7 +69,7 @@ def synthesize(
69
69
  ) -> QuantumProgram:
70
70
  """
71
71
  Synthesize a model with the Classiq engine to receive a quantum program.
72
- [More details](https://docs.classiq.io/latest/reference-manual/synthesis/)
72
+ [More details](https://docs.classiq.io/latest/sdk-reference/synthesis/#classiq.synthesize)
73
73
 
74
74
  Args:
75
75
  model: The entry point of the Qmod model - a qfunc named 'main' (or alternatively the output of 'create_model').
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: classiq
3
- Version: 0.91.1
3
+ Version: 0.92.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  License: Proprietary
6
6
  Keywords: quantum computing,quantum circuits,quantum algorithms,QAD,QDL
@@ -29,9 +29,11 @@ Classifier: Typing :: Typed
29
29
  Provides-Extra: analyzer-sdk
30
30
  Provides-Extra: chemistry
31
31
  Provides-Extra: qml
32
+ Provides-Extra: qsp
32
33
  Requires-Dist: ConfigArgParse (>=1.5.3,<2.0.0)
33
34
  Requires-Dist: Pyomo (>=6.9,<6.10)
34
35
  Requires-Dist: black (>=24.0,<25.0)
36
+ Requires-Dist: cvxpy ; extra == "qsp"
35
37
  Requires-Dist: httpx (>=0.23.0,<1)
36
38
  Requires-Dist: ipywidgets ; extra == "analyzer-sdk"
37
39
  Requires-Dist: jupyterlab ; extra == "analyzer-sdk"
@@ -49,6 +51,7 @@ Requires-Dist: pandas (>=1.4.0,<3.0.0)
49
51
  Requires-Dist: plotly (>=5.7.0,<6.0.0)
50
52
  Requires-Dist: pydantic (>=2.10.4,<3.0.0)
51
53
  Requires-Dist: pydantic-settings (>=2.4.0,<3.0.0)
54
+ Requires-Dist: pyqsp ; extra == "qsp"
52
55
  Requires-Dist: scipy (>=1.10.0,<2.0.0) ; python_version < "3.12"
53
56
  Requires-Dist: scipy (>=1.11.0,<2.0.0) ; python_version >= "3.12"
54
57
  Requires-Dist: sympy (>=1.13.0,<2.0.0)