Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
fdmalone committed Dec 12, 2024
1 parent c5224f0 commit 03ec63a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 62 deletions.
2 changes: 1 addition & 1 deletion qualtran/bloqs/chemistry/trotter/hubbard/interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ def _interaction() -> Interaction:
@bloq_example
def _interaction_hwp() -> InteractionHWP:
length = 8
angle = 0.5
angle = 0.52728
hubb_u = 4.0
interaction_hwp = InteractionHWP(length, angle, hubb_u)
return interaction_hwp
Expand Down
22 changes: 1 addition & 21 deletions qualtran/bloqs/chemistry/trotter/hubbard/interaction_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,9 @@
# 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.
import attrs

from qualtran import Bloq
from qualtran.bloqs.basic_gates import Rz
from qualtran.bloqs.basic_gates.rotation import ZPowGate
from qualtran.bloqs.bookkeeping import ArbitraryClifford
from qualtran.bloqs.chemistry.trotter.hubbard.interaction import _interaction, _interaction_hwp
from qualtran.resource_counting import get_cost_value, QECGatesCost
from qualtran.resource_counting.generalizers import PHI


def catch_rotations(bloq) -> Bloq:
if isinstance(bloq, Rz):
if isinstance(bloq.angle, float) and abs(bloq.angle) < 1e-12:
return ArbitraryClifford(1)
else:
return attrs.evolve(bloq, angle=PHI)
if isinstance(bloq, ZPowGate):
if isinstance(bloq.exponent, float) and abs(bloq.exponent) < 1e-12:
return ArbitraryClifford(1)
else:
return attrs.evolve(bloq, exponent=PHI, global_shift=0)
return bloq


def test_hopping_tile(bloq_autotester):
Expand All @@ -46,7 +26,7 @@ def test_interaction_hwp(bloq_autotester):

def test_interaction_hwp_bloq_counts():
bloq = _interaction_hwp()
costs = get_cost_value(bloq, QECGatesCost(), generalizer=catch_rotations)
costs = get_cost_value(bloq, QECGatesCost())
n_rot_par = bloq.length**2 // 2
assert costs.rotation == 2 * n_rot_par.bit_length()
assert costs.total_t_count(ts_per_rotation=0) == 2 * 4 * (n_rot_par - n_rot_par.bit_count())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,32 +112,12 @@
"import sympy\n",
"import attrs\n",
"\n",
"from qualtran.bloqs.basic_gates.rotation import ZPowGate\n",
"from qualtran.resource_counting.generalizers import PHI\n",
"from qualtran.cirq_interop.t_complexity_protocol import TComplexity\n",
"from qualtran import Bloq\n",
"from qualtran.bloqs.basic_gates import Rz\n",
"from qualtran.bloqs.bookkeeping import ArbitraryClifford\n",
"from qualtran.resource_counting import get_cost_value, QECGatesCost\n",
"\n",
"\n",
"def catch_rotations(bloq) -> Bloq:\n",
" \"\"\"Generalizer to catch rotations.\"\"\"\n",
" if isinstance(bloq, Rz):\n",
" if isinstance(bloq.angle, float) and abs(bloq.angle) < 1e-12:\n",
" return ArbitraryClifford(1)\n",
" else:\n",
" return Rz(angle=PHI, eps=bloq.eps)\n",
" if isinstance(bloq, ZPowGate):\n",
" if isinstance(bloq.exponent, float) and abs(bloq.exponent) < 1e-12:\n",
" return ArbitraryClifford(1)\n",
" else:\n",
" return attrs.evolve(bloq, exponent=PHI, global_shift=0)\n",
" return bloq\n",
"\n",
"\n",
"def t_and_rot_counts_from_bloq(bloq) -> Tuple[int, int]:\n",
" costs = get_cost_value(bloq, QECGatesCost(), generalizer=catch_rotations)\n",
" costs = get_cost_value(bloq, QECGatesCost())\n",
" n_rot = costs.rotation\n",
" n_t = costs.total_t_count(ts_per_rotation=0)\n",
" return n_t, n_rot\n",
Expand Down Expand Up @@ -289,6 +269,7 @@
"outputs": [],
"source": [
"from qualtran.drawing import show_call_graph\n",
"from qualtran.resource_counting.generalizers import generalize_rotation_angle \n",
"# get appropriate epsilon given our input parameters now we know the number of rotations\n",
"eps_single_rot = get_single_rot_eps(n_rot, delta_ht, timestep)\n",
"print(f\"Adjusted eps_single_rot: {eps_single_rot}\")\n",
Expand All @@ -298,7 +279,7 @@
"# But let's show the call graph anyway to check the parameters all all what we expect.\n",
"updated_eps_bloqs = tuple(attrs.evolve(b, eps=eps_single_rot) for b in trotter_step.bloqs)\n",
"trotter_step = attrs.evolve(trotter_step, bloqs=updated_eps_bloqs)\n",
"trotter_step_g, _ = trotter_step.call_graph(generalizer=catch_rotations)\n",
"trotter_step_g, _ = trotter_step.call_graph(generalizer=generalize_rotation_angle)\n",
"show_call_graph(trotter_step_g)"
]
},
Expand Down Expand Up @@ -517,14 +498,18 @@
"metadata": {},
"outputs": [],
"source": [
"s_eps_r, s_length, s_hubb_u, s_timestep, s_tau = sympy.symbols(r'\\epsilon_{R}, L, u, t, \\tau')"
"s_eps_r, s_length, s_hubb_u, s_timestep, s_tau = sympy.symbols(r'\\epsilon_{R}, L, u, t, \\tau')\n",
"s_delta_ht, s_delta_ts, s_delta_pe, s_p, s_xi = sympy.symbols(\n",
" '\\Delta_{HT}, \\Delta_{TS}, \\Delta_{PE}, p, xi'\n",
")\n",
"s_n_rot, s_n_t, s_n_pe = sympy.symbols('N_R, N_T, N_PE')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First let's check the Bloq counts look correct for the Trotter step, there are two sources rotations from the interaction and hopping bloq and some direct T gates from the `TwoBitFFFT` gate."
"First let's check the Bloq counts look correct for the Trotter step, there are two sources: rotations from the interaction and hopping bloq, and some direct T gates from the `TwoBitFFFT` gate."
]
},
{
Expand All @@ -538,8 +523,8 @@
"s_trotter_step = build_plaq_unitary_second_order_suzuki(\n",
" s_length, s_hubb_u, s_timestep, eps=s_eps_r, hubb_t=s_tau\n",
")\n",
"t_counts = t_counts_from_sigma(s_trotter_step.call_graph(generalizer=catch_rotations)[1])\n",
"t_counts"
"t_counts, n_rot = t_and_rot_counts_from_bloq(s_trotter_step)\n",
"t_counts + rotation_cost(n_rot, s_delta_ht, s_timestep)"
]
},
{
Expand All @@ -549,7 +534,7 @@
"outputs": [],
"source": [
"# check the symbolic counts match the expected counts\n",
"t_counts_orig = t_counts_from_sigma(trotter_step.call_graph(generalizer=catch_rotations)[1])\n",
"t_counts_orig, n_rot = t_and_rot_counts_from_bloq(trotter_step)\n",
"# for some reason substituting both at once leads to a precision error\n",
"t_counts = t_counts.evalf(subs={s_eps_r: eps_single_rot})\n",
"t_counts_symb = t_counts.evalf(subs={s_length: length})\n",
Expand All @@ -569,10 +554,6 @@
"metadata": {},
"outputs": [],
"source": [
"s_delta_ht, s_delta_ts, s_delta_pe, s_p, s_xi = sympy.symbols(\n",
" '\\Delta_{HT}, \\Delta_{TS}, \\Delta_{PE}, p, xi'\n",
")\n",
"s_n_rot, s_n_t, s_n_pe = sympy.symbols('N_R, N_T, N_PE')\n",
"s_timestep = (s_delta_ts / s_xi) ** (1 / s_p)\n",
"s_eps_r = (s_delta_ht * s_timestep) / s_n_rot\n",
"s_n_pe = 0.76 * sympy.pi / (s_delta_pe * s_timestep)\n",
Expand All @@ -581,8 +562,9 @@
")\n",
"# just use this cost in lieu of a QPE bloq\n",
"# See: https://github.com/quantumlib/Qualtran/issues/932 this should be replaced by a real bloq.\n",
"t_counts = s_n_pe * t_counts_from_sigma(s_trotter_step.call_graph(generalizer=catch_rotations)[1])\n",
"t_counts"
"s_t_counts, s_n_rot = t_and_rot_counts_from_bloq(s_trotter_step)\n",
"qpe_cost_symb = s_n_pe * (s_t_counts + rotation_cost(s_n_rot, s_delta_ht, s_timestep))\n",
"qpe_cost_symb"
]
},
{
Expand All @@ -591,7 +573,7 @@
"metadata": {},
"outputs": [],
"source": [
"symb_t_count = t_counts.evalf(\n",
"symb_t_count = qpe_cost_symb.evalf(\n",
" subs={\n",
" s_length: length,\n",
" s_delta_ht: delta_ht,\n",
Expand All @@ -601,7 +583,7 @@
" s_n_rot: n_rot,\n",
" }\n",
")\n",
"symb_t_count = symb_t_count.evalf(subs={s_p: prod_ord})\n",
"symb_t_count = symb_t_count.evalf(subs={s_p: prod_ord}, maxn=500)\n",
"tot_t_count = qpe_t_count(delta_pe, delta_ts, delta_ht, n_rot, n_t, xi_bound, prod_ord)\n",
"assert int(symb_t_count) == int(tot_t_count)"
]
Expand All @@ -623,7 +605,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
"version": "3.10.4"
}
},
"nbformat": 4,
Expand Down
6 changes: 2 additions & 4 deletions qualtran/bloqs/chemistry/trotter/hubbard/trotter_step_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.
import pytest

from qualtran.bloqs.chemistry.trotter.hubbard.interaction_test import catch_rotations
from qualtran.bloqs.chemistry.trotter.hubbard.trotter_step import (
build_plaq_unitary_second_order_suzuki,
)
Expand All @@ -24,10 +23,9 @@
def test_second_order_suzuki_costs():
length = 8
u = 4
dt = 0.1
dt = 0.1234
unitary = build_plaq_unitary_second_order_suzuki(length, u, dt)
# _, sigma = unitary.call_graph(generalizer=catch_rotations)
costs = get_cost_value(unitary, QECGatesCost(), generalizer=catch_rotations)
costs = get_cost_value(unitary, QECGatesCost())
# there are 3 hopping unitaries contributing 8 Ts from from the F gate
assert costs.total_t_count(ts_per_rotation=0) == (3 * length**2 // 2) * 8
# 3 hopping unitaries and 2 interaction unitaries
Expand Down

0 comments on commit 03ec63a

Please sign in to comment.