Add lattice-utils to dwave-experimental#44
Conversation
-move initialization of num_spins to subclass
thisac
left a comment
There was a problem hiding this comment.
Thanks @SebastianGitt! First pass of the lattice submodule.
- I'd recommend running a formatter (black) since all of these files are new and there are a few places with incorrect spacing, etc.
- I think the saving/loading of embeddings can be refined a bit, but I'll have a closer look at it later.
| # from latqa.experiment import * | ||
| # from latqa.lattice import * | ||
| # from latqa.observable import * | ||
| # from latqa.analysis import * | ||
| # from latqa._paths import * |
There was a problem hiding this comment.
Forgotten? Should probably just be
import dwave.experimental.lattice_utils.experiment
import dwave.experimental.lattice_utils.lattice
...unless there any any general functions that should be accessible directly from the dwave.experimental.lattice_utils namespace.
| seed: int | None = None, | ||
| skipnan: bool = True, | ||
| ) -> list[float]: | ||
| """Compute bootstrap estimates of a statistic.""" |
There was a problem hiding this comment.
Expand on docstring, add args, return, etc.
| repetitions: int, | ||
| seed: int | None = None, | ||
| ) -> Iterator[NDArray]: | ||
| """Generate resampled indices.""" |
|
|
||
|
|
||
| def confidence_interval(array: NDArray, width: float = 0.95) -> tuple[float, float, float]: | ||
| """Ravel and take the quantiles; return median and error bar lengths.""" |
| def generate_bootstrap_indices( | ||
| size: int, | ||
| repetitions: int, | ||
| seed: int | None = None, |
There was a problem hiding this comment.
Better to use NumPy's random.default_rng instead (see note on random.seed doc).
| seed: int | None = None, | |
| rng: np.random.Generator | None = None, |
and then use rng.choice(...) below.
| u: Hashable, | ||
| v: Hashable | None = None, | ||
| ) -> Iterator[tuple[int, int]]: | ||
| """Should also work for chains! These can be thought of as self-loops.""" |
There was a problem hiding this comment.
Update docstring and add args, returns.
| if u == v or v is None: | ||
| # Interior chain connectivity. | ||
| # Generic version: add all possible edges. | ||
| return ((0, 1),) |
There was a problem hiding this comment.
Why return tuple[tuple[int, int]] instead of just tuple[int, int]?
There was a problem hiding this comment.
It represents a tuple of edges. In this case it's only a single edge but for other geometries it's expected that get_chain_connectivity() returns multiple edges
| import os | ||
| from pathlib import Path | ||
| from collections.abc import Hashable | ||
| from numbers import Integral |
There was a problem hiding this comment.
Not used.
| from numbers import Integral |
| __all__ = ['Lattice'] | ||
|
|
There was a problem hiding this comment.
| __all__ = ['Lattice'] | |
| __all__ = ['Lattice'] | |
| if not hasattr(self, "num_spins"): | ||
| raise AttributeError(f"{type(self).__name__} subclass must initialize self.num_spins") |
There was a problem hiding this comment.
This would make it pointless to instantiate Lattice directly, no? Why not make it into an abstract base-class instead, adding in potentially relevant abstract methods, etc.?
-added more comprehensive docstrings -fixed formatting issues
-added more comprehensive docstrings -fixed formatting issues
…dwave-experimental into add-lattice-utils
-removed spin reversal transform functionality -uses automorphism module already in dwave-experimental -uses data classes for experiment configs
-removed spin reversal transform functionality -uses automorphism module already in dwave-experimental -uses data classes for experiment configs -formatted using black
andrew-d-king
left a comment
There was a problem hiding this comment.
Looks generally good; I am not able to pore over it in detail but it all seems sensible.
| response_dict = {} | ||
| call_dict = {} | ||
|
|
||
| for index, param in enumerate(parameter_list): |
There was a problem hiding this comment.
I would like to see the progress bars restored here.
| ret = parameter_list.copy() | ||
| for entry in ret: | ||
| if "anneal_time" in entry: | ||
| entry["anneal_time"] = np.round(entry["anneal_time"], 6) |
There was a problem hiding this comment.
Always nice to see smarter ways of doing things 👍 didn't know np.round took that parameter!
|
|
||
| return sampler_call | ||
|
|
||
| def _format_parameter_list( |
There was a problem hiding this comment.
Maybe not for this PR, but ultimately I think that a parameter class should be written, with a format parameter (basically sig figs, for float parameters). It's a bit ugly to do it ad hoc, as I've written it.
| filename = title | ||
| for bad_symbol in "/: ;,": | ||
| filename = filename.replace(bad_symbol, "_") | ||
| fig.savefig(Path(os.getcwd()) / 'figures' / f"{filename}.png") |
There was a problem hiding this comment.
All the figures should be tight_layout(), then saved, then shown. It's inconsistent right now.
| plt.show() | ||
|
|
||
| # Now we will analyze the kink-kink correlator for the fastest anneals (5ns) | ||
| fig3, ax3 = plt.subplots(1, 2, figsize=(10, 8)) |
There was a problem hiding this comment.
It should be noted that running only five iterations will give poor results for ckk, which is fairly sensitive and requires a converged shim. It also requires more data. But we don't want to put too much QPU usage in a mere example, so I think it is best to just point this out clearly.
|
|
||
| ax = axes[2, 0] | ||
| ax.plot(cshim[0]) | ||
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[0]:.3f}μs") |
There was a problem hiding this comment.
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[0]:.3f}μs") | |
| ax.set_title(f"Coupler shim, $t_a=${ANNEAL_TIMES[0]:.3f}μs") |
|
|
||
| ax = axes[2, 1] | ||
| ax.plot(cshim[1]) | ||
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[1]:.3f}μs") |
There was a problem hiding this comment.
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[1]:.3f}μs") | |
| ax.set_title(f"Coupler shim, $t_a=${ANNEAL_TIMES[1]:.3f}μs") |
|
|
||
| ax = axes[2, 2] | ||
| ax.plot(cshim[6]) | ||
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[-1]:.3f}μs") |
There was a problem hiding this comment.
| ax.set_title(f"Coupler shim, t_a={ANNEAL_TIMES[-1]:.3f}μs") | |
| ax.set_title(f"Coupler shim, $t_a=${ANNEAL_TIMES[-1]:.3f}μs") |
| config = experiment.FastAnnealExperimentConfig( | ||
| energy_scale=energy_scale, | ||
| coupler_shim_step=0.05, | ||
| flux_bias_shim_step=1e-6, |
There was a problem hiding this comment.
| flux_bias_shim_step=1e-6, | |
| flux_bias_shim_step=3e-6, |
| # Make parameter list. We will only vary anneal time. | ||
| parameter_list = [{"anneal_time": time} for time in ANNEAL_TIMES] | ||
|
|
||
| for _ in range(20): #TODO clean this up? |
There was a problem hiding this comment.
| for _ in range(20): #TODO clean this up? | |
| while True: |
Add a minimal version of LatQA to dwave-experimental as a submodule named
lattice-utils. Currently supports examples of a 1D Ising Chain and a 2D dimerized triangular lattice. Tests still need to be added to the pull request.