classiq 0.42.2__py3-none-any.whl → 0.43.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 +2 -6
- classiq/_internals/api_wrapper.py +6 -12
- classiq/_internals/authentication/token_manager.py +5 -2
- classiq/_internals/jobs.py +5 -10
- classiq/analyzer/rb.py +3 -3
- classiq/applications/chemistry/chemistry_model_constructor.py +12 -8
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +2 -2
- classiq/applications/finance/finance_model_constructor.py +16 -13
- classiq/applications/qsvm/__init__.py +1 -3
- classiq/applications/qsvm/qsvm_model_constructor.py +7 -6
- classiq/exceptions.py +9 -4
- classiq/execution/execution_session.py +5 -2
- classiq/execution/qnn.py +1 -1
- classiq/executor.py +0 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/chemistry/operator.py +19 -5
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/finance/function_input.py +16 -10
- classiq/interface/generator/application_apis/chemistry_declarations.py +2 -2
- classiq/interface/generator/application_apis/qsvm_declarations.py +4 -2
- classiq/interface/generator/arith/argument_utils.py +20 -3
- classiq/interface/generator/arith/arithmetic_expression_validator.py +3 -26
- classiq/interface/generator/arith/binary_ops.py +8 -14
- classiq/interface/generator/arith/extremum_operations.py +30 -0
- classiq/interface/generator/arith/number_utils.py +1 -1
- classiq/interface/generator/arith/unary_ops.py +1 -3
- classiq/interface/generator/compiler_keywords.py +1 -1
- classiq/interface/generator/expressions/atomic_expression_functions.py +13 -3
- classiq/interface/generator/expressions/enums/__init__.py +0 -20
- classiq/interface/generator/expressions/enums/finance_functions.py +11 -18
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -37
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +16 -11
- classiq/interface/generator/expressions/qmod_sized_proxy.py +5 -5
- classiq/interface/generator/function_param_list_without_self_reference.py +0 -10
- classiq/interface/generator/function_params.py +0 -4
- classiq/interface/generator/functions/__init__.py +0 -20
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +2 -2
- classiq/interface/generator/functions/builtins/open_lib_functions.py +530 -1
- classiq/interface/generator/functions/classical_type.py +22 -69
- classiq/interface/generator/functions/port_declaration.py +0 -11
- classiq/interface/generator/model/__init__.py +0 -1
- classiq/interface/generator/model/model.py +9 -185
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -1
- classiq/interface/generator/types/builtin_enum_declarations.py +69 -0
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +2 -2
- classiq/interface/generator/types/enum_declaration.py +57 -0
- classiq/interface/jobs.py +36 -65
- classiq/interface/model/bind_operation.py +3 -0
- classiq/interface/model/classical_parameter_declaration.py +3 -0
- classiq/interface/model/handle_binding.py +7 -0
- classiq/interface/model/inplace_binary_operation.py +13 -15
- classiq/interface/model/model.py +8 -20
- classiq/interface/model/native_function_definition.py +0 -17
- classiq/interface/model/quantum_function_call.py +63 -182
- classiq/interface/model/quantum_type.py +71 -10
- classiq/interface/server/routes.py +0 -6
- classiq/qmod/__init__.py +3 -3
- classiq/qmod/builtins/__init__.py +10 -1
- classiq/qmod/builtins/classical_execution_primitives.py +4 -2
- classiq/qmod/builtins/enums.py +177 -0
- classiq/qmod/builtins/functions.py +1 -2
- classiq/qmod/builtins/operations.py +2 -4
- classiq/qmod/builtins/structs.py +16 -17
- classiq/qmod/declaration_inferrer.py +23 -20
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/pretty_printer.py +31 -13
- classiq/qmod/pretty_print/pretty_printer.py +52 -27
- classiq/qmod/qmod_constant.py +7 -3
- classiq/qmod/qmod_parameter.py +2 -1
- classiq/qmod/qmod_struct.py +9 -33
- classiq/qmod/qmod_variable.py +55 -22
- classiq/qmod/quantum_callable.py +6 -1
- classiq/qmod/quantum_expandable.py +29 -11
- classiq/qmod/quantum_function.py +8 -4
- classiq/qmod/semantics/annotation.py +38 -0
- classiq/qmod/semantics/error_manager.py +49 -0
- classiq/qmod/semantics/static_semantics_visitor.py +308 -0
- classiq/qmod/semantics/validation/func_call_validation.py +149 -0
- classiq/qmod/semantics/validation/types_validation.py +21 -0
- classiq/qmod/symbolic.py +6 -6
- classiq/qmod/symbolic_expr.py +26 -11
- classiq/qmod/utilities.py +23 -1
- {classiq-0.42.2.dist-info → classiq-0.43.0.dist-info}/METADATA +2 -2
- {classiq-0.42.2.dist-info → classiq-0.43.0.dist-info}/RECORD +88 -103
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/libraries/ampltitude_estimation_library.py +0 -11
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -20
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -6
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -74
- classiq/interface/model/resolvers/function_call_resolver.py +0 -64
- classiq/interface/model/validations/__init__.py +0 -0
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -153
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- /classiq/{interface/generator/credit_risk_example → qmod/semantics}/__init__.py +0 -0
- /classiq/{interface/model/resolvers → qmod/semantics/validation}/__init__.py +0 -0
- {classiq-0.42.2.dist-info → classiq-0.43.0.dist-info}/WHEEL +0 -0
classiq/__init__.py
CHANGED
@@ -9,17 +9,15 @@ from classiq.interface.generator.arith.register_user_input import (
|
|
9
9
|
RegisterUserInput,
|
10
10
|
)
|
11
11
|
from classiq.interface.generator.control_state import ControlState
|
12
|
-
from classiq.interface.generator.expressions.enums import * # noqa: F403
|
13
|
-
from classiq.interface.generator.expressions.enums import __all__ as _enums_all
|
14
12
|
from classiq.interface.generator.functions import * # noqa: F403
|
15
|
-
from classiq.interface.generator.functions import __all__ as _ifunc_all
|
16
13
|
from classiq.interface.generator.model import * # noqa: F403
|
17
14
|
from classiq.interface.generator.model import __all__ as _md_all
|
18
15
|
from classiq.interface.generator.quantum_program import QuantumProgram
|
16
|
+
from classiq.interface.generator.types.builtin_enum_declarations import * # noqa: F403
|
19
17
|
from classiq.interface.ide.show import show
|
20
18
|
|
21
19
|
from classiq import applications, exceptions, execution, synthesis
|
22
|
-
from classiq._internals import
|
20
|
+
from classiq._internals import logger
|
23
21
|
from classiq._internals.async_utils import (
|
24
22
|
enable_jupyter_notebook,
|
25
23
|
is_notebook as _is_notebook,
|
@@ -99,11 +97,9 @@ __all__ = (
|
|
99
97
|
"show",
|
100
98
|
]
|
101
99
|
+ _md_all
|
102
|
-
+ _ifunc_all
|
103
100
|
+ _sub_modules
|
104
101
|
+ _application_constructors_all
|
105
102
|
+ _qmod_all
|
106
|
-
+ _enums_all
|
107
103
|
)
|
108
104
|
|
109
105
|
|
@@ -15,13 +15,7 @@ from classiq.interface.execution.jobs import (
|
|
15
15
|
from classiq.interface.executor import execution_request
|
16
16
|
from classiq.interface.generator import quantum_program as generator_result
|
17
17
|
from classiq.interface.hardware import HardwareInformation
|
18
|
-
from classiq.interface.jobs import
|
19
|
-
JobDescriptionBase,
|
20
|
-
JobDescriptionFailure,
|
21
|
-
JobDescriptionSuccess,
|
22
|
-
JobID,
|
23
|
-
JSONObject,
|
24
|
-
)
|
18
|
+
from classiq.interface.jobs import JobDescription, JobID, JSONObject
|
25
19
|
from classiq.interface.model.model import Model
|
26
20
|
from classiq.interface.server import routes
|
27
21
|
|
@@ -49,13 +43,13 @@ class StatusType(Protocol):
|
|
49
43
|
|
50
44
|
|
51
45
|
def _parse_job_response(
|
52
|
-
job_result:
|
46
|
+
job_result: JobDescription[JSONObject],
|
53
47
|
output_type: Type[ResultType],
|
54
48
|
) -> ResultType:
|
55
|
-
if
|
56
|
-
return output_type.parse_obj(job_result.
|
57
|
-
if
|
58
|
-
raise ClassiqAPIError(job_result.
|
49
|
+
if job_result.result is not None:
|
50
|
+
return output_type.parse_obj(job_result.result)
|
51
|
+
if job_result.failure_details:
|
52
|
+
raise ClassiqAPIError(job_result.failure_details)
|
59
53
|
|
60
54
|
raise ClassiqAPIError("Unexpected response from server")
|
61
55
|
|
@@ -2,7 +2,7 @@ import argparse
|
|
2
2
|
import logging
|
3
3
|
import threading
|
4
4
|
import warnings
|
5
|
-
from typing import Optional
|
5
|
+
from typing import Optional, Sequence, Type
|
6
6
|
|
7
7
|
from classiq._internals.authentication import password_manager as pm
|
8
8
|
from classiq._internals.authentication.auth0 import Auth0
|
@@ -13,7 +13,10 @@ from classiq.exceptions import (
|
|
13
13
|
ClassiqPasswordManagerSelectionError,
|
14
14
|
)
|
15
15
|
|
16
|
-
PASSWORD_MANAGERS
|
16
|
+
PASSWORD_MANAGERS: Sequence[Type[pm.PasswordManager]] = [
|
17
|
+
pm.KeyringPasswordManager,
|
18
|
+
pm.FilePasswordManager,
|
19
|
+
]
|
17
20
|
_logger = logging.getLogger(__name__)
|
18
21
|
|
19
22
|
|
classiq/_internals/jobs.py
CHANGED
@@ -5,12 +5,7 @@ from typing import Callable, Dict, Iterable, Optional, Set, TypeVar
|
|
5
5
|
import httpx
|
6
6
|
import pydantic
|
7
7
|
|
8
|
-
from classiq.interface.jobs import
|
9
|
-
JobDescriptionBase,
|
10
|
-
JobDescriptionUnion,
|
11
|
-
JobID,
|
12
|
-
JSONObject,
|
13
|
-
)
|
8
|
+
from classiq.interface.jobs import JobDescription, JobID, JSONObject
|
14
9
|
|
15
10
|
from classiq._internals.async_utils import poll_for
|
16
11
|
from classiq._internals.client import client, try_again_on_failure
|
@@ -18,7 +13,7 @@ from classiq._internals.config import SDKMode
|
|
18
13
|
from classiq.exceptions import ClassiqAPIError
|
19
14
|
|
20
15
|
_URL_PATH_SEP = "/"
|
21
|
-
GeneralJobDescription =
|
16
|
+
GeneralJobDescription = JobDescription[JSONObject]
|
22
17
|
_logger = logging.getLogger(__name__)
|
23
18
|
T = TypeVar("T")
|
24
19
|
|
@@ -42,9 +37,9 @@ def _join_url_path(*parts: str) -> str:
|
|
42
37
|
def _general_job_description_parser(
|
43
38
|
json_response: JSONObject,
|
44
39
|
) -> Optional[GeneralJobDescription]:
|
45
|
-
job_description =
|
46
|
-
if job_description.
|
47
|
-
return job_description
|
40
|
+
job_description = GeneralJobDescription.parse_obj(json_response)
|
41
|
+
if job_description.status.is_final():
|
42
|
+
return job_description
|
48
43
|
return None
|
49
44
|
|
50
45
|
|
classiq/analyzer/rb.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from enum import Enum
|
1
|
+
from enum import Enum as PythonEnum
|
2
2
|
from typing import Dict, List, Optional, Set, Union
|
3
3
|
|
4
4
|
import matplotlib.pyplot as plt
|
@@ -78,8 +78,8 @@ class RBAnalysis:
|
|
78
78
|
return fig
|
79
79
|
|
80
80
|
|
81
|
-
def _strict_string(arg: Union[
|
82
|
-
if isinstance(arg,
|
81
|
+
def _strict_string(arg: Union[PythonEnum, str]) -> str:
|
82
|
+
if isinstance(arg, PythonEnum):
|
83
83
|
return arg.value
|
84
84
|
return arg
|
85
85
|
|
@@ -18,7 +18,7 @@ from classiq.interface.chemistry.ground_state_problem import (
|
|
18
18
|
MoleculeProblem,
|
19
19
|
)
|
20
20
|
from classiq.interface.chemistry.molecule import Atom
|
21
|
-
from classiq.
|
21
|
+
from classiq.qmod.builtins.enums import (
|
22
22
|
Element,
|
23
23
|
FermionMapping,
|
24
24
|
)
|
@@ -51,6 +51,7 @@ from classiq.applications.chemistry.chemistry_execution_parameters import (
|
|
51
51
|
ChemistryExecutionParameters,
|
52
52
|
)
|
53
53
|
from classiq.exceptions import ClassiqError
|
54
|
+
from classiq.qmod.utilities import qmod_val_to_expr_str
|
54
55
|
|
55
56
|
_LADDER_OPERATOR_TYPE_INDICATOR_TO_QMOD_MAPPING: Dict[str, str] = {
|
56
57
|
"+": "PLUS",
|
@@ -153,7 +154,7 @@ _HAE_GATE_MAPPING: Dict[str, QuantumFunctionCall] = {
|
|
153
154
|
),
|
154
155
|
"crx": QuantumFunctionCall(
|
155
156
|
function="CRX",
|
156
|
-
|
157
|
+
designated_params={"theta": Expression(expr="angle")},
|
157
158
|
positional_args=[
|
158
159
|
Expression(expr="angle"),
|
159
160
|
HandleBinding(name="q1"),
|
@@ -194,7 +195,7 @@ _HAE_GATE_MAPPING: Dict[str, QuantumFunctionCall] = {
|
|
194
195
|
def _atoms_to_qmod_atoms(atoms: List[Atom]) -> List[QmodChemistryAtom]:
|
195
196
|
return [
|
196
197
|
QmodChemistryAtom(
|
197
|
-
element=Element[atom.symbol],
|
198
|
+
element=Element[atom.symbol], # type:ignore[arg-type]
|
198
199
|
position=QmodPosition(
|
199
200
|
x=atom.x, # type:ignore[arg-type]
|
200
201
|
y=atom.y, # type:ignore[arg-type]
|
@@ -209,7 +210,9 @@ def molecule_problem_to_qmod(
|
|
209
210
|
molecule_problem: MoleculeProblem,
|
210
211
|
) -> QmodMoleculeProblem:
|
211
212
|
return QmodMoleculeProblem(
|
212
|
-
mapping=FermionMapping[
|
213
|
+
mapping=FermionMapping[ # type:ignore[arg-type]
|
214
|
+
molecule_problem.mapping.value.upper()
|
215
|
+
],
|
213
216
|
z2_symmetries=molecule_problem.z2_symmetries, # type:ignore[arg-type]
|
214
217
|
molecule=QmodMolecule(
|
215
218
|
atoms=_atoms_to_qmod_atoms(
|
@@ -256,11 +259,12 @@ def _summed_fermionic_operator_to_qmod_lader_terms(
|
|
256
259
|
def _hamiltonian_problem_to_qmod_fock_hamiltonian_problem(
|
257
260
|
hamiltonian_problem: HamiltonianProblem,
|
258
261
|
) -> str:
|
262
|
+
mapping = FermionMapping[hamiltonian_problem.mapping.value.upper()]
|
259
263
|
return (
|
260
264
|
# fmt: off
|
261
265
|
"struct_literal("
|
262
266
|
"FockHamiltonianProblem,"
|
263
|
-
f"mapping={
|
267
|
+
f"mapping={qmod_val_to_expr_str(mapping)},"
|
264
268
|
f"z2_symmetries={hamiltonian_problem.z2_symmetries},"
|
265
269
|
f"terms=[{_summed_fermionic_operator_to_qmod_lader_terms(hamiltonian_problem.hamiltonian)}],"
|
266
270
|
f"num_particles={hamiltonian_problem.num_particles}"
|
@@ -271,7 +275,7 @@ def _hamiltonian_problem_to_qmod_fock_hamiltonian_problem(
|
|
271
275
|
|
272
276
|
def _convert_library_problem_to_qmod_problem(problem: CHEMISTRY_PROBLEMS_TYPE) -> str:
|
273
277
|
if isinstance(problem, MoleculeProblem):
|
274
|
-
return
|
278
|
+
return qmod_val_to_expr_str(molecule_problem_to_qmod(problem))
|
275
279
|
elif isinstance(problem, HamiltonianProblem):
|
276
280
|
return _hamiltonian_problem_to_qmod_fock_hamiltonian_problem(problem)
|
277
281
|
else:
|
@@ -368,13 +372,13 @@ def _get_molecule_problem_execution_post_processing(
|
|
368
372
|
molecule_problem: MoleculeProblem,
|
369
373
|
) -> str:
|
370
374
|
return f"""
|
371
|
-
{_MOLECULE_PROBLEM_RESULT} = molecule_ground_state_solution_post_process({molecule_problem_to_qmod(molecule_problem)},{_EXECUTION_RESULT})
|
375
|
+
{_MOLECULE_PROBLEM_RESULT} = molecule_ground_state_solution_post_process({qmod_val_to_expr_str(molecule_problem_to_qmod(molecule_problem))},{_EXECUTION_RESULT})
|
372
376
|
save({{{_MOLECULE_PROBLEM_RESULT!r}: {_MOLECULE_PROBLEM_RESULT}}})
|
373
377
|
"""
|
374
378
|
|
375
379
|
|
376
380
|
def _is_parametric_gate(call: QuantumFunctionCall) -> bool:
|
377
|
-
return len(call.
|
381
|
+
return len(call.designated_params) > 0 or any(
|
378
382
|
isinstance(arg, Expression) for arg in call.positional_args
|
379
383
|
)
|
380
384
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from typing import List
|
2
2
|
|
3
|
-
from classiq.interface.generator.expressions.enums.pauli import Pauli
|
4
3
|
from classiq.interface.generator.functions.qmod_python_interface import QmodPyStruct
|
5
4
|
from classiq.interface.helpers.custom_pydantic_types import PydanticPauliList
|
6
5
|
|
7
6
|
from classiq.exceptions import ClassiqNonNumericCoefficientInPauliError
|
8
7
|
from classiq.qmod.builtins import PauliTerm
|
8
|
+
from classiq.qmod.builtins.enums import Pauli
|
9
9
|
|
10
10
|
|
11
11
|
def pauli_operator_to_hamiltonian(pauli_list: PydanticPauliList) -> List[PauliTerm]:
|
@@ -30,7 +30,7 @@ def pauli_enum_to_str(pauli: Pauli) -> str:
|
|
30
30
|
Pauli.X: "Pauli.X",
|
31
31
|
Pauli.Y: "Pauli.Y",
|
32
32
|
Pauli.Z: "Pauli.Z",
|
33
|
-
}
|
33
|
+
}[pauli]
|
34
34
|
|
35
35
|
|
36
36
|
def _pauli_terms_to_qmod(hamiltonian: List[PauliTerm]) -> str:
|
@@ -19,13 +19,11 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
19
19
|
VariableDeclarationStatement,
|
20
20
|
)
|
21
21
|
|
22
|
-
from classiq.applications.libraries.ampltitude_estimation_library import (
|
23
|
-
AE_CLASSICAL_LIBRARY,
|
24
|
-
)
|
25
22
|
from classiq.applications.libraries.qmci_library import QMCI_LIBRARY
|
26
23
|
from classiq.exceptions import ClassiqError
|
24
|
+
from classiq.qmod.utilities import qmod_val_to_expr_str
|
27
25
|
|
28
|
-
_OUTPUT_VARIABLE_NAME = "
|
26
|
+
_OUTPUT_VARIABLE_NAME = "payoff_estimation"
|
29
27
|
|
30
28
|
|
31
29
|
def construct_finance_model(
|
@@ -59,7 +57,7 @@ def construct_finance_model(
|
|
59
57
|
if finance_function_input.tail_probability is not None:
|
60
58
|
tail_probability = finance_function_input.tail_probability
|
61
59
|
|
62
|
-
finance_function_object = f"struct_literal(FinanceFunction, f={finance_function_input.f}, threshold={finance_function_input.condition.threshold}, larger={finance_function_input.condition.larger}, polynomial_degree={polynomial_degree}, use_chebyshev_polynomial_approximation={finance_function_input.use_chebyshev_polynomial_approximation}, tail_probability={tail_probability})"
|
60
|
+
finance_function_object = f"struct_literal(FinanceFunction, f={qmod_val_to_expr_str(finance_function_input.f)}, threshold={finance_function_input.condition.threshold}, larger={finance_function_input.condition.larger}, polynomial_degree={polynomial_degree}, use_chebyshev_polynomial_approximation={finance_function_input.use_chebyshev_polynomial_approximation}, tail_probability={tail_probability})"
|
63
61
|
num_unitary_qubits = total_num_qubits + 1
|
64
62
|
|
65
63
|
model = Model(
|
@@ -117,13 +115,18 @@ def construct_finance_model(
|
|
117
115
|
],
|
118
116
|
),
|
119
117
|
],
|
120
|
-
classical_execution_code=
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
118
|
+
classical_execution_code=f"""
|
119
|
+
phase_port_size = {phase_port_size}
|
120
|
+
counts = sample()
|
121
|
+
save({{"counts": counts}})
|
122
|
+
probability_estimation = qae_with_qpe_result_post_processing(
|
123
|
+
estimation_register_size=phase_port_size,
|
124
|
+
estimation_method=1,
|
125
|
+
result=counts
|
126
|
+
)
|
127
|
+
save({{"probability_estimation": probability_estimation}})
|
128
|
+
{_OUTPUT_VARIABLE_NAME} = {post_process_function}({finance_model}, {finance_function_object}, probability_estimation)
|
129
|
+
save({{"{_OUTPUT_VARIABLE_NAME}": {_OUTPUT_VARIABLE_NAME}}})
|
130
|
+
""".strip(),
|
128
131
|
)
|
129
132
|
return model.get_model()
|
@@ -1,6 +1,4 @@
|
|
1
|
-
from classiq.
|
2
|
-
QSVMFeatureMapEntanglement,
|
3
|
-
)
|
1
|
+
from classiq.qmod.builtins.enums import QSVMFeatureMapEntanglement
|
4
2
|
|
5
3
|
from ..qsvm import qsvm_data_generation
|
6
4
|
from .qsvm import * # noqa: F403
|
@@ -1,10 +1,6 @@
|
|
1
1
|
from typing import Any, List, Tuple
|
2
2
|
|
3
3
|
from classiq.interface.applications.qsvm import DataList, LabelsInt
|
4
|
-
from classiq.interface.generator.expressions.enums.pauli import Pauli
|
5
|
-
from classiq.interface.generator.expressions.enums.qsvm_feature_map_entanglement import (
|
6
|
-
QSVMFeatureMapEntanglement,
|
7
|
-
)
|
8
4
|
from classiq.interface.generator.expressions.expression import Expression
|
9
5
|
from classiq.interface.generator.functions.port_declaration import (
|
10
6
|
PortDeclarationDirection,
|
@@ -16,6 +12,8 @@ from classiq.interface.model.port_declaration import PortDeclaration
|
|
16
12
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
17
13
|
|
18
14
|
from classiq.exceptions import ClassiqValueError
|
15
|
+
from classiq.qmod.builtins.enums import Pauli, QSVMFeatureMapEntanglement
|
16
|
+
from classiq.qmod.utilities import qmod_val_to_expr_str
|
19
17
|
|
20
18
|
INVALID_FEATURE_MAP_FUNC_NAME_MSG = "Invalid feature_map_function_name, it can be bloch_sphere_feature_map or pauli_feature_map"
|
21
19
|
|
@@ -40,13 +38,16 @@ def _pauli_feature_map_function_params(
|
|
40
38
|
paulis_str = (
|
41
39
|
"["
|
42
40
|
+ ",".join(
|
43
|
-
[
|
41
|
+
[
|
42
|
+
"[" + ",".join([qmod_val_to_expr_str(p) for p in p_list]) + "]"
|
43
|
+
for p_list in paulis
|
44
|
+
]
|
44
45
|
)
|
45
46
|
+ "]"
|
46
47
|
)
|
47
48
|
pauli_feature_map_params = (
|
48
49
|
f"paulis={paulis_str}, "
|
49
|
-
f"entanglement={entanglement}, "
|
50
|
+
f"entanglement={qmod_val_to_expr_str(entanglement)}, "
|
50
51
|
f"alpha={alpha}, "
|
51
52
|
f"reps={reps}, "
|
52
53
|
f"feature_dimension={feature_dimension}"
|
classiq/exceptions.py
CHANGED
@@ -4,16 +4,17 @@ from typing import Iterable, List
|
|
4
4
|
_logger = logging.getLogger(__name__)
|
5
5
|
|
6
6
|
CLASSIQ_SLACK_COMMUNITY_LINK = (
|
7
|
-
"\nIf you need further assistance, please reach out on our Community Slack channel
|
8
|
-
"
|
7
|
+
"\nIf you need further assistance, please reach out on our Community Slack channel "
|
8
|
+
"at: https://short.classiq.io/join-slack"
|
9
9
|
)
|
10
10
|
|
11
11
|
|
12
12
|
class ClassiqError(Exception):
|
13
13
|
def __init__(self, message: str) -> None:
|
14
|
-
message_with_link = message + CLASSIQ_SLACK_COMMUNITY_LINK
|
15
|
-
super().__init__(message_with_link)
|
16
14
|
self._raw_message = message
|
15
|
+
if CLASSIQ_SLACK_COMMUNITY_LINK not in message:
|
16
|
+
message = message + CLASSIQ_SLACK_COMMUNITY_LINK
|
17
|
+
super().__init__(message)
|
17
18
|
|
18
19
|
@property
|
19
20
|
def raw_message(self) -> str:
|
@@ -171,3 +172,7 @@ class ClassiqExecutorInvalidHamiltonianError(ClassiqCombOptError):
|
|
171
172
|
|
172
173
|
def __init__(self) -> None:
|
173
174
|
super().__init__("Invalid hamiltonian")
|
175
|
+
|
176
|
+
|
177
|
+
class ClassiqSemanticError(ClassiqError):
|
178
|
+
pass
|
@@ -19,7 +19,10 @@ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import
|
|
19
19
|
from classiq.exceptions import ClassiqValueError
|
20
20
|
from classiq.executor import execute
|
21
21
|
from classiq.qmod.builtins import PauliTerm
|
22
|
-
from classiq.qmod.builtins.classical_execution_primitives import
|
22
|
+
from classiq.qmod.builtins.classical_execution_primitives import (
|
23
|
+
CARRAY_SEPARATOR,
|
24
|
+
ExecutionParams,
|
25
|
+
)
|
23
26
|
from classiq.synthesis import SerializedQuantumProgram
|
24
27
|
|
25
28
|
Hamiltonian = Union[List[QmodPyStruct], List[PauliTerm]]
|
@@ -70,7 +73,7 @@ def parse_params(params: ExecutionParams) -> ParsedExecutionParams:
|
|
70
73
|
for key, values in params.items():
|
71
74
|
if isinstance(values, list):
|
72
75
|
for index, value in enumerate(values):
|
73
|
-
new_key = f"{key}
|
76
|
+
new_key = f"{key}{CARRAY_SEPARATOR}{index}"
|
74
77
|
result[new_key] = value
|
75
78
|
elif isinstance(values, (int, float)):
|
76
79
|
result[key] = values
|
classiq/execution/qnn.py
CHANGED
@@ -4,6 +4,7 @@ from typing import List, Optional
|
|
4
4
|
import more_itertools
|
5
5
|
|
6
6
|
from classiq.interface.chemistry.operator import PauliOperator
|
7
|
+
from classiq.interface.executor.constants import DEFAULT_RESULT_NAME
|
7
8
|
from classiq.interface.executor.execution_result import (
|
8
9
|
ResultsCollection,
|
9
10
|
SavedResultValueType,
|
@@ -16,7 +17,6 @@ from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import
|
|
16
17
|
pauli_operator_to_hamiltonian,
|
17
18
|
)
|
18
19
|
from classiq.execution.execution_session import ExecutionSession
|
19
|
-
from classiq.executor import DEFAULT_RESULT_NAME
|
20
20
|
from classiq.synthesis import SerializedQuantumProgram
|
21
21
|
|
22
22
|
_MAX_ARGUMENTS_SIZE = 1024
|
classiq/executor.py
CHANGED
@@ -17,8 +17,6 @@ from classiq._internals.async_utils import syncify_function
|
|
17
17
|
from classiq.execution.jobs import ExecutionJob
|
18
18
|
from classiq.synthesis import SerializedQuantumProgram
|
19
19
|
|
20
|
-
DEFAULT_RESULT_NAME = "result"
|
21
|
-
|
22
20
|
BatchExecutionResult: TypeAlias = Union[ExecutionDetails, BaseException]
|
23
21
|
ProgramAndResult: TypeAlias = Tuple[QuantumCode, BatchExecutionResult]
|
24
22
|
BackendPreferencesAndResult: TypeAlias = Tuple[
|
classiq/interface/_version.py
CHANGED
@@ -1,12 +1,21 @@
|
|
1
1
|
from functools import reduce
|
2
|
-
from typing import
|
2
|
+
from typing import (
|
3
|
+
TYPE_CHECKING,
|
4
|
+
Any,
|
5
|
+
Collection,
|
6
|
+
Dict,
|
7
|
+
List,
|
8
|
+
Optional,
|
9
|
+
Tuple,
|
10
|
+
Union,
|
11
|
+
cast,
|
12
|
+
)
|
3
13
|
|
4
14
|
import numpy as np
|
5
15
|
import pydantic
|
6
16
|
import sympy
|
7
17
|
from more_itertools import all_equal
|
8
18
|
|
9
|
-
from classiq.interface.generator.expressions.enums.pauli import Pauli
|
10
19
|
from classiq.interface.generator.function_params import validate_expression_str
|
11
20
|
from classiq.interface.generator.parameters import (
|
12
21
|
ParameterComplexType,
|
@@ -25,6 +34,9 @@ from classiq.interface.helpers.versioned_model import VersionedModel
|
|
25
34
|
|
26
35
|
from classiq.exceptions import ClassiqValueError
|
27
36
|
|
37
|
+
if TYPE_CHECKING:
|
38
|
+
from classiq.qmod.builtins.enums import Pauli
|
39
|
+
|
28
40
|
|
29
41
|
class PauliOperator(HashablePydanticBaseModel, VersionedModel):
|
30
42
|
"""
|
@@ -204,7 +216,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
|
|
204
216
|
@classmethod
|
205
217
|
def from_unzipped_lists(
|
206
218
|
cls,
|
207
|
-
operators: List[List[Pauli]],
|
219
|
+
operators: List[List["Pauli"]],
|
208
220
|
coefficients: Optional[List[complex]] = None,
|
209
221
|
) -> "PauliOperator":
|
210
222
|
if coefficients is None:
|
@@ -404,7 +416,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
|
|
404
416
|
@classmethod
|
405
417
|
def from_unzipped_lists(
|
406
418
|
cls,
|
407
|
-
operators: List[List[Pauli]],
|
419
|
+
operators: List[List["Pauli"]],
|
408
420
|
coefficients: Optional[List[complex]] = None,
|
409
421
|
) -> "PauliOperatorV1":
|
410
422
|
if coefficients is None:
|
@@ -466,7 +478,9 @@ def validate_operator_has_no_complex_coefficients(
|
|
466
478
|
return pauli_operator
|
467
479
|
|
468
480
|
|
469
|
-
def pauli_integers_to_str(paulis: List[Pauli]) -> str:
|
481
|
+
def pauli_integers_to_str(paulis: List["Pauli"]) -> str:
|
482
|
+
from classiq.qmod.builtins.enums import Pauli
|
483
|
+
|
470
484
|
return "".join([Pauli(pauli).name for pauli in paulis])
|
471
485
|
|
472
486
|
|
@@ -0,0 +1 @@
|
|
1
|
+
DEFAULT_RESULT_NAME = "result"
|
@@ -1,10 +1,9 @@
|
|
1
|
-
from typing import Any, Dict, Optional, Union
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
5
|
from classiq.interface.generator.expressions.enums.finance_functions import (
|
6
|
-
|
7
|
-
FinanceFunctionType,
|
6
|
+
get_finance_function_dict,
|
8
7
|
)
|
9
8
|
from classiq.interface.helpers.custom_pydantic_types import (
|
10
9
|
PydanticNonZeroProbabilityFloat,
|
@@ -12,6 +11,9 @@ from classiq.interface.helpers.custom_pydantic_types import (
|
|
12
11
|
|
13
12
|
from classiq.exceptions import ClassiqValueError
|
14
13
|
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from classiq.qmod.builtins.enums import FinanceFunctionType
|
16
|
+
|
15
17
|
|
16
18
|
class FunctionCondition(pydantic.BaseModel):
|
17
19
|
threshold: float
|
@@ -25,7 +27,7 @@ class FunctionCondition(pydantic.BaseModel):
|
|
25
27
|
|
26
28
|
|
27
29
|
class FinanceFunctionInput(pydantic.BaseModel):
|
28
|
-
f: FinanceFunctionType = pydantic.Field(
|
30
|
+
f: "FinanceFunctionType" = pydantic.Field(
|
29
31
|
description="An enumeration of the wanted financial function: VaR, expected "
|
30
32
|
"shortfall, European call options or x^2"
|
31
33
|
)
|
@@ -50,10 +52,10 @@ class FinanceFunctionInput(pydantic.BaseModel):
|
|
50
52
|
)
|
51
53
|
|
52
54
|
@pydantic.validator("f", pre=True)
|
53
|
-
def _convert_f_if_str(cls, f: Any) -> FinanceFunctionType:
|
55
|
+
def _convert_f_if_str(cls, f: Any) -> "FinanceFunctionType":
|
54
56
|
# Keep this for backwards-compatible string support
|
55
|
-
if f in
|
56
|
-
return
|
57
|
+
if f in get_finance_function_dict():
|
58
|
+
return get_finance_function_dict()[f]
|
57
59
|
return f
|
58
60
|
|
59
61
|
@pydantic.validator("use_chebyshev_polynomial_approximation")
|
@@ -68,13 +70,15 @@ class FinanceFunctionInput(pydantic.BaseModel):
|
|
68
70
|
|
69
71
|
@pydantic.validator("f")
|
70
72
|
def _validate_finance_function(
|
71
|
-
cls, f: Union[int, str, FinanceFunctionType]
|
72
|
-
) -> FinanceFunctionType:
|
73
|
+
cls, f: Union[int, str, "FinanceFunctionType"]
|
74
|
+
) -> "FinanceFunctionType":
|
75
|
+
from classiq.qmod.builtins.enums import FinanceFunctionType
|
76
|
+
|
73
77
|
if isinstance(f, FinanceFunctionType):
|
74
78
|
return f
|
75
79
|
if isinstance(f, int):
|
76
80
|
return FinanceFunctionType(f)
|
77
|
-
return
|
81
|
+
return get_finance_function_dict()[f]
|
78
82
|
|
79
83
|
@pydantic.validator("tail_probability", always=True)
|
80
84
|
def _validate_tail_probability_assignment_for_shortfall(
|
@@ -82,6 +86,8 @@ class FinanceFunctionInput(pydantic.BaseModel):
|
|
82
86
|
tail_probability: Optional[PydanticNonZeroProbabilityFloat],
|
83
87
|
values: Dict[str, Any],
|
84
88
|
) -> Optional[PydanticNonZeroProbabilityFloat]:
|
89
|
+
from classiq.qmod.builtins.enums import FinanceFunctionType
|
90
|
+
|
85
91
|
if values.get("f") == FinanceFunctionType.SHORTFALL and not tail_probability:
|
86
92
|
raise ClassiqValueError(
|
87
93
|
"Tail probability must be set for expected shortfall"
|
@@ -9,9 +9,9 @@ from classiq.interface.generator.functions.classical_type import (
|
|
9
9
|
Bool,
|
10
10
|
ClassicalList,
|
11
11
|
Integer,
|
12
|
-
LadderOperator,
|
13
12
|
Real,
|
14
13
|
Struct,
|
14
|
+
TypeName,
|
15
15
|
VQEResult,
|
16
16
|
)
|
17
17
|
from classiq.interface.generator.functions.port_declaration import (
|
@@ -169,7 +169,7 @@ LADDER_TERM = StructDeclaration(
|
|
169
169
|
LADDER_OP = StructDeclaration(
|
170
170
|
name="LadderOp",
|
171
171
|
variables={
|
172
|
-
"op": LadderOperator
|
172
|
+
"op": TypeName(name="LadderOperator"),
|
173
173
|
"index": Integer(),
|
174
174
|
},
|
175
175
|
)
|
@@ -3,8 +3,8 @@ import enum
|
|
3
3
|
from classiq.interface.generator.expressions.expression import Expression
|
4
4
|
from classiq.interface.generator.functions.classical_type import (
|
5
5
|
ClassicalList,
|
6
|
+
Enum,
|
6
7
|
Integer,
|
7
|
-
Pauli,
|
8
8
|
Real,
|
9
9
|
Struct,
|
10
10
|
)
|
@@ -56,7 +56,9 @@ QSVM_FEATURE_MAP_PAULI = StructDeclaration(
|
|
56
56
|
"reps": Integer(),
|
57
57
|
"entanglement": Integer(),
|
58
58
|
"alpha": Real(),
|
59
|
-
"paulis": ClassicalList(
|
59
|
+
"paulis": ClassicalList(
|
60
|
+
element_type=ClassicalList(element_type=Enum(name="Pauli"))
|
61
|
+
),
|
60
62
|
},
|
61
63
|
)
|
62
64
|
|
@@ -49,10 +49,27 @@ def bounds(argument: RegisterOrConst) -> Tuple[float, float]:
|
|
49
49
|
|
50
50
|
|
51
51
|
def limit_fraction_places(
|
52
|
-
argument: RegisterOrConst,
|
52
|
+
argument: RegisterOrConst, machine_precision: int
|
53
53
|
) -> RegisterOrConst:
|
54
54
|
if isinstance(argument, RegisterArithmeticInfo):
|
55
55
|
return argument.limit_fraction_places(machine_precision)
|
56
|
-
return number_utils.limit_fraction_places(
|
57
|
-
|
56
|
+
return number_utils.limit_fraction_places(argument, machine_precision)
|
57
|
+
|
58
|
+
|
59
|
+
def arg_bounds_overlap(args: Tuple[RegisterOrConst, RegisterOrConst]) -> bool:
|
60
|
+
return (max(bounds(args[0])) - min(bounds(args[1]))) * (
|
61
|
+
min(bounds(args[0])) - max(bounds(args[1]))
|
62
|
+
) < 0
|
63
|
+
|
64
|
+
|
65
|
+
def as_arithmetic_info(
|
66
|
+
arg: RegisterOrConst, with_bounds: bool = True
|
67
|
+
) -> RegisterArithmeticInfo:
|
68
|
+
if isinstance(arg, RegisterArithmeticInfo):
|
69
|
+
return arg
|
70
|
+
return RegisterArithmeticInfo(
|
71
|
+
size=number_utils.size(arg),
|
72
|
+
is_signed=arg < 0,
|
73
|
+
fraction_places=number_utils.fraction_places(arg),
|
74
|
+
bounds=(arg, arg) if with_bounds else None,
|
58
75
|
)
|