Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b002796

Browse files
add circuit cop
1 parent aea9dab commit b002796

File tree

7 files changed

+31
-7
lines changed

7 files changed

+31
-7
lines changed

‎CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
- Add keras3 example showcasing integration with tc
1414

15+
- Add circuit copy method that avoid shallow copy issue `Circuit.copy()`
16+
17+
### Changed
18+
19+
- The static method `BaseCircuit.copy` is renamed as `BaseCircuit.copy_nodes`
20+
1521
## 0.10.0
1622

1723
### Added

‎docs/source/quickstart.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ The IR is given as a list, each element is a dict containing information on one
148148
>>> c.to_qir()
149149
[{'gate': cnot, 'index': (0, 1), 'name': 'cnot', 'split': None}, {'gate': crx, 'index': (1, 0), 'name': 'crx', 'split': None, 'parameters': {'theta': 0.2}}]
150150
151+
We can also create new copied circuit via ``c.copy()`` which internally utilize the ``qir``.
152+
151153

152154
Programming Paradigm
153155
-------------------------

‎tensorcircuit/abstractcircuit.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,6 +1172,11 @@ def append(
11721172
self.__dict__.update(newc.__dict__)
11731173
return self
11741174

1175+
def copy(self) -> "AbstractCircuit":
1176+
qir = self.to_qir()
1177+
c = type(self).from_qir(qir, self.circuit_param)
1178+
return c
1179+
11751180
def expectation(
11761181
self,
11771182
*ops: Tuple[tn.Node, List[int]],

‎tensorcircuit/basecircuit.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def coloring_copied_nodes(
8181
node.id = getattr(n0, "id", id(n0))
8282

8383
@staticmethod
84-
def copy(
84+
def copy_nodes(
8585
nodes: Sequence[tn.Node],
8686
dangling: Optional[Sequence[tn.Edge]] = None,
8787
conj: Optional[bool] = False,
@@ -111,7 +111,7 @@ def copy(
111111
def _copy(
112112
self, conj: Optional[bool] = False
113113
) -> Tuple[List[tn.Node], List[tn.Edge]]:
114-
return self.copy(self._nodes, self._front, conj)
114+
return self.copy_nodes(self._nodes, self._front, conj)
115115

116116
def apply_general_gate(
117117
self,
@@ -171,7 +171,7 @@ def apply_general_gate(
171171
self._front[index[0]] = n1[0]
172172
self._front[index[1]] = n2[1]
173173
if self.is_dm:
174-
[n1l, n2l], _ = self.copy([n1, n2], conj=True)
174+
[n1l, n2l], _ = self.copy_nodes([n1, n2], conj=True)
175175
n1l[1] ^ self._front[index[0] + nq]
176176
n2l[2] ^ self._front[index[1] + nq]
177177
self._nodes.append(n1l)
@@ -186,7 +186,7 @@ def apply_general_gate(
186186
self._front[index[0]] = n1[0]
187187
self._front[index[1]] = n2[1]
188188
if self.is_dm:
189-
[n1l, n2l], _ = self.copy([n1, n2], conj=True)
189+
[n1l, n2l], _ = self.copy_nodes([n1, n2], conj=True)
190190
n2l[1] ^ self._front[index[0] + nq]
191191
n1l[2] ^ self._front[index[1] + nq]
192192
self._nodes.append(n1l)
@@ -203,7 +203,7 @@ def apply_general_gate(
203203
# gate.id = id(gate)
204204
self._nodes.append(gate)
205205
if self.is_dm:
206-
lgates, _ = self.copy([gate], conj=True)
206+
lgates, _ = self.copy_nodes([gate], conj=True)
207207
lgate = lgates[0]
208208
self._nodes.append(lgate)
209209
for i, ind in enumerate(index):

‎tensorcircuit/densitymatrix.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def __init__(
8686
for i, n in enumerate(mps_nodes):
8787
mps_nodes[i].tensor = backend.cast(n.tensor, dtypestr) # type: ignore
8888
mps_edges = mps_inputs.out_edges + mps_inputs.in_edges
89-
self._nodes, self._front = self.copy(mps_nodes, mps_edges)
89+
self._nodes, self._front = self.copy_nodes(mps_nodes, mps_edges)
9090
self.coloring_nodes(self._nodes)
9191
self._double_nodes_front()
9292

@@ -131,7 +131,7 @@ def __init__(
131131
self._extra_qir: List[Dict[str, Any]] = []
132132

133133
def _double_nodes_front(self) -> None:
134-
lnodes, lfront = self.copy(self._nodes, self._front, conj=True)
134+
lnodes, lfront = self.copy_nodes(self._nodes, self._front, conj=True)
135135
self._front.extend(lfront)
136136
self._nodes.extend(lnodes)
137137

‎tensorcircuit/results/counts.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
Tensor = Any
1010
ct = Dict[str, int]
1111

12+
# TODO(@refraction-ray): merge_count
13+
1214

1315
def reverse_count(count: ct) -> ct:
1416
ncount = {}

‎tests/test_circuit.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,3 +1627,12 @@ def test_general_kraus_with_prob(backend):
16271627
np.testing.assert_allclose(rs[0][1], [0.25, 0.25, 0.5], atol=1e-5)
16281628
np.testing.assert_allclose(rs[1][1], [0.25, 0.25, 0.5], atol=1e-5)
16291629
np.testing.assert_allclose(tc.backend.norm(c.state()), 1, atol=1e-5)
1630+
1631+
1632+
@pytest.mark.parametrize("backend", [lf("tfb"), lf("jaxb"), lf("npb")])
1633+
def test_circuit_copy(backend):
1634+
c = tc.Circuit(2)
1635+
c.h(0)
1636+
c1 = c.copy()
1637+
c.rz(0, theta=0.1)
1638+
assert c1.gate_count() == 1

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /