## `eigenkit.algorithms.iqae`

### `IQAE`

Bases: `BaseQuantumSolver`

Iterative Quantum Amplitude Estimation (IQAE).

Estimates `a = |⟨ψ₁|A|0⟩|²` to an additive precision `epsilon`, with a failure probability of at most `alpha`. It uses the Grover operator `Q = A S₀ A† S_ψ₁`, built from the oracle `A` that you provide.

The oracle can be given in two forms:

- A **PennyLane callable** `oracle(wires)`, which applies the circuit `A` in place. The last wire (`wires[-1]`) must be the ancilla qubit:

```python
def my_oracle(wires):
    qml.RY(theta, wires=wires[0])
    qml.CNOT(wires=[wires[0], wires[-1]])
```

The matrix of the circuit is extracted internally with `qml.matrix`, so this form requires `provider="pennylane"` and the `pennylane` extra.

- A CircuitSpec, which works on any backend that supports the `QubitUnitary`, `X`, `MCZ` and `Z` gates. With a provider other than PennyLane, pass `shot_mode="synthetic"` or `shot_mode="auto"`, because `shot_mode="provider"` works only with PennyLane.

Parameters:

| Name           | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Default                                                                                                                                         |
| -------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `epsilon`      | `float`        | The additive precision to reach, that is, the half-width of the final confidence interval for a. It must be in (0, π/8).                                                                                                                                                                                                                                                                                                                                                                                                                                                          | *required*                                                                                                                                      |
| `alpha`        | `float`        | The total failure probability. The algorithm applies a Bonferroni correction, so the confidence interval of each round is valid at level alpha / T, where T = ceil(log2(π / (8 * epsilon))) is the maximum number of rounds. It must be in (0, 1).                                                                                                                                                                                                                                                                                                                                | *required*                                                                                                                                      |
| `n_qubits`     | `int`          | The total number of qubits, including the ancilla.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | *required*                                                                                                                                      |
| `provider`     | `ProviderSpec` | The backend to use: a registered name ("numpy", "pennylane", "qiskit" and so on), a config instance, or a backend object. The default is "numpy", the built-in simulator.                                                                                                                                                                                                                                                                                                                                                                                                         | `'numpy'`                                                                                                                                       |
| `n_shots`      | `int`          | The number of measurement shots per round. With shot_mode="synthetic", which is used on analytic backends, it sets the size of a seeded binomial draw on top of the exact probability of the ancilla. With shot_mode="provider" or "auto", it is the number of samples per round on the hardware or simulator, unless the provider config sets its own shots, which takes precedence. For example, a device configured for 50 shots samples 50 times, whatever the value of n_shots. To control sampling on those backends, set shots on the provider config. The default is 100. | `100`                                                                                                                                           |
| `shot_mode`    | `ShotMode`     | How the ancilla measurements are obtained. With "auto", the default, the provider's shot count is used when the backend config sets a finite shots, and synthetic binomial noise is used otherwise. "provider" always samples from the backend. "synthetic" always uses exact expectation values plus seeded binomial noise.                                                                                                                                                                                                                                                      | `'auto'`                                                                                                                                        |
| `min_ratio`    | `float`        | The minimum ratio K\_{i+1} / K_i between the Grover powers of consecutive rounds. It must be greater than 1.                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | `2.0`                                                                                                                                           |
| `random_state` | \`int          | None\`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | The seed of the random number generator used for the shot noise. An integer gives reproducible results, and None uses a non-deterministic seed. |

Example

```python
import numpy as np
from eigenkit import CircuitBuilder
from eigenkit.algorithms import IQAE

# RY(pi/3) on the ancilla prepares an amplitude of sin^2(pi/6) = 0.25.
qc = CircuitBuilder(n_qubits=2)
qc.ry(np.pi / 3, qubit=1)
oracle = qc.build()

iqae = IQAE(epsilon=0.02, alpha=0.05, n_qubits=2, random_state=0)
result = iqae.solve(oracle)

print(result.estimation)           # 0.246
print(result.confidence_interval)  # (0.2407, 0.2513), which contains 0.25
print(result.n_oracle_calls)       # 2600
```

#### `solve(oracle)`

Estimate the amplitude `a = |⟨ψ₁|A|0⟩|²`.

Parameters:

| Name     | Type       | Description   | Default                                                                                                                                                                                      |
| -------- | ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `oracle` | \`Callable | CircuitSpec\` | Either a PennyLane callable oracle(wires) that builds the state-preparation circuit A, or a CircuitSpec produced by CircuitBuilder. In both cases, the last qubit is treated as the ancilla. |

Returns:

| Type         | Description                                                                             |
| ------------ | --------------------------------------------------------------------------------------- |
| `IQAEResult` | An IQAEResult with the point estimate, the confidence interval and the resource counts. |

Raises:

| Type         | Description                                                                                       |
| ------------ | ------------------------------------------------------------------------------------------------- |
| `ValueError` | If the selected provider does not support the gates that IQAE needs (QubitUnitary, X, MCZ and Z). |

### `IQAEResult`

Bases: `ValueEquality`

Outcome of a completed Iterative Quantum Amplitude Estimation (IQAE) run.

The result is read-only. Assigning to a field raises `FrozenInstanceError`, so a mistyped `=` (instead of `==`) cannot change a result. This type holds no arrays, so nothing else needs protecting.

Results compare by value. They are not hashable, so that all result types behave in the same way: the types that hold arrays cannot be hashed both correctly and efficiently.

Attributes:

| Name                  | Type                  | Description                                                                                                                                                                                                                                                                  |
| --------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `estimation`          | `float`               | The point estimate of the amplitude a.                                                                                                                                                                                                                                       |
| `confidence_interval` | `tuple[float, float]` | The (lower, upper) Clopper-Pearson interval at the requested confidence level 1 - alpha.                                                                                                                                                                                     |
| `n_rounds`            | `int`                 | The number of rounds that the run executed. It can also be read as n_iterations, the name that the other result types use.                                                                                                                                                   |
| `n_oracle_calls`      | `int`                 | The total number of oracle calls over all rounds.                                                                                                                                                                                                                            |
| `success`             | `bool`                | Whether the interval reached the requested precision. This is the same test that ends the loop over rounds, and the one reported by the warning that the run did not converge. False means that the run stopped at max_rounds with an interval still wider than 2 * epsilon. |

#### `n_iterations`

The number of rounds, under the name that the other results use.

`n_rounds` is the name that IQAE uses, and it stays available. This property lets one loop read the number of iterations from any result.

Returns:

| Type  | Description                                 |
| ----- | ------------------------------------------- |
| `int` | The number of rounds that the run executed. |
