1# Copyright 2018 The Cirq Developers 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import functools 16import itertools 17 18import numpy as np 19import pytest 20 21import cirq 22from cirq.testing import ( 23 EqualsTester, 24 assert_allclose_up_to_global_phase, 25) 26 27_bools = (False, True) 28_paulis = (cirq.X, cirq.Y, cirq.Z) 29 30 31def _assert_not_mirror(gate) -> None: 32 trans_x = gate.transform(cirq.X) 33 trans_y = gate.transform(cirq.Y) 34 trans_z = gate.transform(cirq.Z) 35 right_handed = ( 36 trans_x.flip ^ trans_y.flip ^ trans_z.flip ^ (trans_x.to.relative_index(trans_y.to) != 1) 37 ) 38 assert right_handed, 'Mirrors' 39 40 41def _assert_no_collision(gate) -> None: 42 trans_x = gate.transform(cirq.X) 43 trans_y = gate.transform(cirq.Y) 44 trans_z = gate.transform(cirq.Z) 45 assert trans_x.to != trans_y.to, 'Collision' 46 assert trans_y.to != trans_z.to, 'Collision' 47 assert trans_z.to != trans_x.to, 'Collision' 48 49 50def _all_rotations(): 51 for ( 52 pauli, 53 flip, 54 ) in itertools.product(_paulis, _bools): 55 yield cirq.PauliTransform(pauli, flip) 56 57 58def _all_rotation_pairs(): 59 for px, flip_x, pz, flip_z in itertools.product(_paulis, _bools, _paulis, _bools): 60 if px == pz: 61 continue 62 yield cirq.PauliTransform(px, flip_x), cirq.PauliTransform(pz, flip_z) 63 64 65def _all_clifford_gates(): 66 for trans_x, trans_z in _all_rotation_pairs(): 67 yield cirq.SingleQubitCliffordGate.from_xz_map(trans_x, trans_z) 68 69 70@pytest.mark.parametrize('pauli,flip_x,flip_z', itertools.product(_paulis, _bools, _bools)) 71def test_init_value_error(pauli, flip_x, flip_z): 72 with pytest.raises(ValueError): 73 cirq.SingleQubitCliffordGate.from_xz_map((pauli, flip_x), (pauli, flip_z)) 74 75 76@pytest.mark.parametrize('trans_x,trans_z', _all_rotation_pairs()) 77def test_init_from_xz(trans_x, trans_z): 78 gate = cirq.SingleQubitCliffordGate.from_xz_map(trans_x, trans_z) 79 assert gate.transform(cirq.X) == trans_x 80 assert gate.transform(cirq.Z) == trans_z 81 _assert_not_mirror(gate) 82 _assert_no_collision(gate) 83 84 85@pytest.mark.parametrize( 86 'trans1,trans2,from1', 87 ( 88 (trans1, trans2, from1) 89 for trans1, trans2, from1 in itertools.product(_all_rotations(), _all_rotations(), _paulis) 90 if trans1.to != trans2.to 91 ), 92) 93def test_init_from_double_map_vs_kwargs(trans1, trans2, from1): 94 from2 = cirq.Pauli.by_relative_index(from1, 1) 95 from1_str, from2_str = (str(frm).lower() + '_to' for frm in (from1, from2)) 96 gate_kw = cirq.SingleQubitCliffordGate.from_double_map(**{from1_str: trans1, from2_str: trans2}) 97 gate_map = cirq.SingleQubitCliffordGate.from_double_map({from1: trans1, from2: trans2}) 98 # Test initializes the same gate 99 assert gate_kw == gate_map 100 101 # Test initializes what was expected 102 assert gate_map.transform(from1) == trans1 103 assert gate_map.transform(from2) == trans2 104 _assert_not_mirror(gate_map) 105 _assert_no_collision(gate_map) 106 107 108@pytest.mark.parametrize( 109 'trans1,from1', 110 ((trans1, from1) for trans1, from1 in itertools.product(_all_rotations(), _paulis)), 111) 112def test_init_from_double_invalid(trans1, from1): 113 from2 = cirq.Pauli.by_relative_index(from1, 1) 114 # Test throws on invalid arguments 115 with pytest.raises(ValueError): 116 cirq.SingleQubitCliffordGate.from_double_map({from1: trans1, from2: trans1}) 117 118 119@pytest.mark.parametrize('trans,frm', itertools.product(_all_rotations(), _paulis)) 120def test_init_from_single_map_vs_kwargs(trans, frm): 121 from_str = str(frm).lower() + '_to' 122 # pylint: disable=unexpected-keyword-arg 123 gate_kw = cirq.SingleQubitCliffordGate.from_single_map(**{from_str: trans}) 124 gate_map = cirq.SingleQubitCliffordGate.from_single_map({frm: trans}) 125 assert gate_kw == gate_map 126 127 128@pytest.mark.parametrize( 129 'trans,frm', 130 ( 131 (trans, frm) 132 for trans, frm in itertools.product(_all_rotations(), _paulis) 133 if trans.to != frm 134 ), 135) 136def test_init_90rot_from_single(trans, frm): 137 gate = cirq.SingleQubitCliffordGate.from_single_map({frm: trans}) 138 assert gate.transform(frm) == trans 139 _assert_not_mirror(gate) 140 _assert_no_collision(gate) 141 # Check that it decomposes to one gate 142 assert len(gate.decompose_rotation()) == 1 143 # Check that this is a 90 degree rotation gate 144 assert ( 145 gate.merged_with(gate).merged_with(gate).merged_with(gate) == cirq.SingleQubitCliffordGate.I 146 ) 147 # Check that flipping the transform produces the inverse rotation 148 trans_rev = cirq.PauliTransform(trans.to, not trans.flip) 149 gate_rev = cirq.SingleQubitCliffordGate.from_single_map({frm: trans_rev}) 150 assert gate ** -1 == gate_rev 151 152 153@pytest.mark.parametrize( 154 'trans,frm', 155 ( 156 (trans, frm) 157 for trans, frm in itertools.product(_all_rotations(), _paulis) 158 if trans.to == frm and trans.flip 159 ), 160) 161def test_init_180rot_from_single(trans, frm): 162 gate = cirq.SingleQubitCliffordGate.from_single_map({frm: trans}) 163 assert gate.transform(frm) == trans 164 _assert_not_mirror(gate) 165 _assert_no_collision(gate) 166 # Check that it decomposes to one gate 167 assert len(gate.decompose_rotation()) == 1 168 # Check that this is a 180 degree rotation gate 169 assert gate.merged_with(gate) == cirq.SingleQubitCliffordGate.I 170 171 172@pytest.mark.parametrize( 173 'trans,frm', 174 ( 175 (trans, frm) 176 for trans, frm in itertools.product(_all_rotations(), _paulis) 177 if trans.to == frm and not trans.flip 178 ), 179) 180def test_init_ident_from_single(trans, frm): 181 gate = cirq.SingleQubitCliffordGate.from_single_map({frm: trans}) 182 assert gate.transform(frm) == trans 183 _assert_not_mirror(gate) 184 _assert_no_collision(gate) 185 # Check that it decomposes to zero gates 186 assert len(gate.decompose_rotation()) == 0 187 # Check that this is an identity gate 188 assert gate == cirq.SingleQubitCliffordGate.I 189 190 191@pytest.mark.parametrize( 192 'pauli,sqrt,expected', 193 ( 194 (cirq.X, False, cirq.SingleQubitCliffordGate.X), 195 (cirq.Y, False, cirq.SingleQubitCliffordGate.Y), 196 (cirq.Z, False, cirq.SingleQubitCliffordGate.Z), 197 (cirq.X, True, cirq.SingleQubitCliffordGate.X_sqrt), 198 (cirq.Y, True, cirq.SingleQubitCliffordGate.Y_sqrt), 199 (cirq.Z, True, cirq.SingleQubitCliffordGate.Z_sqrt), 200 ), 201) 202def test_init_from_pauli(pauli, sqrt, expected): 203 gate = cirq.SingleQubitCliffordGate.from_pauli(pauli, sqrt=sqrt) 204 assert gate == expected 205 206 207def test_pow(): 208 assert cirq.SingleQubitCliffordGate.X ** -1 == cirq.SingleQubitCliffordGate.X 209 assert cirq.SingleQubitCliffordGate.H ** -1 == cirq.SingleQubitCliffordGate.H 210 assert cirq.SingleQubitCliffordGate.X_sqrt == cirq.SingleQubitCliffordGate.X ** 0.5 211 assert cirq.SingleQubitCliffordGate.Y_sqrt == cirq.SingleQubitCliffordGate.Y ** 0.5 212 assert cirq.SingleQubitCliffordGate.Z_sqrt == cirq.SingleQubitCliffordGate.Z ** 0.5 213 assert cirq.SingleQubitCliffordGate.X_nsqrt == cirq.SingleQubitCliffordGate.X ** -0.5 214 assert cirq.SingleQubitCliffordGate.Y_nsqrt == cirq.SingleQubitCliffordGate.Y ** -0.5 215 assert cirq.SingleQubitCliffordGate.Z_nsqrt == cirq.SingleQubitCliffordGate.Z ** -0.5 216 assert cirq.SingleQubitCliffordGate.X_sqrt ** -1 == cirq.SingleQubitCliffordGate.X_nsqrt 217 assert cirq.inverse(cirq.SingleQubitCliffordGate.X_nsqrt) == ( 218 cirq.SingleQubitCliffordGate.X_sqrt 219 ) 220 with pytest.raises(TypeError): 221 _ = cirq.SingleQubitCliffordGate.Z ** 0.25 222 223 224def test_init_from_quarter_turns(): 225 eq = cirq.testing.EqualsTester() 226 eq.add_equality_group( 227 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 0), 228 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 0), 229 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 0), 230 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 4), 231 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 4), 232 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 4), 233 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 8), 234 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 8), 235 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 8), 236 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, -4), 237 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, -4), 238 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, -4), 239 ) 240 eq.add_equality_group( 241 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 1), 242 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 5), 243 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 9), 244 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, -3), 245 ) 246 eq.add_equality_group( 247 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 1), 248 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 5), 249 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, 9), 250 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Y, -3), 251 ) 252 eq.add_equality_group( 253 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 1), 254 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 5), 255 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, 9), 256 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.Z, -3), 257 ) 258 eq.add_equality_group( 259 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 2), 260 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 6), 261 ) 262 eq.add_equality_group( 263 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 3), 264 cirq.SingleQubitCliffordGate.from_quarter_turns(cirq.X, 7), 265 ) 266 267 268@pytest.mark.parametrize('gate', _all_clifford_gates()) 269def test_init_from_quarter_turns_reconstruct(gate): 270 new_gate = functools.reduce( 271 cirq.SingleQubitCliffordGate.merged_with, 272 ( 273 cirq.SingleQubitCliffordGate.from_quarter_turns(pauli, qt) 274 for pauli, qt in gate.decompose_rotation() 275 ), 276 cirq.SingleQubitCliffordGate.I, 277 ) 278 assert gate == new_gate 279 280 281def test_init_invalid(): 282 with pytest.raises(ValueError): 283 cirq.SingleQubitCliffordGate.from_single_map() 284 with pytest.raises(ValueError): 285 cirq.SingleQubitCliffordGate.from_single_map({}) 286 with pytest.raises(ValueError): 287 cirq.SingleQubitCliffordGate.from_single_map( 288 {cirq.X: (cirq.X, False)}, y_to=(cirq.Y, False) 289 ) 290 with pytest.raises(ValueError): 291 cirq.SingleQubitCliffordGate.from_single_map( 292 {cirq.X: (cirq.X, False), cirq.Y: (cirq.Y, False)} 293 ) 294 with pytest.raises(ValueError): 295 cirq.SingleQubitCliffordGate.from_double_map() 296 with pytest.raises(ValueError): 297 cirq.SingleQubitCliffordGate.from_double_map({}) 298 with pytest.raises(ValueError): 299 cirq.SingleQubitCliffordGate.from_double_map({cirq.X: (cirq.X, False)}) 300 with pytest.raises(ValueError): 301 cirq.SingleQubitCliffordGate.from_double_map(x_to=(cirq.X, False)) 302 with pytest.raises(ValueError): 303 cirq.SingleQubitCliffordGate.from_single_map( 304 {cirq.X: (cirq.Y, False), cirq.Y: (cirq.Z, False), cirq.Z: (cirq.X, False)} 305 ) 306 with pytest.raises(ValueError): 307 cirq.SingleQubitCliffordGate.from_single_map( 308 {cirq.X: (cirq.X, False), cirq.Y: (cirq.X, False)} 309 ) 310 311 312def test_eq_ne_and_hash(): 313 eq = EqualsTester() 314 for trans_x, trans_z in _all_rotation_pairs(): 315 gate_gen = lambda: cirq.SingleQubitCliffordGate.from_xz_map(trans_x, trans_z) 316 eq.make_equality_group(gate_gen) 317 318 319@pytest.mark.parametrize( 320 'gate,rep', 321 ( 322 (cirq.SingleQubitCliffordGate.I, 'cirq.SingleQubitCliffordGate(X:+X, Y:+Y, Z:+Z)'), 323 (cirq.SingleQubitCliffordGate.H, 'cirq.SingleQubitCliffordGate(X:+Z, Y:-Y, Z:+X)'), 324 (cirq.SingleQubitCliffordGate.X, 'cirq.SingleQubitCliffordGate(X:+X, Y:-Y, Z:-Z)'), 325 (cirq.SingleQubitCliffordGate.X_sqrt, 'cirq.SingleQubitCliffordGate(X:+X, Y:+Z, Z:-Y)'), 326 ), 327) 328def test_repr(gate, rep): 329 assert repr(gate) == rep 330 331 332@pytest.mark.parametrize( 333 'gate,trans_y', 334 ( 335 (cirq.SingleQubitCliffordGate.I, (cirq.Y, False)), 336 (cirq.SingleQubitCliffordGate.H, (cirq.Y, True)), 337 (cirq.SingleQubitCliffordGate.X, (cirq.Y, True)), 338 (cirq.SingleQubitCliffordGate.Y, (cirq.Y, False)), 339 (cirq.SingleQubitCliffordGate.Z, (cirq.Y, True)), 340 (cirq.SingleQubitCliffordGate.X_sqrt, (cirq.Z, False)), 341 (cirq.SingleQubitCliffordGate.X_nsqrt, (cirq.Z, True)), 342 (cirq.SingleQubitCliffordGate.Y_sqrt, (cirq.Y, False)), 343 (cirq.SingleQubitCliffordGate.Y_nsqrt, (cirq.Y, False)), 344 (cirq.SingleQubitCliffordGate.Z_sqrt, (cirq.X, True)), 345 (cirq.SingleQubitCliffordGate.Z_nsqrt, (cirq.X, False)), 346 ), 347) 348def test_y_rotation(gate, trans_y): 349 assert gate.transform(cirq.Y) == trans_y 350 351 352@pytest.mark.parametrize( 353 'gate,gate_equiv', 354 ( 355 (cirq.SingleQubitCliffordGate.I, cirq.X ** 0), 356 (cirq.SingleQubitCliffordGate.H, cirq.H), 357 (cirq.SingleQubitCliffordGate.X, cirq.X), 358 (cirq.SingleQubitCliffordGate.Y, cirq.Y), 359 (cirq.SingleQubitCliffordGate.Z, cirq.Z), 360 (cirq.SingleQubitCliffordGate.X_sqrt, cirq.X ** 0.5), 361 (cirq.SingleQubitCliffordGate.X_nsqrt, cirq.X ** -0.5), 362 (cirq.SingleQubitCliffordGate.Y_sqrt, cirq.Y ** 0.5), 363 (cirq.SingleQubitCliffordGate.Y_nsqrt, cirq.Y ** -0.5), 364 (cirq.SingleQubitCliffordGate.Z_sqrt, cirq.Z ** 0.5), 365 (cirq.SingleQubitCliffordGate.Z_nsqrt, cirq.Z ** -0.5), 366 ), 367) 368def test_decompose(gate, gate_equiv): 369 q0 = cirq.NamedQubit('q0') 370 mat = cirq.Circuit(gate(q0)).unitary() 371 mat_check = cirq.Circuit( 372 gate_equiv(q0), 373 ).unitary() 374 assert_allclose_up_to_global_phase(mat, mat_check, rtol=1e-7, atol=1e-7) 375 376 377@pytest.mark.parametrize( 378 'gate,gate_equiv', 379 ( 380 (cirq.SingleQubitCliffordGate.I, cirq.X ** 0), 381 (cirq.SingleQubitCliffordGate.H, cirq.H), 382 (cirq.SingleQubitCliffordGate.X, cirq.X), 383 (cirq.SingleQubitCliffordGate.Y, cirq.Y), 384 (cirq.SingleQubitCliffordGate.Z, cirq.Z), 385 (cirq.SingleQubitCliffordGate.X_sqrt, cirq.X ** 0.5), 386 (cirq.SingleQubitCliffordGate.X_nsqrt, cirq.X ** -0.5), 387 (cirq.SingleQubitCliffordGate.Y_sqrt, cirq.Y ** 0.5), 388 (cirq.SingleQubitCliffordGate.Y_nsqrt, cirq.Y ** -0.5), 389 (cirq.SingleQubitCliffordGate.Z_sqrt, cirq.Z ** 0.5), 390 (cirq.SingleQubitCliffordGate.Z_nsqrt, cirq.Z ** -0.5), 391 ), 392) 393def test_known_matrix(gate, gate_equiv): 394 assert cirq.has_unitary(gate) 395 mat = cirq.unitary(gate) 396 mat_check = cirq.unitary(gate_equiv) 397 assert_allclose_up_to_global_phase(mat, mat_check, rtol=1e-7, atol=1e-7) 398 399 400@pytest.mark.parametrize('gate', _all_clifford_gates()) 401def test_inverse(gate): 402 assert gate == cirq.inverse(cirq.inverse(gate)) 403 404 405@pytest.mark.parametrize('gate', _all_clifford_gates()) 406def test_inverse_matrix(gate): 407 q0 = cirq.NamedQubit('q0') 408 mat = cirq.Circuit(gate(q0)).unitary() 409 mat_inv = cirq.Circuit(cirq.inverse(gate)(q0)).unitary() 410 assert_allclose_up_to_global_phase(mat, mat_inv.T.conj(), rtol=1e-7, atol=1e-7) 411 412 413def test_commutes_notimplemented_type(): 414 with pytest.raises(TypeError): 415 cirq.commutes(cirq.SingleQubitCliffordGate.X, 'X') 416 assert cirq.commutes(cirq.SingleQubitCliffordGate.X, 'X', default='default') == 'default' 417 418 419@pytest.mark.parametrize( 420 'gate,other', itertools.product(_all_clifford_gates(), _all_clifford_gates()) 421) 422def test_commutes_single_qubit_gate(gate, other): 423 q0 = cirq.NamedQubit('q0') 424 gate_op = gate(q0) 425 other_op = other(q0) 426 mat = cirq.Circuit( 427 gate_op, 428 other_op, 429 ).unitary() 430 mat_swap = cirq.Circuit( 431 other_op, 432 gate_op, 433 ).unitary() 434 commutes = cirq.commutes(gate, other) 435 commutes_check = cirq.allclose_up_to_global_phase(mat, mat_swap) 436 assert commutes == commutes_check 437 438 # Test after switching order 439 mat_swap = cirq.Circuit( 440 gate.equivalent_gate_before(other)(q0), 441 gate_op, 442 ).unitary() 443 assert_allclose_up_to_global_phase(mat, mat_swap, rtol=1e-7, atol=1e-7) 444 445 446@pytest.mark.parametrize( 447 'gate,pauli,half_turns', 448 itertools.product(_all_clifford_gates(), _paulis, (1.0, 0.25, 0.5, -0.5)), 449) 450def test_commutes_pauli(gate, pauli, half_turns): 451 pauli_gate = pauli ** half_turns 452 q0 = cirq.NamedQubit('q0') 453 mat = cirq.Circuit( 454 gate(q0), 455 pauli_gate(q0), 456 ).unitary() 457 mat_swap = cirq.Circuit( 458 pauli_gate(q0), 459 gate(q0), 460 ).unitary() 461 commutes = cirq.commutes(gate, pauli_gate) 462 commutes_check = np.allclose(mat, mat_swap) 463 assert commutes == commutes_check 464 465 466@pytest.mark.parametrize( 467 'gate,sym,exp', 468 ( 469 (cirq.SingleQubitCliffordGate.I, 'I', 1), 470 (cirq.SingleQubitCliffordGate.H, 'H', 1), 471 (cirq.SingleQubitCliffordGate.X, 'X', 1), 472 (cirq.SingleQubitCliffordGate.X_sqrt, 'X', 0.5), 473 (cirq.SingleQubitCliffordGate.X_nsqrt, 'X', -0.5), 474 ( 475 cirq.SingleQubitCliffordGate.from_xz_map((cirq.Y, False), (cirq.X, True)), 476 '(X^-0.5-Z^0.5)', 477 1, 478 ), 479 ), 480) 481def test_text_diagram_info(gate, sym, exp): 482 assert cirq.circuit_diagram_info(gate) == cirq.CircuitDiagramInfo( 483 wire_symbols=(sym,), exponent=exp 484 ) 485 486 487def test_from_unitary(): 488 def _test(clifford_gate): 489 u = cirq.unitary(clifford_gate) 490 result_gate = cirq.SingleQubitCliffordGate.from_unitary(u) 491 assert result_gate == clifford_gate 492 493 _test(cirq.SingleQubitCliffordGate.I) 494 _test(cirq.SingleQubitCliffordGate.H) 495 _test(cirq.SingleQubitCliffordGate.X) 496 _test(cirq.SingleQubitCliffordGate.Y) 497 _test(cirq.SingleQubitCliffordGate.Z) 498 _test(cirq.SingleQubitCliffordGate.X_nsqrt) 499 500 501def test_from_unitary_with_phase_shift(): 502 u = np.exp(0.42j) * cirq.unitary(cirq.SingleQubitCliffordGate.Y_sqrt) 503 gate = cirq.SingleQubitCliffordGate.from_unitary(u) 504 505 assert gate == cirq.SingleQubitCliffordGate.Y_sqrt 506 507 508def test_from_unitary_not_clifford(): 509 # Not a single-qubit gate. 510 u = cirq.unitary(cirq.CNOT) 511 assert cirq.SingleQubitCliffordGate.from_unitary(u) is None 512 513 # Not an unitary matrix. 514 u = 2 * cirq.unitary(cirq.X) 515 assert cirq.SingleQubitCliffordGate.from_unitary(u) is None 516 517 # Not a Clifford gate. 518 u = cirq.unitary(cirq.T) 519 assert cirq.SingleQubitCliffordGate.from_unitary(u) is None 520 521 522@pytest.mark.parametrize('trans_x,trans_z', _all_rotation_pairs()) 523def test_to_phased_xz_gate(trans_x, trans_z): 524 gate = cirq.SingleQubitCliffordGate.from_xz_map(trans_x, trans_z) 525 actual_phased_xz_gate = gate.to_phased_xz_gate()._canonical() 526 expect_phased_xz_gates = cirq.PhasedXZGate.from_matrix(cirq.unitary(gate)) 527 528 assert np.isclose(actual_phased_xz_gate.x_exponent, expect_phased_xz_gates.x_exponent) 529 assert np.isclose(actual_phased_xz_gate.z_exponent, expect_phased_xz_gates.z_exponent) 530 assert np.isclose( 531 actual_phased_xz_gate.axis_phase_exponent, expect_phased_xz_gates.axis_phase_exponent 532 ) 533