A python
package for approximating quantum circuits with a single qubit.
Documentation created with mkdocs
can be found in https://pablovegan.github.io/QubitApproximant/.
With pip
:
pip install qubit-approximant
In the submodule benchmarking.functions there are multiple test functions to choose from
import numpy as np
from qubit_approximant.benchmarking.functions import gaussian
x = np.linspace(-2.5, 2.5, 1000)
fn_kwargs = {'mean': 0.0, 'std': 0.5, 'coef': 1}
fn = gaussian(x, **fn_kwargs)
To create a circuit just choose the ansaz (CircuitRxRyRz
, CircuitRxRy
or CircuitRy
) and the encoding ('prob'
or 'amp'
).
from qubit_approximant.core import CircuitRxRyRz
circuit = CircuitRxRyRz(x, encoding='prob')
To find the optimum parameters of the circuit, we need to choose a cost function. This can be done with the Cost
class, where we input the function to approximate, the circuit ansatz and a metric to quantify the error in the approximation (options are 'mse'
, 'rmse'
, 'mse_weighted'
, 'kl_divergence'
or 'log_cosh'
)
from qubit_approximant.core import Cost
cost = Cost(fn, circuit, metric='mse')
Choose an optimizer (BlackBoxOptimizer
, GDOptimizer
or AdamOptimizer
)
from qubit_approximant.core import BlackBoxOptimizer
optimizer = BlackBoxOptimizer(method="L-BFGS-B")
and find the optimum parameters for the chosen circuit
layers = 6
init_params = np.random.default_rng().standard_normal(4 * layers)
opt_params = optimizer(cost, cost.grad, init_params)
We may also optimize an ansatz for multiple layers using the LayerwiseOptimizer
, which uses the optimum parameters for a circuit with
from qubit_approximant.core import LayerwiseOptimizer
layerwise_opt = LayerwiseOptimizer(
optimizer,
min_layer=3,
max_layer=7,
new_layer_coef=0.3,
new_layer_position='random'
)
params_list = layerwise_opt(cost, cost.grad, init_params)
Note: a MultilayerOptimizer
which doesn't reuse the optimized parameters from previous layers is also available.
To benchmark the optimization we can use some common metrics, like the fn
is a gaussian
:
l1_list, l2_list, inf_list, infidelity_list = metric_results(
params_list,
circuit,
fn = gaussian,
fn_kwargs = {'mean': 0.0, 'std': 0.5, 'coef': 1}
)
Test the library yourself!
import numpy as np
from qubit_approximant.benchmarking.functions import gaussian
from qubit_approximant.core import CircuitRxRyRz, Cost, BlackBoxOptimizer, LayerwiseOptimizer
from qubit_approximant.benchmarking import metric_results
x = np.linspace(-2.5, 2.5, 1000)
fn_kwargs = {'mean': 0.0, 'std': 0.5, 'coef': 1}
fn = gaussian(x, **fn_kwargs)
circuit = CircuitRxRyRz(x, encoding='prob')
cost = Cost(fn, circuit, metric='mse')
optimizer = BlackBoxOptimizer(method="L-BFGS-B")
min_layer = 3
init_params = np.random.default_rng().standard_normal(4 * min_layer)
layerwise_opt = LayerwiseOptimizer(
optimizer,
min_layer=min_layer,
max_layer=7,
new_layer_coef=0.3,
new_layer_position='random'
)
params_list = layerwise_opt(cost, cost.grad, init_params)
l1_list, l2_list, inf_list, infidelity_list = metric_results(
fn=gaussian,
fn_kwargs={'mean': 0.0, 'std': 0.5, 'coef': 1},
circuit=circuit,
params_list=params_list
)
The initial paramenters for the optimizer are generated at random with a seed
of our choice. We can benchmark the optimizer against multiple seeds (since it is a time consuming task it is parallelized using mpi
).
benchmark_seeds(
num_seeds = 4,
fn = gaussian,
fn_kwargs = fn_kwargs,
circuit = circuit,
cost = cost,
optimizer = multilayer_opt,
filename = "results",
)
This library is based on Adrian Pérez Salinas article Data re-uploading for a universal quantum classifier.
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.
This software is under the GNU General Public License v3.0.