Skip to content

feat(core): implement Circuit.append with corresponding unit tests (#59)#65

Merged
rafaelha merged 4 commits intoQuEraComputing:mainfrom
jaideepkathiresan:issue-59-implement-circuit-append
Mar 12, 2026
Merged

feat(core): implement Circuit.append with corresponding unit tests (#59)#65
rafaelha merged 4 commits intoQuEraComputing:mainfrom
jaideepkathiresan:issue-59-implement-circuit-append

Conversation

@jaideepkathiresan
Copy link
Contributor

Changes Made

  1. In src/tsim/circuit.py, drafted the append function which detects the operation name.
  2. Translates "T" and "T_DAG" mappings to .append("S" / "S_DAG", tag="T").
  3. Dynamically maps "R_X", "R_Y", "R_Z", and "U3" inputs to I gates configured with string-interpolated tags holding their calculated parameters, formatted similarly to:
    .append("I", arg=(), tag="R_Z(theta=0.3*pi)")
  4. Passes all non-custom operations cleanly through using Stim’s direct append parameters, preserving its flexibility.
  5. Added unit tests in test/unit/test_circuit.py to validate behavior; all tests passed successfully via pytest.

@jaideepkathiresan
Copy link
Contributor Author

Hi @rafaelha, this is my first time contributing to this repo. Could you take a look at this PR and share your feedback. Thanks!

@rafaelha
Copy link
Collaborator

Hi this looks good, but a few things are still missing. It's best to look at the Circuit.append API in Stim to see what all needs to be supported.

In your current PR, name has to be a string. Could you also support cases where name is stim.CircuitInstruction, stim.CircuitRepeatBlock, or stim.Circuit. I believe in these cases you simply can forward to the stim.Circuit.append method.

Tsim also unrolls all loops. So, when you add a stim.CircuitRepeatBlock, you should also call self._stim_circ = self._stim_circ.flattened().

    @overload
    def append(
        self,
        name: str,
        targets: Union[int, stim.GateTarget, stim.PauliString, Iterable[Union[int, stim.GateTarget, stim.PauliString]]],
        arg: Union[float, Iterable[float]],
        *,
        tag: str = "",
    ) -> None:
        pass
    @overload
    def append(
        self,
        name: Union[stim.CircuitInstruction, stim.CircuitRepeatBlock, stim.Circuit],
    ) -> None:
        pass
    def append(
        self,
        name: object,
        targets: object = (),
        arg: object = None,
        *,
        tag: str = '',
    ) -> None:

@rafaelha
Copy link
Collaborator

Finally, could you also reuse the Stim docstring for tsim.append. I.e.

        """Appends an operation into the circuit.

        Args:
            name: The name of the operation's gate (e.g. "H" or "M" or "CNOT").

                This argument can also be set to a `stim.CircuitInstruction` or
                `stim.CircuitInstructionBlock`, which results in the instruction or
                block being appended to the circuit. The other arguments (targets
                and arg) can't be specified when doing so.

            targets: The objects operated on by the gate. This can be either a
                single target or an iterable of multiple targets.

                Each target can be:
                    An int: The index of a targeted qubit.
                    A `stim.GateTarget`: Could be a variety of things. Methods like
                        `stim.target_rec`, `stim.target_sweet`, `stim.target_x`, and
                        `stim.CircuitInstruction.__getitem__` all return this type.
                    A `stim.PauliString`: This will automatically be expanded into
                        a product of pauli targets like `X1*Y2*Z3`.
            arg: The "parens arguments" for the gate, such as the probability for a
                noise operation. A double or list of doubles parameterizing the
                gate. Different gates take different parens arguments. For example,
                X_ERROR takes a probability, OBSERVABLE_INCLUDE takes an observable
                index, and PAULI_CHANNEL_1 takes three disjoint probabilities.

            tag: A customizable string attached to the instruction.

        """

@jaideepkathiresan
Copy link
Contributor Author

Hi @rafaelha, I think I’ve incorporated all the suggestions. Could you take a look at the latest commit?

@rafaelha rafaelha self-requested a review March 12, 2026 20:22
Copy link
Collaborator

@rafaelha rafaelha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Thanks for the contribution!

@rafaelha rafaelha merged commit df95c24 into QuEraComputing:main Mar 12, 2026
8 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants