Skip to content

Commit

Permalink
review comments
Browse files Browse the repository at this point in the history
Co-authored-by: Christopher J. Wood <[email protected]>
  • Loading branch information
nkanazawa1989 and chriseclectic committed Apr 25, 2022
1 parent 3a86a25 commit 3d043d9
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 95 deletions.
22 changes: 11 additions & 11 deletions docs/tutorials/experiment_cloud_service.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ experiment database.

from qiskit_experiments.library.characterization import T1
import numpy as np

t1_delays = np.arange(1e-6, 600e-6, 50e-6)

# Create an experiment for qubit 0,
# setting the unit to microseconds,
# with the specified time intervals
Expand Down Expand Up @@ -158,7 +158,7 @@ on by default at the experiment service level.
.. jupyter-execute::

exp = T1(qubit=0, delays=t1_delays)

t1_expdata = exp.run(backend=backend, shots=1000)
t1_expdata.auto_save = True
t1_expdata.block_for_results()
Expand Down Expand Up @@ -189,7 +189,7 @@ Tags and notes can be added to experiments to help identify specific experiments
For example, an experiment can be tagged and made public with the following code.

.. jupyter-execute::

t1_expdata.tags = ['tag1', 'tag2']
t1_expdata.share_level = "public"
t1_expdata.notes = "Example note."
Expand All @@ -201,7 +201,7 @@ These fields can also be updated in the web interface from the menu on the right

.. |web_tags_share.png| image:: ./experiment_cloud_service/web_tags_share.png

For more information about using the cloud database interface, please take a look at its `documentation <https://quantum-computing.ibm.com/lab/docs/iql/manage/experiments/>`__.
For more information about using the cloud database interface, please take a look at its `documentation <https://quantum-computing.ibm.com/lab/docs/iql/manage/experiments/>`__.

Randomized Benchmarking experiment
----------------------------------
Expand All @@ -211,11 +211,11 @@ Let’s now do a standard RB experiment and save the results to ResultsDB.
.. jupyter-execute::

from qiskit_experiments.library import randomized_benchmarking as rb

lengths = list(range(1, 1000, 200))
num_samples = 10
seed = 1010

rb_exp = rb.StandardRB([0], lengths, num_samples=num_samples, seed=seed)
rb_expdata = rb_exp.run(backend).block_for_results()
rb_expdata.save()
Expand All @@ -242,15 +242,15 @@ Let’s do state tomography on a Hadamard state.

from qiskit_experiments.library import StateTomography
import qiskit

# Construct state by applying H gate
qc_h = qiskit.QuantumCircuit(1)
qc_h.h(0)

qstexp = StateTomography(qc_h)
qst_expdata = qstexp.run(backend).block_for_results()
qst_expdata.save()

for result in qst_expdata.analysis_results():
print(result)

Expand All @@ -262,7 +262,7 @@ graphical interface, but the other analysis parameters are:
.. image:: ./experiment_cloud_service/tomo_experiment.png

|
.. jupyter-execute::

import qiskit.tools.jupyter
Expand Down
6 changes: 3 additions & 3 deletions qiskit_experiments/curve_analysis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,13 @@ class AnalysisB(CurveAnalysis):
Typically curve analysis performs fitting as follows.
This workflow is defined in the method :meth:`CurveAnalysis._run_analysis`.
1. Preparation
1. Initialization
Curve analysis calls :meth:`_preparation` method where it initializes
Curve analysis calls :meth:`_initialization` method where it initializes
some internal states and optionally populate analysis options
with the input experiment data.
In some case it may train the data processor with fresh outcomes.
A developer can override this method to perform extra preparation.
A developer can override this method to perform initialization of analysis-specific variables.
2. Data processing
Expand Down
50 changes: 24 additions & 26 deletions qiskit_experiments/curve_analysis/base_curve_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,62 +49,64 @@ class BaseCurveAnalysis(BaseAnalysis, ABC):
.. rubric:: _generate_fit_guesses
An abstract method to create initial guesses for the fit parameters.
This should be implemented by subclass.
This method creates initial guesses for the fit parameters.
This might be overridden by subclass.
See :ref:`curve_analysis_init_guess` for details.
.. rubric:: _format_data
A method to format curve data. By default, this method takes the average of y values
over the same x values and then sort the entire data by x values.
This method consumes the processed dataset and outputs the formatted dataset.
By default, this method takes the average of y values over
the same x values and then sort the entire data by x values.
.. rubric:: _evaluate_quality
A method to evaluate the quality of the fit based on the fit result.
This method evaluates the quality of the fit based on the fit result.
This returns "good" when reduced chi-squared is less than 3.0.
Usually it returns string "good" or "bad" according to the evaluation.
This criterion can be updated by subclass.
.. rubric:: _run_data_processing
A method to perform data processing, i.e. create data arrays from
a list of experiment data payload.
This method performs data processing and returns the processed dataset.
By default, it internally calls :class:`DataProcessor` instance from the analysis options
and processes experiment data payload to create Y data with uncertainty.
X data and other metadata are generated within this method by inspecting the
circuit metadata. The series classification is also performed by based upon the
matching of circuit metadata and :attr:`SeriesDef.filter_kwargs`.
.. rubric:: _run_curve_fit
A method to perform fitting with predefined fit models and formatted data.
This method internally calls :meth:`_generate_fit_guesses`.
This method performs the fitting with predefined fit models and the formatted dataset.
This method internally calls :meth:`_generate_fit_guesses` method.
Note that this is a core functionality of the :meth:`_run_analysis` method,
that creates fit result object from the processed curve data.
that creates fit result object from the formatted dataset.
.. rubric:: _create_analysis_results
A method to create analysis results for important fit parameters
This method to creates analysis results for important fit parameters
that might be defined by analysis options ``result_parameters``.
In addition, another entry for all fit parameters is created when
the analysis option ``return_fit_parameters`` is ``True``.
.. rubric:: _create_curve_data
A method to create analysis results for data points used for the fitting.
This method to creates analysis results for the formatted dataset, i.e. data used for the fitting.
Entries are created when the analysis option ``return_data_points`` is ``True``.
If analysis consists of multiple series, analysis result is created for
each curve data in the series.
each curve data in the series definitions.
.. rubric:: _preparation
.. rubric:: _initialize
A method that should be called before other methods are called.
This method initializes analysis options against input experiment data.
Usually this method is called before other methods are called.
"""

def __init__(self):
"""Initialize data fields that are privately accessed by methods."""
super().__init__()

#: List[int]: Index of physical qubits
self._physical_qubits = None

@property
@abstractmethod
def parameters(self) -> List[str]:
Expand Down Expand Up @@ -522,11 +524,13 @@ def _create_curve_data(

return samples

def _preparation(
def _initialize(
self,
experiment_data: ExperimentData,
):
"""Prepare for curve analysis. This method is called ahead of other processing.
"""Initialize curve analysis with experiment data.
This method is called ahead of other processing.
Args:
experiment_data: Experiment data to analyze.
Expand All @@ -542,9 +546,3 @@ def _preparation(
if not data_processor.is_trained:
data_processor.train(data=experiment_data.data())
self.set_options(data_processor=data_processor)

# get experiment metadata
try:
self._physical_qubits = experiment_data.metadata["physical_qubits"]
except KeyError:
pass
7 changes: 1 addition & 6 deletions qiskit_experiments/curve_analysis/curve_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,6 @@ def parameters(self) -> List[str]:
"""Return parameters of this curve analysis."""
return [s for s in self._fit_params() if s not in self.options.fixed_parameters]

@property
def _num_qubits(self) -> int:
"""Getter for qubit number."""
return len(self._physical_qubits)

# pylint: disable=bad-docstring-quotes
@deprecated_function(
last_version="0.4",
Expand Down Expand Up @@ -156,7 +151,7 @@ def _run_analysis(
self.__series__ = assigned_series

# Prepare for fitting
self._preparation(experiment_data)
self._initialize(experiment_data)
analysis_results = []

# Run data processing
Expand Down
108 changes: 61 additions & 47 deletions qiskit_experiments/curve_analysis/curve_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,39 @@

@dataclasses.dataclass(frozen=True)
class SeriesDef:
"""Description of curve."""
"""A dataclass to describe the definition of the curve.
Args:
fit_func: A callable that defines the fit model of this curve. The argument names
in the callable are parsed to create the fit parameter list, which will appear
in the analysis results. The first argument should be ``x`` that represents
X-values that the experiment sweeps.
filter_kwargs: Optional. Dictionary of properties that uniquely identifies this series.
This dictionary is used for data processing.
This must be provided when the curve analysis consists of multiple series.
name: Optional. Name of this series.
plot_color: Optional. String representation of the color that is used to draw fit data
and data points in the output figure. This depends on the drawer class
being set to the curve analysis options. Usually this conforms to the
Matplotlib color names.
plot_symbol: Optional. String representation of the marker shape that is used to draw
data points in the output figure. This depends on the drawer class
being set to the curve analysis options. Usually this conforms to the
Matplotlib symbol names.
canvas: Optional. Index of sub-axis in the output figure that draws this curve.
This option is valid only when the drawer instance provides multi-axis drawing.
model_description: Optional. Arbitrary string representation of this fit model.
This string will appear in the analysis results as a part of metadata.
"""

# Arbitrary callback to define the fit function. First argument should be x.
fit_func: Callable

# Keyword dictionary to define the series with circuit metadata
filter_kwargs: Dict[str, Any] = dataclasses.field(default_factory=dict)

# Name of this series. This name will appear in the figure and raw x-y value report.
name: str = "Series-0"

# Color of this line.
plot_color: str = "black"

# Symbol to represent data points of this line.
plot_symbol: str = "o"

# Latex description of this fit model
model_description: Optional[str] = None

# Index of canvas if the result figure is multi-panel
canvas: Optional[int] = None

# Automatically extracted signature of the fit function
signature: Tuple[str] = dataclasses.field(init=False)
model_description: Optional[str] = None
signature: Tuple[str, ...] = dataclasses.field(init=False)

def __post_init__(self):
"""Parse the fit function signature to extract the names of the variables.
Expand All @@ -65,24 +73,27 @@ def __post_init__(self):

@dataclasses.dataclass(frozen=True)
class CurveData:
"""Set of extracted experiment data."""
"""A dataclass that manages the multiple arrays comprising the dataset for fitting.
Args:
x: X-values that experiment sweeps.
y: Y-values that observed and processed by the data processor.
y_err: Uncertainty of the Y-values which is created by the data processor.
Usually this assumes standard error.
shots: Number of shots used in the experiment to obtain the Y-values.
data_allocation: List with identical size with other arrays.
The value indicates the series index of the corresponding element.
This is classified based upon the matching of :attr:`SeriesDef.filter_kwargs`
with the circuit metadata of the corresponding data index.
If metadata doesn't match with any series definition, element is filled with ``-1``.
labels: List of curve labels. The list index corresponds to the series index.
"""

# X data
x: np.ndarray

# Y data
y: np.ndarray

# Error bar
y_err: np.ndarray

# Shots number
shots: np.ndarray

# Maping of data index to series index
data_allocation: np.ndarray

# List of curve names
labels: List[str]

def get_subset_of(self, index: Union[str, int]) -> "CurveData":
Expand Down Expand Up @@ -114,37 +125,34 @@ def get_subset_of(self, index: Union[str, int]) -> "CurveData":

@dataclasses.dataclass(frozen=True)
class FitData:
"""Set of data generated by the fit function."""
"""A dataclass to store the outcome of the fitting.
Args:
popt: List of optimal parameter values with uncertainties if available.
popt_keys: List of parameter names being fit.
pcov: Covariance matrix from the least square fitting.
reduced_chisq: Reduced Chi-squared value for the fit curve.
dof: Degree of freedom in this fit model.
x_data: X-values provided to the fitter.
y_data: Y-values provided to the fitter.
"""

# Order sensitive fit parameter values
popt: List[uncertainties.UFloat]

# Order sensitive parameter name list
popt_keys: List[str]

# Covariance matrix
pcov: np.ndarray

# Reduced Chi-squared value of fit curve
reduced_chisq: float

# Degree of freedom
dof: int

# X data
x_data: np.ndarray

# Y data
y_data: np.ndarray

@property
def x_range(self) -> Tuple[float, float]:
"""Return range of x values."""
"""Range of x values."""
return np.min(self.x_data), np.max(self.x_data)

@property
def y_range(self) -> Tuple[float, float]:
"""Return range of y values."""
"""Range of y values."""
return np.min(self.y_data), np.max(self.y_data)

def fitval(self, key: str) -> uncertainties.UFloat:
Expand All @@ -169,7 +177,13 @@ def fitval(self, key: str) -> uncertainties.UFloat:

@dataclasses.dataclass
class ParameterRepr:
"""Detailed description of fitting parameter."""
"""Detailed description of fitting parameter.
Args:
name: Original name of the fit parameter being defined in the fit model.
repr: Optional. Human-readable parameter name shown in the analysis result and in the figure.
unit: Optional. Physical unit of this parameter if applicable.
"""

# Fitter argument name
name: str
Expand Down
Loading

0 comments on commit 3d043d9

Please sign in to comment.