diff --git a/src/braket/ir/ahs/hamiltonian.py b/src/braket/ir/ahs/hamiltonian.py index 6277e656..b1c23840 100644 --- a/src/braket/ir/ahs/hamiltonian.py +++ b/src/braket/ir/ahs/hamiltonian.py @@ -13,10 +13,10 @@ from typing import List -from pydantic.v1 import BaseModel +from pydantic.v1 import BaseModel, Field from braket.ir.ahs.driving_field import DrivingField -from braket.ir.ahs.shifting_field import ShiftingField +from braket.ir.ahs.local_detuning import LocalDetuning class Hamiltonian(BaseModel): @@ -24,14 +24,30 @@ class Hamiltonian(BaseModel): Specifies the Hamiltonian Attributes: - driving_fileds: An externally controlled force + drivingFields: An externally controlled force that drives coherent transitions between selected levels of certain atom types - shifting_fields: An externally controlled polarizing force + localDetuning: An externally controlled polarizing force the effect of which is accurately described by a frequency shift of certain levels. Examples: - >>> Hamiltonian(driving_fields=[DrivingField],shifting_fields=[ShiftingField]) + >>> Hamiltonian(drivingFields=[DrivingField],localDetuning=[LocalDetuning]) """ drivingFields: List[DrivingField] - shiftingFields: List[ShiftingField] + localDetuning: List[LocalDetuning] = Field(alias="shiftingFields") + + def __getattr__(self, name): + return self.__dict__[name] if name != "shiftingFields" else self.__dict__["localDetuning"] + + def __setattr__(self, name, value): + if name == "shiftingFields": + name = "localDetuning" + self.__dict__[name] = value + + def __delattr__(self, name): + if name == "shiftingFields": + name = "localDetuning" + del self.__dict__[name] + + class Config: + allow_population_by_field_name = True diff --git a/src/braket/ir/ahs/local_detuning.py b/src/braket/ir/ahs/local_detuning.py new file mode 100644 index 00000000..570781c8 --- /dev/null +++ b/src/braket/ir/ahs/local_detuning.py @@ -0,0 +1,42 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You +# may not use this file except in compliance with the License. A copy of +# the License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF +# ANY KIND, either express or implied. See the License for the specific +# language governing permissions and limitations under the License. + +from pydantic.v1 import BaseModel + +from braket.ir.ahs.physical_field import PhysicalField + + +class LocalDetuning(BaseModel): + r"""Specifies the local detuning, defined by the formula + + .. math:: + H_{shift} (t) := -\Delta(t) \sum_k h_k | r_k \rangle \langle r_k | + + where + + :math:`\Delta(t)` is the magnitude of the frequency shift in rad/s, + + :math:`h_k` is the site coefficient, + + :math:`|r_k \rangle` is the Rydberg state of atom k. + + with the sum :math:`\sum_k` taken over all target atoms. + + Attributes: + magnitude: PhysicalField + + Examples: + >>> LocalDetuning(magnitude=PhysicalField) + """ + + magnitude: PhysicalField diff --git a/src/braket/ir/ahs/program_v1.py b/src/braket/ir/ahs/program_v1.py index 5a83935e..af044a79 100644 --- a/src/braket/ir/ahs/program_v1.py +++ b/src/braket/ir/ahs/program_v1.py @@ -43,7 +43,7 @@ class Program(BraketSchemaBase): Examples: >>> Program( ... setup={"ahs_register":AtomArrangement}, - ... hamiltonian={"drivingFields":DrivingField,"shiftingFields":ShiftingField} + ... hamiltonian={"drivingFields":DrivingField,"localDetuning":LocalDetuning} ... ) """ diff --git a/src/braket/ir/ahs/shifting_field.py b/src/braket/ir/ahs/shifting_field.py index 37542f14..eaffdb20 100644 --- a/src/braket/ir/ahs/shifting_field.py +++ b/src/braket/ir/ahs/shifting_field.py @@ -11,32 +11,10 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from pydantic.v1 import BaseModel +from braket.ir.ahs.local_detuning import LocalDetuning -from braket.ir.ahs.physical_field import PhysicalField - - -class ShiftingField(BaseModel): - r"""Specifies the shifting field, defined by the formula - - .. math:: - H_{shift} (t) := -\Delta(t) \sum_k h_k | r_k \rangle \langle r_k | - - where - - :math:`\Delta(t)` is the magnitude of the frequency shift in rad/s, - - :math:`h_k` is the site coefficient, - - :math:`|r_k \rangle` is the Rydberg state of atom k. - - with the sum :math:`\sum_k` taken over all target atoms. - - Attributes: - magnitude: PhysicalField - - Examples: - >>> ShiftingField(magnitude=PhysicalField) - """ - - magnitude: PhysicalField +# The class `ShiftingField` is deprecated. Please use `LocalDetuning` instead. +# This file and class will be removed in a future version. +# We are retaining this now to avoid breaking backwards compatibility for users already +# utilizing this nomenclature. +ShiftingField = LocalDetuning diff --git a/test/unit_tests/braket/ir/ahs/test_ahs_program_v1.py b/test/unit_tests/braket/ir/ahs/test_ahs_program_v1.py index 898f0b2c..d60cd5ad 100644 --- a/test/unit_tests/braket/ir/ahs/test_ahs_program_v1.py +++ b/test/unit_tests/braket/ir/ahs/test_ahs_program_v1.py @@ -32,41 +32,49 @@ } } -valid_hamiltonian_input = { - "drivingFields": [ - { - "amplitude": { - "time_series": { - "values": [0.0, 2.51327e7, 2.51327e7, 0.0], - "times": [0.0, 3.0e-7, 2.7e-6, 3.0e-6], + +@pytest.fixture( + params=[ + "shiftingFields", + "localDetuning", + ] +) +def valid_hamiltonian_input(request): + return { + "drivingFields": [ + { + "amplitude": { + "time_series": { + "values": [0.0, 2.51327e7, 2.51327e7, 0.0], + "times": [0.0, 3.0e-7, 2.7e-6, 3.0e-6], + }, + "pattern": "uniform", }, - "pattern": "uniform", - }, - "phase": { - "time_series": {"values": [0, 0], "times": [0.0, 3.0e-6]}, - "pattern": "uniform", - }, - "detuning": { - "time_series": { - "values": [-1.25664e8, -1.25664e8, 1.25664e8, 1.25664e8], - "times": [0.0, 3.0e-7, 2.7e-6, 3.0e-6], + "phase": { + "time_series": {"values": [0, 0], "times": [0.0, 3.0e-6]}, + "pattern": "uniform", + }, + "detuning": { + "time_series": { + "values": [-1.25664e8, -1.25664e8, 1.25664e8, 1.25664e8], + "times": [0.0, 3.0e-7, 2.7e-6, 3.0e-6], + }, + "pattern": "uniform", }, - "pattern": "uniform", - }, - } - ], - "shiftingFields": [ - { - "magnitude": { - "time_series": {"values": [-1.25664e8, 1.25664e8], "times": [0.0, 3.0e-6]}, - "pattern": [0.5, 1.0, 0.5, 0.5, 0.5, 0.5], } - } - ], -} + ], + request.param: [ + { + "magnitude": { + "time_series": {"values": [-1.25664e8, 1.25664e8], "times": [0.0, 3.0e-6]}, + "pattern": [0.5, 1.0, 0.5, 0.5, 0.5, 0.5], + } + } + ], + } -def test_valid(): +def test_valid(valid_hamiltonian_input): program = Program( setup=valid_setup_input, hamiltonian=valid_hamiltonian_input, @@ -76,7 +84,7 @@ def test_valid(): @pytest.mark.xfail(raises=ValidationError) -def test__missing_setup(): +def test__missing_setup(valid_hamiltonian_input): Program( hamiltonian=valid_hamiltonian_input, ) @@ -89,7 +97,7 @@ def test__missing_hamiltonian(): ) -def test_correct_decimal_serialization(): +def test_correct_decimal_serialization(valid_hamiltonian_input): program = Program( setup=valid_setup_input, hamiltonian=valid_hamiltonian_input, diff --git a/test/unit_tests/braket/ir/ahs/test_hamiltonian.py b/test/unit_tests/braket/ir/ahs/test_hamiltonian.py index db256d92..28fd856c 100644 --- a/test/unit_tests/braket/ir/ahs/test_hamiltonian.py +++ b/test/unit_tests/braket/ir/ahs/test_hamiltonian.py @@ -25,8 +25,45 @@ def test_valid(): drivingFields=valid_driving_fields, shiftingFields=valid_shifting_fields ) assert hamiltonian_field.drivingFields == valid_driving_fields + assert hamiltonian_field.localDetuning == valid_shifting_fields assert hamiltonian_field.shiftingFields == valid_shifting_fields + hamiltonian_field = Hamiltonian( + drivingFields=valid_driving_fields, localDetuning=valid_shifting_fields + ) + assert hamiltonian_field.drivingFields == valid_driving_fields + assert hamiltonian_field.shiftingFields == valid_shifting_fields + assert hamiltonian_field.localDetuning == valid_shifting_fields + + +def test_get_local_detuning(): + hamiltonian_field = Hamiltonian( + drivingFields=valid_driving_fields, shiftingFields=valid_shifting_fields + ) + assert hamiltonian_field.localDetuning == valid_shifting_fields + + +def test_set(): + hamiltonian_field = Hamiltonian( + drivingFields=valid_driving_fields, shiftingFields=valid_shifting_fields + ) + hamiltonian_field.localDetuning = [] + hamiltonian_field.shiftingFields = [] + + +def test_del_shifting_fields(): + hamiltonian_field = Hamiltonian( + drivingFields=valid_driving_fields, shiftingFields=valid_shifting_fields + ) + del hamiltonian_field.shiftingFields + + +def test_del_local_detuning(): + hamiltonian_field = Hamiltonian( + drivingFields=valid_driving_fields, shiftingFields=valid_shifting_fields + ) + del hamiltonian_field.localDetuning + @pytest.mark.xfail(raises=ValidationError) def test__missing_driving_fields(): @@ -36,7 +73,14 @@ def test__missing_driving_fields(): @pytest.mark.xfail(raises=ValidationError) -def test__missing_shifting_fields(): +def test__missing_driving_fields_with_local_detuning(): + Hamiltonian( + localDetuning=valid_shifting_fields, + ) + + +@pytest.mark.xfail(raises=ValidationError) +def test__missing_local_detuning(): Hamiltonian( drivingFields=valid_driving_fields, ) diff --git a/test/unit_tests/braket/task_result/conftest.py b/test/unit_tests/braket/task_result/conftest.py index 880483d3..fde6b717 100644 --- a/test/unit_tests/braket/task_result/conftest.py +++ b/test/unit_tests/braket/task_result/conftest.py @@ -139,8 +139,8 @@ def blackbird_program(): ) -@pytest.fixture -def ahs_program(): +@pytest.fixture(params=["shiftingFields", "localDetuning"]) +def ahs_program(request): return AHSProgram( setup={ "ahs_register": { @@ -178,7 +178,7 @@ def ahs_program(): }, } ], - "shiftingFields": [ + request.param: [ { "magnitude": { "time_series": {"values": [-1.25664e8, 1.25664e8], "times": [0.0, 3.0e-6]},